입력 검증 및 표현 문제는 메타 문자, 대체 인코딩 및 숫자 표현 때문에 발생합니다. 보안 문제는 입력을 신뢰하기 때문에 발생합니다. 문제로는 "Buffer Overflows", "Cross-Site Scripting" 공격, "SQL Injection", 그 외 여러 가지가 있습니다.
debug
요청 매개 변수를 사용하여 트리거할 수 있습니다.console
인 경우 개발자가 서버에서 임의의 OGNL 식을 평가할 수 있는 OGNL 평가 콘솔이 팝업으로 표시됩니다.command
인 경우 개발자는 요청 매개 변수 expression
을 사용하여 평가할 임의의 OGNL 식을 제출할 수 있습니다.xml
은 매개 변수, 컨텍스트, 세션 및 값 스택을 XML 문서로 덤프합니다.browser
는 매개 변수, 컨텍스트, 세션 및 값 스택을 검색 가능한 HTML 문서로 덤프합니다.dest
요청 매개 변수에서 구문 분석한 URL을 열도록 지시합니다.
...
DATA: str_dest TYPE c.
str_dest = request->get_form_field( 'dest' ).
response->redirect( str_dest ).
...
Example 1
의 코드가 브라우저를 “http://www.wilyhacker.com”으로 리디렉션합니다.dest
요청 매개 변수에서 읽어들인 URL을 열도록 지시합니다.
...
var params:Object = LoaderInfo(this.root.loaderInfo).parameters;
var strDest:String = String(params["dest"]);
host.updateLocation(strDest);
...
Example 1
의 코드가 브라우저를 “http://www.wilyhacker.com”으로 리디렉션합니다.dest
요청 매개 변수의 URL로 구성된 PageReference
개체를 반환합니다.
public PageReference pageAction() {
...
PageReference ref = ApexPages.currentPage();
Map<String,String> params = ref.getParameters();
return new PageReference(params.get('dest'));
}
Example 1
의 코드가 브라우저를 "http://www.wilyhacker.com"으로 리디렉션합니다.aspnet:AllowRelaxedRelativeUrl
설정을 사용하여 무제한 URL 리디렉션을 허용하도록 수정될 수 있습니다. 이러한 취약점을 성공적으로 익스플로이트한 공격자는 사용자 동의 없이 공격자가 선택한 웹 사이트로 사용자를 리디렉션할 수 있게 됩니다. 그런 다음 공격자는 피싱 공격을 수행하여 사용자로부터 공개할 의도가 없는 정보를 획득할 수 있습니다.aspnet:AllowRelaxedRelativeUrl
이 true
로 설정됩니다.
...
<appSettings>
<add key="aspnet:AllowRelaxedRelativeUrl" value="true" />
</appSettings>
...
dest
요청 매개 변수에서 구문 분석한 URL을 열도록 지시합니다.
...
final server = await HttpServer.bind(host, port);
await for (HttpRequest request in server) {
final response = request.response;
final headers = request.headers;
final strDest = headers.value('strDest');
response.headers.contentType = ContentType.text;
response.redirect(Uri.parse(strDest!));
await response.close();
}
...
Example 1
의 코드가 브라우저를 “http://www.wilyhacker.com”으로 리디렉션합니다.dest
요청 매개 변수에서 구문 분석한 URL을 열도록 지시합니다.
...
strDest := r.Form.Get("dest")
http.Redirect(w, r, strDest, http.StatusSeeOther)
...
Example 1
의 코드가 브라우저를 “http://www.wilyhacker.com”으로 리디렉션합니다.dest
요청 매개 변수에서 구문 분석한 URL을 열도록 지시합니다.
<end-state id="redirectView" view="externalRedirect:#{requestParameters.dest}" />
Example 1
의 코드가 브라우저를 “http://www.wilyhacker.com”으로 리디렉션합니다.dest
요청 매개 변수에서 읽어 들인 URL을 열도록 지시합니다.
...
strDest = form.dest.value;
window.open(strDest,"myresults");
...
Example 1
의 코드가 브라우저를 “http://www.wilyhacker.com”으로 리디렉션합니다.dest
요청 매개 변수에서 구문 분석한 URL을 열도록 사용자 브라우저에 지시합니다.
<%
...
$strDest = $_GET["dest"];
header("Location: " . $strDest);
...
%>
Example 1
의 코드가 브라우저를 “http://www.wilyhacker.com”으로 리디렉션합니다.dest
요청 매개 변수에서 구문 분석한 URL을 열도록 지시합니다.
...
-- Assume QUERY_STRING looks like dest=http://www.wilyhacker.com
dest := SUBSTR(OWA_UTIL.get_cgi_env('QUERY_STRING'), 6);
OWA_UTIL.redirect_url('dest');
...
Example 1
의 코드가 브라우저를 “http://www.wilyhacker.com”으로 리디렉션합니다.dest
요청 매개 변수에서 구문 분석한 URL을 열도록 지시합니다.
...
strDest = request.field("dest")
redirect(strDest)
...
Example 1
의 코드가 브라우저를 “http://www.wilyhacker.com”으로 리디렉션합니다.dest
요청 매개 변수에서 구문 분석한 URL을 열도록 지시합니다.
...
str_dest = req.params['dest']
...
res = Rack::Response.new
...
res.redirect("http://#{dest}")
...
Example 1
의 코드가 브라우저를 “http://www.wilyhacker.com”으로 리디렉션합니다.dest
요청 매개 변수에서 구문 분석한 URL을 열도록 지시합니다.
def myAction = Action { implicit request =>
...
request.getQueryString("dest") match {
case Some(location) => Redirect(location)
case None => Ok("No url found!")
}
...
}
Example 1
의 코드가 브라우저를 “http://www.wilyhacker.com”으로 리디렉션합니다.dest
요청 매개 변수에서 구문 분석한 URL을 열도록 지시합니다.
...
strDest = Request.Form('dest')
HyperLink.NavigateTo strDest
...
Example 1
의 코드가 브라우저를 “http://www.wilyhacker.com”으로 리디렉션합니다.strncpy()
와 같은 범위 지정 함수도 잘못 사용되면 취약점을 일으킬 수 있습니다. 대부분의 buffer overflow의 원인은 메모리 조작과 데이터의 크기 또는 구성에 대한 가정 위반이 결합된 것입니다.memcpy()
호출은 cArray
의 할당된 경계 외부에서 메모리를 읽습니다. 여기에는 char
유형의 MAX
요소가 포함되지만 iArray
에는 int
유형의 MAX
요소가 포함됩니다.예제 2: 다음의 간단한 프로그램은 분석할 상수 바이트와 함께
void MemFuncs() {
char array1[MAX];
int array2[MAX];
memcpy(array2, array1, sizeof(array2));
}
memchr()
호출에서 신뢰할 수 없는 명령줄 인수를 검색 버퍼로 사용합니다.
int main(int argc, char** argv) {
char* ret = memchr(argv[0], 'x', MAX_PATH);
printf("%s\n", ret);
}
argv[0]
데이터를 상수 바이트까지 검색하여 argv[0]
의 부분 문자열을 인쇄하기 위한 것입니다. 그러나, 상수 바이트가 argv[0]
에 할당된 데이터보다 클 수도 있기 때문에 검색은 argv[0]
에 할당된 데이터를 넘어 계속됩니다. 이는 x
가 argv[0]
에 없을 경우입니다.strncpy()
와 같은 범위 지정 함수도 잘못 사용되면 취약점을 일으킬 수 있습니다. 대부분의 buffer overflow의 원인은 메모리 조작과 데이터의 크기 또는 구성에 대한 가정 위반이 결합된 것입니다.char
의 5 요소 배열을 연속적으로 역참조합니다.
char Read() {
char buf[5];
return 0
+ buf[0]
+ buf[1]
+ buf[2]
+ buf[3]
+ buf[4]
+ buf[5];
}
strncpy()
와 같은 범위 지정 함수도 잘못 사용되면 취약점을 일으킬 수 있습니다. 대부분의 buffer overflow의 원인은 메모리 조작과 데이터의 크기 또는 구성에 대한 가정 위반이 결합된 것입니다.getInputLength()
에서 읽은 신뢰할 수 없는 값이 대상 버퍼 output
의 크기보다 작은지 확인하여 경계 외부에서 buffer overflow를 읽는 것을 막습니다. 그러나 len
과 MAX
의 비교에 부호가 있으므로 len
이 음수인 경우 부호 없는 인수가 memcpy()
로 변환되면 매우 큰 양수가 됩니다.
void TypeConvert() {
char input[MAX];
char output[MAX];
fillBuffer(input);
int len = getInputLength();
if (len <= MAX) {
memcpy(output, input, len);
}
...
}
...
*Get the report that is to be deleted
r_name = request->get_form_field( 'report_name' ).
CONCATENATE `C:\\users\\reports\\` r_name INTO dsn.
DELETE DATASET dsn.
...
..\\..\\usr\\sap\\DVEBMGS00\\exe\\disp+work.exe
" 등의 파일 이름을 지정하면 응용 프로그램이 중요 파일을 삭제하게 되므로 SPS 시스템이 즉시 중단됩니다.
...
PARAMETERS: p_date TYPE string.
*Get the invoice file for the date provided
CALL FUNCTION 'FILE_GET_NAME'
EXPORTING
logical_filename = 'INVOICE'
parameter_1 = p_date
IMPORTING
file_name = v_file
EXCEPTIONS
file_not_found = 1
OTHERS = 2.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
OPEN DATASET v_file FOR INPUT IN TEXT MODE.
DO.
READ DATASET v_file INTO v_record.
IF SY-SUBRC NE 0.
EXIT.
ELSE.
WRITE: / v_record.
ENDIF.
ENDDO.
...
..\\..\\usr\\sap\\sys\\profile\\default.pfl
" 등의 문자열을 지정하면 응용 프로그램은 모든 기본 SAP 응용 프로그램 서버 매개 변수 설정을 노출시키고, 이는 더욱 치밀한 공격으로 이어질 수 있습니다.../../tomcat/conf/server.xml
" 등의 파일 이름을 제공하여 응용 프로그램이 자신의 구성 파일을 삭제하게 만들 가능성을 고려하지 않았습니다.예제 2: 다음 코드는 구성 파일의 입력을 사용하여 열 파일을 결정하고 "디버그" 콘솔 또는 로그 파일에 씁니다. 프로그램이 일정한 권한으로 실행되고 악의적인 사용자가 구성 파일을 변경할 수 있는 경우, 이 프로그램을 사용하여 시스템에서 확장명이
var params:Object = LoaderInfo(this.root.loaderInfo).parameters;
var rName:String = String(params["reportName"]);
var rFile:File = new File("/usr/local/apfr/reports/" + rName);
...
rFile.deleteFile();
.txt
인 파일을 읽을 수 있습니다.
var fs:FileStream = new FileStream();
fs.open(new File(String(configStream.readObject())+".txt"), FileMode.READ);
fs.readBytes(arr);
trace(arr);
public class MyController {
...
public PageRerference loadRes() {
PageReference ref = ApexPages.currentPage();
Map<String,String> params = ref.getParameters();
if (params.containsKey('resName')) {
if (params.containsKey('resPath')) {
return PageReference.forResource(params.get('resName'), params.get('resPath'));
}
}
return null;
}
}
..\\..\\Windows\\System32\\krnl386.exe
" 등의 파일 이름을 제공하여 응용 프로그램이 중요한 Windows 시스템 파일을 삭제하게 만들 가능성을 고려하지 않았습니다.예제 2: 다음 코드는 구성 파일의 입력을 사용하여 열 파일을 결정하고 사용자에게 돌려 보냅니다. 프로그램이 충분한 권한으로 실행되고 악의적인 사용자가 구성 파일을 변경할 수 있는 경우, 이 프로그램을 사용하여 시스템에서 확장명이 ".txt"인 파일을 읽을 수 있습니다.
String rName = Request.Item("reportName");
...
File.delete("C:\\users\\reports\\" + rName);
sr = new StreamReader(resmngr.GetString("sub")+".txt");
while ((line = sr.ReadLine()) != null) {
Console.WriteLine(line);
}
../../apache/conf/httpd.conf
" 등의 파일 이름을 제공하여 응용 프로그램이 지정한 구성 파일을 삭제하게 만들 가능성을 고려하지 않았습니다.예제 2: 다음 코드는 명령줄의 입력을 사용하여 열 파일을 결정하고 사용자에게 돌려 보냅니다. 프로그램이 충분한 권한으로 실행되고 악의적인 사용자가 파일에 대한 소프트 링크를 만들게 되면 프로그램을 이용하여 시스템의 모든 파일의 첫 부분을 읽을 수 있습니다.
char* rName = getenv("reportName");
...
unlink(rName);
ifstream ifs(argv[0]);
string s;
ifs >> s;
cout << s;
...
EXEC CICS
WEB READ
FORMFIELD(FILE)
VALUE(FILENAME)
...
END-EXEC.
EXEC CICS
READ
FILE(FILENAME)
INTO(RECORD)
RIDFLD(ACCTNO)
UPDATE
...
END-EXEC.
...
..\\..\\Windows\\System32\\krnl386.exe
" 등의 파일 이름을 제공하여 응용 프로그램이 중요한 Windows 시스템 파일을 삭제하게 만들 가능성을 고려하지 않았습니다.
<cffile action = "delete"
file = "C:\\users\\reports\\#Form.reportName#">
final server = await HttpServer.bind('localhost', 18081);
server.listen((request) async {
final headers = request.headers;
final path = headers.value('path');
File(path!).delete();
}
Example 1
에서는 파일에 대한 삭제 기능을 수행하기 전에 headers.value('path')
의 유효성을 검사하지 않습니다.../../tomcat/conf/server.xml
" 등의 파일 이름을 제공하여 응용 프로그램이 자신의 구성 파일을 삭제하게 만들 가능성을 고려하지 않았습니다.예제 2: 다음 코드는 구성 파일의 입력을 사용하여 열 파일을 결정하고 사용자에게 돌려 보냅니다. 프로그램이 일정한 권한으로 실행되고 악의적인 사용자가 구성 파일을 변경할 수 있는 경우, 이 프로그램을 사용하여 시스템에서 확장명이
rName := "/usr/local/apfr/reports/" + req.FormValue("fName")
rFile, err := os.OpenFile(rName, os.O_RDWR|os.O_CREATE, 0755)
defer os.Remove(rName);
defer rFile.Close()
...
.txt
인 파일을 읽을 수 있습니다.
...
config := ReadConfigFile()
filename := config.fName + ".txt";
data, err := ioutil.ReadFile(filename)
...
fmt.Println(string(data))
../../tomcat/conf/server.xml
" 등의 파일 이름을 제공하여 응용 프로그램이 자신의 구성 파일을 삭제하게 만들 가능성을 고려하지 않았습니다.예제 2: 다음 코드는 구성 파일의 입력을 사용하여 열 파일을 결정하고 사용자에게 돌려 보냅니다. 프로그램이 일정한 권한으로 실행되고 악의적인 사용자가 구성 파일을 변경할 수 있는 경우, 이 프로그램을 사용하여 시스템에서 확장명이
String rName = request.getParameter("reportName");
File rFile = new File("/usr/local/apfr/reports/" + rName);
...
rFile.delete();
.txt
인 파일을 읽을 수 있습니다.
fis = new FileInputStream(cfg.getProperty("sub")+".txt");
amt = fis.read(arr);
out.println(arr);
Example 1
을 Android 플랫폼에 맞게 조정합니다.
...
String rName = this.getIntent().getExtras().getString("reportName");
File rFile = getBaseContext().getFileStreamPath(rName);
...
rFile.delete();
...
../../tomcat/conf/server.xml
" 등의 파일 이름을 제공하여 응용 프로그램이 자신의 구성 파일을 삭제하게 만들 가능성을 고려하지 않았습니다.예제 2: 다음 코드는 로컬 저장소의 입력을 사용하여 열 파일을 결정하고 사용자에게 돌려보냅니다. 악의적인 사용자가 로컬 저장소의 내용을 변경할 수 있는 경우, 이 프로그램을 사용하여 시스템에서 확장명이
...
var reportNameParam = "reportName=";
var reportIndex = document.indexOf(reportNameParam);
if (reportIndex < 0) return;
var rName = document.URL.substring(reportIndex+reportNameParam.length);
window.requestFileSystem(window.TEMPORARY, 1024*1024, function(fs) {
fs.root.getFile('/usr/local/apfr/reports/' + rName, {create: false}, function(fileEntry) {
fileEntry.remove(function() {
console.log('File removed.');
}, errorHandler);
}, errorHandler);
}, errorHandler);
.txt
인 파일을 읽을 수 있습니다.
...
var filename = localStorage.sub + '.txt';
function oninit(fs) {
fs.root.getFile(filename, {}, function(fileEntry) {
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function(e) {
var txtArea = document.createElement('textarea');
txtArea.value = this.result;
document.body.appendChild(txtArea);
};
reader.readAsText(file);
}, errorHandler);
}, errorHandler);
}
window.requestFileSystem(window.TEMPORARY, 1024*1024, oninit, errorHandler);
...
../../tomcat/conf/server.xml
" 등의 파일 이름을 제공하여 응용 프로그램이 자신의 구성 파일을 삭제하게 만들 가능성을 고려하지 않았습니다.예제 2: 다음 코드는 구성 파일의 입력을 사용하여 열 파일을 결정하고 사용자에게 돌려 보냅니다. 프로그램이 일정한 권한으로 실행되고 악의적인 사용자가 구성 파일을 변경할 수 있는 경우, 이 프로그램을 사용하여 시스템에서 확장명이
val rName: String = request.getParameter("reportName")
val rFile = File("/usr/local/apfr/reports/$rName")
...
rFile.delete()
.txt
인 파일을 읽을 수 있습니다.
fis = FileInputStream(cfg.getProperty("sub").toString() + ".txt")
amt = fis.read(arr)
out.println(arr)
Example 1
을 Android 플랫폼에 맞게 조정합니다.
...
val rName: String = getIntent().getExtras().getString("reportName")
val rFile: File = getBaseContext().getFileStreamPath(rName)
...
rFile.delete()
...
- (NSData*) testFileManager {
NSString *rootfolder = @"/Documents/";
NSString *filePath = [rootfolder stringByAppendingString:[fileName text]];
NSFileManager *fm = [NSFileManager defaultManager];
return [fm contentsAtPath:filePath];
}
../../tomcat/conf/server.xml
" 등의 파일 이름을 제공하여 응용 프로그램이 자신의 구성 파일을 삭제하게 만들 가능성을 고려하지 않았습니다.예제 2: 다음 코드는 구성 파일의 입력을 사용하여 열 파일을 결정하고 사용자에게 돌려 보냅니다. 프로그램이 일정한 권한으로 실행되고 악의적인 사용자가 구성 파일을 변경할 수 있는 경우, 이 프로그램을 사용하여 시스템에서 확장명이
$rName = $_GET['reportName'];
$rFile = fopen("/usr/local/apfr/reports/" . rName,"a+");
...
unlink($rFile);
.txt
인 파일을 읽을 수 있습니다.
...
$filename = $CONFIG_TXT['sub'] . ".txt";
$handle = fopen($filename,"r");
$amt = fread($handle, filesize($filename));
echo $amt;
...
../../tomcat/conf/server.xml
" 등의 파일 이름을 제공하여 응용 프로그램이 자신의 구성 파일을 삭제하게 만들 가능성을 고려하지 않았습니다.예제 2: 다음 코드는 구성 파일의 입력을 사용하여 열 파일을 결정하고 사용자에게 돌려 보냅니다. 프로그램이 일정한 권한으로 실행되고 악의적인 사용자가 구성 파일을 변경할 수 있는 경우, 이 프로그램을 사용하여 시스템에서 확장명이
rName = req.field('reportName')
rFile = os.open("/usr/local/apfr/reports/" + rName)
...
os.unlink(rFile);
.txt
인 파일을 읽을 수 있습니다.
...
filename = CONFIG_TXT['sub'] + ".txt";
handle = os.open(filename)
print handle
...
../../tomcat/conf/server.xml
" 등의 파일 이름을 제공하여 응용 프로그램이 자신의 구성 파일을 삭제하게 만들 가능성을 고려하지 않았습니다.예제 2: 다음 코드는 구성 파일의 입력을 사용하여 열 파일을 결정하고 사용자에게 돌려 보냅니다. 프로그램이 일정한 권한으로 실행되고 악의적인 사용자가 구성 파일을 변경할 수 있는 경우, 이 프로그램을 사용하여 시스템에서 확장명이
rName = req['reportName']
File.delete("/usr/local/apfr/reports/#{rName}")
.txt
인 파일을 읽을 수 있습니다.
...
fis = File.new("#{cfg.getProperty("sub")}.txt")
amt = fis.read
puts amt
../../tomcat/conf/server.xml
" 등의 파일 이름을 제공하여 응용 프로그램이 자신의 구성 파일을 삭제하게 만들 가능성을 고려하지 않았습니다.예제 2: 다음 코드는 구성 파일의 입력을 사용하여 열 파일을 결정하고 사용자에게 돌려 보냅니다. 프로그램이 일정한 권한으로 실행되고 악의적인 사용자가 구성 파일을 변경할 수 있는 경우, 이 프로그램을 사용하여 시스템에서 확장명이
def readFile(reportName: String) = Action { request =>
val rFile = new File("/usr/local/apfr/reports/" + reportName)
...
rFile.delete()
}
.txt
인 파일을 읽을 수 있습니다.
val fis = new FileInputStream(cfg.getProperty("sub")+".txt")
val amt = fis.read(arr)
out.println(arr)
func testFileManager() -> NSData {
let filePath : String = "/Documents/\(fileName.text)"
let fm : NSFileManager = NSFileManager.defaultManager()
return fm.contentsAtPath(filePath)
}
..\conf\server.xml
" 등의 파일 이름을 제공하여 응용 프로그램이 자신의 구성 파일을 삭제하게 만들 가능성을 고려하지 않았습니다.예제 2: 다음 코드는 구성 파일의 입력을 사용하여 열 파일을 결정하고 사용자에게 돌려 보냅니다. 프로그램이 일정한 권한으로 실행되고 악의적인 사용자가 구성 파일을 변경할 수 있는 경우, 이 프로그램을 사용하여 시스템에서 확장명이
Dim rName As String
Dim fso As New FileSystemObject
Dim rFile as File
Set rName = Request.Form("reportName")
Set rFile = fso.GetFile("C:\reports\" & rName)
...
fso.DeleteFile("C:\reports\" & rName)
...
.txt
인 파일을 읽을 수 있습니다.
Dim fileName As String
Dim tsContent As String
Dim ts As TextStream
Dim fso As New FileSystemObject
fileName = GetPrivateProfileString("MyApp", "sub", _
"", value, Len(value), _
App.Path & "\" & "Config.ini")
...
Set ts = fso.OpenTextFile(fileName,1)
tsContent = ts.ReadAll
Response.Write tsContent
...
Path.Combine
은 여러 파일 경로를 인수로 사용합니다. 일반적으로 파일에 대한 read()
또는 write()
호출 후에 여러 파일 경로를 연결하여 하나의 전체 경로를 가져옵니다. 첫 번째 또는 나머지 매개 변수가 절대 경로인지 여부에 따라 서로 다른 여러 시나리오가 설명서에 설명되어 있습니다. 두 번째 또는 나머지 매개 변수가 절대 경로인 경우 Path.Combine()
은 해당 절대 경로를 반환합니다. 이전 매개 변수는 무시됩니다. 이 경우 다음 예제와 유사한 코드가 있는 응용 프로그램에서 심각한 영향이 발생합니다.
// Called with user-controlled data
public static bytes[] getFile(String filename)
{
String imageDir = "\\FILESHARE\images\";
filepath = Path.Combine(imageDir, filename);
return File.ReadAllBytes(filepath);
}
C:\\inetpub\wwwroot\web.config
)를 제공하여 응용 프로그램이 반환하는 파일을 제어할 수 있습니다.