입력 검증 및 표현 문제는 메타 문자, 대체 인코딩 및 숫자 표현 때문에 발생합니다. 보안 문제는 입력을 신뢰하기 때문에 발생합니다. 문제로는 "Buffer Overflows", "Cross-Site Scripting" 공격, "SQL Injection", 그 외 여러 가지가 있습니다.
send
함수 및 해당 변형을 사용하면 프로그래머는 함수에 대한 Ruby 접근 지정자를 우회할 수 있습니다. 특히 프로그래머는 일반적으로는 허용되지 않는 개인(private) 및 보호(protected) 필드에의 접근이 가능합니다.paramName
URL 매개 변수의 변환 또는 검증을 수행하지 않도록 구성된 책갈피 지정 가능한 보기의 샘플을 보여줍니다.
...
<bookmark>
<method>#{paramHandler.handleParams}</method>
<url-parameter>
<name>paramName</name>
<value>#{requestScope.paramName}</value>
</url-parameter>
</bookmark>
...
userClassPath
를 사용하여 로드할 클래스를 검색할 디렉터리를 결정합니다.
...
productCategory = this.getIntent().getExtras().getString("userClassPath");
DexClassLoader dexClassLoader = new DexClassLoader(productCategory, optimizedDexOutputPath.getAbsolutePath(), null, getClassLoader());
...
userClassPath
의 결과를 자신이 제어하는 다른 경로를 가리키도록 수정할 수 있기 때문에 공격자가 라이브러리를 로드하고 응용 프로그램의 높은 권한으로 임의 코드를 실행할 수 있습니다. 프로그램이 환경에서 읽은 값을 확인하지 않기 때문에 공격자가 userClassPath
의 값을 제어할 수 있으면, 공격자가 제어하는 디렉터리를 가리키도록 응용 프로그램을 속일 수 있고 이에 따라 공격자가 정의한 클래스를 원래 응용 프로그램과 동일한 권한으로 로드할 수 있습니다.userOutput
를 사용하여 로드할 클래스를 검색할 디렉터리를 결정합니다.
...
productCategory = this.getIntent().getExtras().getString("userOutput");
DexClassLoader dexClassLoader = new DexClassLoader(sanitizedPath, productCategory, null, getClassLoader());
...
userOutput
의 값을 외부 저장소와 같은 자신이 제어하는 디렉터리로 변경할 수 있습니다. 이렇게 되면 출력된 ODEX 파일을 악의적 ODEX 파일로 바꾸기만 하면 원래 응용 프로그램과 동일한 권한으로 실행됩니다.ModelState.IsValid
를 사용하여 모델 검증의 통과 여부를 확인합니다.class.classLoader
)에 액세스할 수 있게 됩니다.
String prop = request.getParameter('prop');
String value = request.getParameter('value');
HashMap properties = new HashMap();
properties.put(prop, value);
BeanUtils.populate(user, properties);
strncpy()
와 같은 범위 지정 함수도 잘못 사용되면 취약점을 일으킬 수 있습니다. 대부분의 buffer overflow의 원인은 메모리 조작과 데이터의 크기 또는 구성에 대한 가정 위반이 결합된 것입니다.gets()
함수를 사용하여 임의의 양의 데이터를 스택 버퍼에 읽어들입니다. 이 함수가 읽는 데이터의 양을 제한할 방법이 없기 때문에 코드의 안전성은 사용자가 BUFSIZE
문자보다 적은 문자를 입력하는 것에 의존할 수 밖에 없습니다.예제 1.b: 이 예제는
...
char buf[BUFSIZE];
gets(buf);
...
>>
연산자를 사용하여 입력을 char[]
문자열에 읽어들임으로써 C++의 gets()
함수의 안전하지 않은 동작을 쉽게 모방할 수 있다는 것을 보여줍니다.예제 2: 또한 이 예제의 코드는 사용자 입력에 의존하여 동작을 제어하지만 범위 지정 메모리 복사 함수
...
char buf[BUFSIZE];
cin >> (buf);
...
memcpy()
를 사용하여 간접 참조를 추가합니다. 이 함수는 대상 버퍼, 소스 버퍼 및 복사할 바이트 수를 받습니다. 입력 버퍼는 범위 지정 read()
호출로 채워지지만 사용자는 memcpy()
가 복사하는 바이트 수를 지정합니다.
...
char buf[64], in[MAX_SIZE];
printf("Enter buffer contents:\n");
read(0, in, MAX_SIZE-1);
printf("Bytes to copy:\n");
scanf("%d", &bytes);
memcpy(buf, in, bytes);
...
lccopy()
라는 함수는 문자열을 인수로 받아 모든 대문자를 소문자로 변환한 문자열의 힙 할당 복사본을 반환합니다. 이 함수는 str
이 항상 BUFSIZE
보다 작다고 예상하기 때문에 해당 입력에 대한 범위 검사를 수행하지 않습니다. 공격자가 lccopy()
를 호출하는 코드의 검사를 우회하거나 해당 코드를 변경하여 str
의 크기에 대한 가정을 참이 아닌 값으로 만드는 경우, lccopy()
는 strcpy()
를 범위 지정 없이 호출하여 buf
오버플로를 일으킵니다.예제 4: 세 번째 시나리오(코드가 너무 복잡하여 동작을 쉽게 예측할 수 없음)에 해당하는 코드가 아래에 나와 있습니다. 이 코드는 다양한 응용 프로그램에서 널리 사용되는 libPNG 이미지 디코더에서 발췌한 것입니다.
char *lccopy(const char *str) {
char buf[BUFSIZE];
char *p;
strcpy(buf, str);
for (p = buf; *p; p++) {
if (isupper(*p)) {
*p = tolower(*p);
}
}
return strdup(buf);
}
png_crc_read()
가 복사하는 데이터 양을 제어합니다. 하지만 길이를 테스트하기 직전에 코드는 png_ptr->mode
에 대한 검사를 수행하고 이 검사가 실패하면 경고를 표시하고 처리를 계속합니다. length
는 else if
블록에서 테스트되므로 첫 번째 검사가 실패하면 length
가 테스트되지 않고 png_crc_read()
호출에 무조건 사용되어 스택 Buffer Overflow를 허용할 수 있습니다.예제 5: 이 예제는 프로그램의 복잡성 때문에 buffer overflow에 노출되는 세 번째 시나리오도 보여줍니다. 이 경우, 노출은 코드의 구조 때문이 아니라 함수의 모호한 인터페이스 때문입니다(이전 예제의 경우와 마찬가지).
if (!(png_ptr->mode & PNG_HAVE_PLTE)) {
/* Should be an error, but we can cope with it */
png_warning(png_ptr, "Missing PLTE before tRNS");
}
else if (length > (png_uint_32)png_ptr->num_palette) {
png_warning(png_ptr, "Incorrect tRNS chunk length");
png_crc_finish(png_ptr, length);
return;
}
...
png_crc_read(png_ptr, readbuf, (png_size_t)length);
getUserInfo()
함수는 지정한 사용자 이름을 멀티바이트 문자열 및 사용자 정보의 구조체에 대한 포인터로 받아 사용자에 대한 정보로 구조체를 채웁니다. Windows authentication이 사용자 이름에 유니코드를 사용하기 때문에 우선 username
인수를 멀티바이트 문자열에서 유니코드 문자열로 변환합니다. 그런 다음 이 함수는 unicodeUser
의 크기를 문자 수가 아닌 바이트 수로 잘못 전달합니다. 따라서 MultiByteToWideChar()
호출은 (UNLEN+1)*sizeof(WCHAR)
길이의 문자 또는(UNLEN+1)*sizeof(WCHAR)*sizeof(WCHAR)
바이트까지 (UNLEN+1)*sizeof(WCHAR)
바이트만 할당된 unicodeUser
배열에 쓸 수 있습니다. username
문자열에 UNLEN
문자 넘게 포함되면 MultiByteToWideChar()
호출은 버퍼 unicodeUser
오버플로를 일으킵니다.
void getUserInfo(char *username, struct _USER_INFO_2 info){
WCHAR unicodeUser[UNLEN+1];
MultiByteToWideChar(CP_ACP, 0, username, -1,
unicodeUser, sizeof(unicodeUser));
NetUserGetInfo(NULL, unicodeUser, 2, (LPBYTE *)&info);
}
strncpy()
와 같은 범위 지정 함수도 잘못 사용되면 취약점을 일으킬 수 있습니다. 대부분의 buffer overflow의 원인은 메모리 조작과 데이터의 크기 또는 구성에 대한 가정 위반이 결합된 것입니다.c
에 할당된 공간보다 double
유형에 더 많은 공간이 필요하므로 c
오버플로를 일으킵니다.
void formatString(double d) {
char c;
scanf("%d", &c)
}