API는 호출자와 피호출자 간의 계약입니다. 가장 흔한 형태의 API 오용은 호출자가 이 계약에서 자신의 몫을 이행하지 못하기 때문에 발생합니다. 예를 들어, 프로그램이 chroot()를 호출한 후 chdir()을 호출하지 못하면 활성 루트 디렉터리를 안전하게 변경하는 방법을 지정하는 계약을 위반하는 것입니다. 라이브러리 오용의 또 다른 좋은 예는 피호출자가 호출자에게 신뢰할 만한 DNS 정보를 반환할 것으로 예상하는 것입니다. 이 경우, 호출자는 자신의 행동에 대해 특정한 가정을 함으로써(반환 값이 인증 목적으로 사용될 것으로 예상) 피호출자 API를 오용합니다. 다른 쪽에서 호출자-피호출자 계약을 위반할 수도 있습니다. 예를 들어, 코더가 하위 클래스 SecureRandom을 지정하고 임의 값이 아닌 값을 반환하는 경우 계약을 위반하는 것입니다.
IPAddress hostIPAddress = IPAddress.Parse(RemoteIpAddress);
IPHostEntry hostInfo = Dns.GetHostByAddress(hostIPAddress);
if (hostInfo.HostName.EndsWith("trustme.com")) {
trusted = true;
}
getlogin()
함수는 스푸핑하기 쉽습니다. 함수가 반환하는 이름을 신뢰하지 마십시오.getlogin()
함수는 현재 터미널에 로그인한 사용자의 이름이 들어 있는 문자열을 반환하는 함수이지만 공격자가 getlogin()
이 시스템에 로그인한 사용자의 이름을 반환하게 만들 수 있습니다. 보안 결정을 내릴 때 getlogin()
이 반환하는 이름에 의존해서는 안 됩니다.getlogin()
에 의존하여 사용자에 대한 신뢰 여부를 결정합니다. 이 함수는 쉽게 조작할 수 있습니다.
pwd = getpwnam(getlogin());
if (isTrustedGroup(pwd->pw_gid)) {
allow();
} else {
deny();
}
String ip = request.getRemoteAddr();
InetAddress addr = InetAddress.getByName(ip);
if (addr.getCanonicalHostName().endsWith("trustme.com")) {
trusted = true;
}
Boolean.getBoolean()
메서드는 Boolean.valueOf()
또는 Boolean.parseBoolean()
메서드 호출과 혼동하는 경우가 많습니다.Boolean.getBoolean()
에 대한 호출은 지정된 문자열 인수로 나타내는 부울 값을 반환하는 것으로 가정하기 때문에 자주 오용됩니다. 그러나 Javadoc에 언급된 것처럼 Boolean.getBoolean(String)
메서드는 "해당 인수에 의해 명명된 시스템 속성이 존재하고 'true' 문자열과 동일한 경우에만 true를 반환합니다."Boolean.valueOf(String)
또는 Boolean.parseBoolean(String)
메서드 호출이었습니다.Boolean.getBoolean(String)
이 String 기본 형식을 변환하지 못하기 때문에 "FALSE"를 출력합니다. 이 코드는 시스템 속성만 변환합니다.
...
String isValid = "true";
if ( Boolean.getBoolean(isValid) ) {
System.out.println("TRUE");
}
else {
System.out.println("FALSE");
}
...
Decoder
및 Encoding
클래스의 GetChars
메서드와 .NET Framework의 Encoder
및 Encoding
클래스의 GetBytes
메서드는 문자 및 바이트 배열에 대해 내부적으로 포인터 산술을 수행하여 문자 범위를 바이트 범위로 변환하거나 그 반대로 수행합니다.
out.println("x = " + encoder.encodeForJavaScript(input) + ";");
...
unichar ellipsis = 0x2026;
NSString *myString = [NSString stringWithFormat:@"My Test String%C", ellipsis];
NSData *asciiData = [myString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *asciiString = [[NSString alloc] initWithData:asciiData encoding:NSASCIIStringEncoding];
NSLog(@"Original: %@ (length %d)", myString, [myString length]);
NSLog(@"Best-fit-mapped: %@ (length %d)", asciiString, [asciiString length]);
// output:
// Original: My Test String... (length 15)
// Best-fit-mapped: My Test String... (length 17)
...
...
let ellipsis = 0x2026;
let myString = NSString(format:"My Test String %C", ellipsis)
let asciiData = myString.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion:true)
let asciiString = NSString(data:asciiData!, encoding:NSASCIIStringEncoding)
NSLog("Original: %@ (length %d)", myString, myString.length)
NSLog("Best-fit-mapped: %@ (length %d)", asciiString!, asciiString!.length)
// output:
// Original: My Test String ... (length 16)
// Best-fit-mapped: My Test String ... (length 18)
...
_alloca()
함수는 스택 오버플로 예외 사항을 일으키므로 프로그램이 중단될 수 있습니다._alloca()
함수는 스택에 메모리를 할당합니다. 할당 요청이 사용 가능한 스택 공간에 비해 너무 크면 _alloca()
는 예외를 일으킵니다. 예외 사항을 발견하지 못하면 프로그램이 중단되어 denial of service 공격이 발생할 수 있습니다._alloca()
는 Microsoft Visual Studio 2005(R)부터 사용하지 않습니다. 보다 안전한 _alloca_s()
로 대체되었습니다.MAX_PATH
바이트 이상인 버퍼가 필요하지만 각 함수에 대한 설명을 개별적으로 확인하는 것이 좋습니다. 버퍼가 조작 결과를 저장할 만큼 크지 않으면 buffer overflow가 발생할 수 있습니다.
char *createOutputDirectory(char *name) {
char outputDirectoryName[128];
if (getCurrentDirectory(128, outputDirectoryName) == 0) {
return null;
}
if (!PathAppend(outputDirectoryName, "output")) {
return null;
}
if (!PathAppend(outputDirectoryName, name)) {
return null;
}
if (SHCreateDirectoryEx(NULL, outputDirectoryName, NULL)
!= ERROR_SUCCESS) {
return null;
}
return StrDup(outputDirectoryName);
}
output\<name>
"인 디렉터리를 만들고 해당 이름의 힙(heap) 할당 복사본을 반환합니다. 현재 디렉터리 및 이름 매개 변수의 값 대부분에 대해서 이 함수는 올바로 동작합니다. 하지만 name
매개 변수가 특히 길 경우, 두 번째 PathAppend()
호출은 MAX_PATH
바이트보다 작은 outputDirectoryName
버퍼에 오버플로를 일으킬 수 있습니다.umask()
의 인수로 지정된 마스크와 chmod()
의 인수를 혼동하는 경우가 많습니다.umask()
man page는 다음 false 문으로 시작합니다.chmod()
사용법과 일치하는 것 같지만 다음과 같이 umask()
의 실제 동작은 그 반대입니다. umask()
는 umask를 ~mask & 0777
로 설정합니다.umask()
man page는 다음과 같이 umask()
의 정확한 사용법까지 설명합니다.open()
이 새로 생성한 파일에 초기 파일 권한을 설정할 때 사용합니다. 구체적으로 umask의 권한은 open(2)
의 모드 인수에 따라 비활성화됩니다. 예를 들면, 일반적인 umask 기본값 022는 모드가 0666으로 지정되는 일반적인 경우 0666 & ~022 = 0644 = rw-r--r-- 권한으로 새 파일을 생성합니다."
...
struct stat output;
int ret = stat(aFilePath, &output);
// error handling omitted for this example
struct timespec accessTime = output.st_atime;
...
umask()
의 인수로 지정된 마스크와 chmod()
의 인수를 혼동하는 경우가 많습니다.umask()
man page는 다음 false 문으로 시작합니다.chmod()
사용법과 일치하는 것 같지만 다음과 같이 umask()
의 실제 동작은 그 반대입니다. umask()
는 umask를 ~mask & 0777
로 설정합니다.umask()
man page는 다음과 같이 umask()
의 정확한 사용법까지 설명합니다.transactionId
를 씁니다.
...
//get the documents directory:
let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
//make a file name to write the data to using the documents directory:
let fileName = NSString(format:"%@/tmp_activeTrans.txt", documentsPath)
// write data to the file
let transactionId = "TransactionId=12341234"
transactionId.writeToFile(fileName, atomically:true)
...
posted
개체에 할당합니다. FileUpload
는 System.Web.UI.HtmlControls.HtmlInputFile
형식입니다.
HttpPostedFile posted = FileUpload.PostedFile;
@Controller
public class MyFormController {
...
@RequestMapping("/test")
public String uploadFile (org.springframework.web.multipart.MultipartFile file) {
...
} ...
}
<?php
$udir = 'upload/'; // Relative path under Web root
$ufile = $udir . basename($_FILES['userfile']['name']);
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $ufile)) {
echo "Valid upload received\n";
} else {
echo "Invalid upload rejected\n";
} ?>
from django.core.files.storage import default_storage
from django.core.files.base import File
...
def handle_upload(request):
files = request.FILES
for f in files.values():
path = default_storage.save('upload/', File(f))
...
file
형식의 <input>
태그는 프로그램이 파일 업로드를 허용함을 표시합니다.
<input type="file">
myModule.config(function($interpolateProvider){
$interpolateProvider.startSymbol("[[");
$interpolateProvider.endSymbol("]]");
});