API는 호출자와 피호출자 간의 계약입니다. 가장 흔한 형태의 API 오용은 호출자가 이 계약에서 자신의 몫을 이행하지 못하기 때문에 발생합니다. 예를 들어, 프로그램이 chroot()를 호출한 후 chdir()을 호출하지 못하면 활성 루트 디렉터리를 안전하게 변경하는 방법을 지정하는 계약을 위반하는 것입니다. 라이브러리 오용의 또 다른 좋은 예는 피호출자가 호출자에게 신뢰할 만한 DNS 정보를 반환할 것으로 예상하는 것입니다. 이 경우, 호출자는 자신의 행동에 대해 특정한 가정을 함으로써(반환 값이 인증 목적으로 사용될 것으로 예상) 피호출자 API를 오용합니다. 다른 쪽에서 호출자-피호출자 계약을 위반할 수도 있습니다. 예를 들어, 코더가 하위 클래스 SecureRandom을 지정하고 임의 값이 아닌 값을 반환하는 경우 계약을 위반하는 것입니다.
_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("]]");
});
root
권한으로 실행되는 프로그램은 수없이 많은 Unix 보안 문제를 일으킵니다. 모든 종류의 보안 문제에 대해 권한 있는 프로그램을 신중하게 검토하는 일도 시급하지만 간과한 취약점이 일으킬 수 있는 피해 규모를 줄이기 위해 최대한 빨리 권한 있는 프로그램을 권한 없는 상태로 되돌리는 것도 중요합니다.root
사용자가 아닌 사용자에서 다른 사용자로 전환하려 할 때 두드러집니다. root
로 실행될 때 시그널 처리기 또는 하위 프로세스가 실행되는 경우 시그널 처리기나 하위 프로세스는 루트 권한으로 실행됩니다. 공격자는 이 높은 권한을 이용하여 더 큰 피해를 줄 수 있습니다.root
권한으로 실행된 프로그램은 무수한 Unix 보안 재해를 일으켰습니다. 모든 종류의 보안 문제에 대해 권한 있는 프로그램을 신중하게 검토해야 하지만, 간과된 취약성이 야기할 수 있는 피해를 최소화하기 위해 권한 있는 프로그램에서 최대한 빨리 권한을 박탈하는 것도 그에 못지 않게 중요합니다.root
사용자가 아닌 한 사용자에서 다른 사용자로 전환하는 경우 특히 두드러집니다.root
로 실행 중인 경우 신호 처리기 또는 하위 프로세스는 루트 권한으로 작동합니다. 공격자는 이러한 승격된 권한을 활용하여 추가적인 손상을 입힐 수 있습니다.root
권한으로 실행되는 프로그램은 수없이 많은 Unix 보안 문제를 일으킵니다. 모든 종류의 보안 문제에 대해 권한 있는 프로그램을 신중하게 검토하는 일도 시급하지만 간과한 취약점이 일으킬 수 있는 피해 규모를 줄이기 위해 최대한 빨리 권한 있는 프로그램을 권한 없는 상태로 되돌리는 것도 중요합니다.root
사용자가 아닌 사용자에서 다른 사용자로 전환하려 할 때 두드러집니다.root
로 실행될 때 시그널 처리기 또는 하위 프로세스가 실행되는 경우 시그널 처리기나 하위 프로세스는 루트 권한으로 실행됩니다. 공격자는 이 높은 권한을 이용하여 더 큰 피해를 줄 수 있습니다.root
권한으로 실행되는 프로그램은 수없이 많은 Unix 보안 문제를 일으킵니다. 모든 종류의 보안 문제에 대해 권한 있는 프로그램을 신중하게 검토하는 일도 시급하지만 간과한 취약점이 일으킬 수 있는 피해 규모를 줄이기 위해 최대한 빨리 권한 있는 프로그램을 권한 없는 상태로 되돌리는 것도 중요합니다.root
사용자가 아닌 사용자에서 다른 사용자로 전환하려 할 때 두드러집니다.root
로 실행될 때 시그널 처리기 또는 하위 프로세스가 실행되는 경우 시그널 처리기나 하위 프로세스는 루트 권한으로 실행됩니다. 공격자는 이 높은 권한을 이용하여 더 큰 피해를 줄 수 있습니다....
Device.OpenUri("sms:+12345678910");
...
...
[[CTMessageCenter sharedMessageCenter] sendSMSWithText:@"Hello world!" serviceCenter:nil toAddress:@"+12345678910"];
...
// or
...
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms:+12345678910"]];
...
// or
...
MFMessageComposeViewController *messageComposerVC = [[MFMessageComposeViewController alloc] init];
[messageComposerVC setMessageComposeDelegate:self];
[messageComposerVC setBody:@"Hello World!"];
[messageComposerVC setRecipients:[NSArray arrayWithObject:@"+12345678910"]];
[self presentViewController:messageComposerVC animated:YES completion:nil];
...
...
UIApplication.sharedApplication().openURL(NSURL(string: "sms:+12345678910"))
...
...
let messageComposeVC = MFMessageComposeViewController()
messageComposeVC.messageComposeDelegate = self
messageComposeVC.body = "Hello World!"
messageComposeVC.recipients = ["+12345678910"]
presentViewController(messageComposeVC, animated: true, completion: nil)
...
MultiByteToWideChar()
, WideCharToMultiByte()
, UnicodeToBytes()
및 BytesToUnicode()
함수를 제공하여 임의의 멀티바이트(보통 ANSI) 문자열과 유니코드(와이드 문자) 문자열 간 변환을 수행합니다. 이들 함수의 크기 인수는 다른 단위(바이트 또는 문자)로 지정되기 때문에 이들 함수를 사용하면 오류가 발생하기 쉽습니다. 멀티바이트 문자열에서 각 문자가 차지하는 바이트 수가 다르기 때문에 멀티바이트 문자열의 크기는 총 바이트 수로 지정하는 것이 가장 편리합니다. 하지만 유니코드에서는 문자의 크기가 항상 고정되어 있고 문자열 길이를 보통 문자열에 포함된 문자 수로 나타냅니다. 실수로 크기 인수에 잘못된 단위로 값을 지정하면 buffer overflow가 발생할 수 있습니다.
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);
}
unicodeUser
의 크기를 문자 수가 아닌 바이트 수로 잘못 전달합니다. 따라서 MultiByteToWideChar()
호출에는 (UNLEN+1)*sizeof(WCHAR
) 길이의 문자 또는 (UNLEN+1)*sizeof(WCHAR)*sizeof(WCHAR)
바이트까지 (UNLEN+1)*sizeof(WCHAR)
바이트만 할당된 unicodeUser
배열에 쓸 수 있습니다. username
문자열에 UNLEN
문자 넘게 포함되면 MultiByteToWideChar()
호출은 버퍼 unicodeUser
오버플로를 일으킵니다.sun.misc.Unsafe
의 기능을 사용합니다. 이 클래스의 모든 기능은 기본적으로 사용하기에 안전하지 않으며 리플렉션을 통해서만 액세스할 수 있습니다.sun.misc.Unsafe
클래스는 안전하지 않은 하위 수준 작업 수행용이며 개발자는 사용하면 안 됩니다.Unsafe
클래스는 신뢰할 수 있는 코드에서만 사용해야 하며, 일반적으로는 리플렉션을 통해 액세스해야 합니다. 이 클래스는 시스템을 손상시키거나 힙 메모리를 수동으로 할당하는 데 사용될 수 있으므로, 적절하게 취급하지 않으면 시스템에 심각한 영향을 줄 수 있기 때문입니다. sun.misc.Unsafe
와 관련된 모든 기능을 철저하게 검토 및 테스트하여 결함이 없는지 확인해야 합니다.
String password=request.getParameter("password");
...
DefaultUser user = (DefaultUser) ESAPI.authenticator().createUser(username, password, password);
finalize()
메서드는 개체를 가비지 수집(garbage collection)한 후 JVM 만 호출할 수 있습니다.finalize()
메서드를 종결자(finalizer) 외부에서 호출할 수 있다고 되어 있지만 이는 일반적으로 잘못된 방법입니다. 예를 들어, finalize()
를 명시적으로 호출하면 finalize()
가 두 번 이상 호출됩니다. 첫 호출은 명시적인 호출이고 마지막 호출은 개체를 가비지 수집(garbage collection)한 후 이루어지는 호출입니다.finalize()
를 명시적으로 호출합니다.
// time to clean up
widget.finalize();
dangerouslySetInnerHTML
속성이 코드에서 불필요하게 HTML을 설정합니다.dangerouslySetInnerHTML
속성은 브라우저 DOM에서 innerHTML을 사용하는 대신 사용할 수 있습니다. 이 속성을 사용할 때 발생 가능한 위험을 파악할 수 있도록 API 이름이 바뀌었습니다. 일반적으로는 코드에서 HTML을 설정하면 위험합니다. 사용자가 의도치 않게 Cross-Site Scripting(XSS) 공격에 노출되기 쉽기 때문입니다.dangerouslySetInnerHTML
속성으로 설정합니다.
function MyComponent(data) {
return (
<div
dangerouslySetInnerHTML={{__html: data.innerHTML}}
/>
);
}
AUTHID CURRENT_USER
패키지에서 식별자는 먼저 현재 사용자의 스키마에 대해 확인됩니다. 그러면 식별자가 속해 있는 스키마를 코드의 정의자가 명시적으로 밝히지 않는 경우 예기치 못한 동작이 발생할 수 있습니다.SYS.PERMISSIONS
에 대한 읽기 권한만 있으며 정의된 권한을 수정할 수 없습니다.
CREATE or REPLACE FUNCTION check_permissions(
p_name IN VARCHAR2, p_action IN VARCHAR2)
RETURN BOOLEAN
AUTHID CURRENT_USER
IS
r_count NUMBER;
perm BOOLEAN := FALSE;
BEGIN
SELECT count(*) INTO r_count FROM PERMISSIONS
WHERE name = p_name AND action = p_action;
IF r_count > 0 THEN
perm := TRUE;
END IF;
RETURN perm;
END check_permissions
check_permissions
함수를 호출하는 사용자가 해당 스키마에서 PERMISSIONS
테이블을 정의하는 경우, 데이터베이스에서 식별자는 로컬 테이블을 참조합니다. 사용자는 새 테이블에 대한 쓰기 권한이 있으며 원래는 없던 권한을 얻도록 수정할 수 있습니다.org.apache.struts2.interceptor.ApplicationtAware
, org.apache.struts2.interceptor.SessionAware
및 org.apache.struts2.interceptor.RequestAware
가 있습니다. 이러한 데이터 맵을 자신이 개발한 Actions 코드에 삽입하려는 개발자는 인터페이스에 지정된 setter를 구현해야 합니다(예: SessionAware
인터페이스의 경우 setSession
).
public class VulnerableAction extends ActionSupport implements SessionAware {
protected Map<String, Object> session;
@Override
public void setSession(Map<String, Object> session) {
this.session = session;
}
SessionAware
, RequestAware
, ApplicationAware
인터페이스에서 보여 준 것처럼 원격 공격자가 영향을 받는 인터페이스를 구현한 응용 프로그램에 조작된 매개 변수를 제공하여 런타임 데이터 값을 수정할 수 있습니다.
http://server/VulnerableAction?session.roles=admin
execute()
메서드를 오버라이드할 수 있는 public 메서드를 노출합니다.execute()
이외의 메서드를 노출할 수 있도록 하는 "동적 메서드 호출"이라는 기능이 도입되었습니다. "동적 메서드 호출"이 활성화된 경우 Action URL에 !
(느낌표) 문자 또는 method:
접두사를 사용하여 Action의 모든 public 메서드를 호출할 수 있습니다. 이 기능을 알지 못하는 개발자는 내부 비즈니스 로직을 공격자에게 실수로 노출할 수 있습니다.http://server/app/recoverpassword!getPassword.action
org.apache.struts2.interceptor.ApplicationtAware
, org.apache.struts2.interceptor.SessionAware
및 org.apache.struts2.interceptor.RequestAware
가 있습니다. 이러한 데이터 맵을 자신이 개발한 Actions 코드에 삽입하려는 개발자는 인터페이스에 지정된 setter를 구현해야 합니다(예: SessionAware
인터페이스의 경우 setSession
).
public class VulnerableAction extends ActionSupport implements SessionAware {
protected Map<String, Object> session;
@Override
public void setSession(Map<String, Object> session) {
this.session = session;
}
SessionAware
, RequestAware
, ApplicationAware
인터페이스에서 보여 준 것처럼 원격 공격자가 영향을 받는 인터페이스를 구현한 응용 프로그램에 조작된 매개 변수를 제공하여 런타임 데이터 값을 수정할 수 있습니다.
http://server/VulnerableAction?session.roles=admin
org.apache.struts2.interceptor.ApplicationtAware
, org.apache.struts2.interceptor.SessionAware
및 org.apache.struts2.interceptor.RequestAware
가 있습니다. 이러한 데이터 맵을 자신이 개발한 Actions 코드에 삽입하려는 개발자는 인터페이스에 지정된 setter를 구현해야 합니다(예: SessionAware
인터페이스의 경우 setSession
).
public class VulnerableAction extends ActionSupport implements SessionAware {
protected Map<String, Object> session;
@Override
public void setSession(Map<String, Object> session) {
this.session = session;
}
SessionAware
, RequestAware
, ApplicationAware
인터페이스에서 보여 준 것처럼 원격 공격자가 영향을 받는 인터페이스를 구현한 응용 프로그램에 조작된 매개 변수를 제공하여 런타임 데이터 값을 수정할 수 있습니다.
http://server/VulnerableAction?session.roles=admin