[php 웹보안] 이중 인코딩( Double encoding) 공격 방법과 대책
- URL 더블 인코딩(Double URI-encoding) 공격과 방어 방법
- URL Encoded Attacks and Prevention(Defence)
//-------------------------------------
< 디렉토리 순회 공격 (Directory Traversal , Path Traversal ) >
- 예기치 않은 경로의 파일 읽기
<?php
// 이미 자동으로 디코딩된 상태(1차 디코딩) ,
// 이중인코딩 입력시 : %252F => %2F 로 변환되어 들어옴
$path0 = $path = $_GET["file"] ?? '';
// 보안 검사 : ../ 가 있는지 검사
// 하지만 / 가 %2F 로 변경되어 있는 상태라서 검사에 적용 안됨
if (strstr($path, "../") or strstr($path, "..\\")) {
exit("Directory traversal attempt detected.");
}
// 사용자 입력 디코딩(코드상으로는 처음이지만, 실제는 2차 디코딩)
// 공격 코드가 완성됨
$path = urldecode($path);
// 파일 경로 읽기
echo htmlentities(file_get_contents("uploads1/" . $path));
//-------------------------------------
- 인코딩 없음
http://localhost/php/double_enc.php?file=../../.env1
- 1번 인코딩 - 서버에 사용될때는 한번 자동으로 디코딩 되므로 인코딩 없음과 입력은 결과적으로 동일
http://localhost/php/double_enc.php?file=..%2F..%2F.env1
- 2번 인코딩 - 위 코드의 보안 필터 통과
http://localhost/php/double_enc.php?file=..%252F..%252F.env1
//-----------------------------------------------------------------------------
< 크로스 사이트 스크립팅 공격 (XSS , Cross Site Scripting ) >
- 사용자의 자바스크립트 코드를 다른 사용자에게 실행
<?php
// 이미 자동으로 디코딩된 상태(1차 디코딩) ,
// 이중인코딩 입력시 : %253C => %3C 로 변환되어 들어옴
$name0 = $name = $_GET["name"] ?? '';
// 보안 조치 : 위험 문자 변경, < => <
// 하지만 < 가 %3C 로 변경되어 있는 상태라서 변경에 적용 안됨
$name = htmlentities($name);
// 사용자 입력 디코딩(코드상으로는 처음이지만, 실제는 2차 디코딩)
// 공격 코드가 완성됨
$name = urldecode($name);
// 출력시 사용자 자바스크립트 코드가 실행됨
echo "Hello " . $name;
//-------------------------------------
- 인코딩 없음
http://localhost/php/double_enc2.php?name=<script>console.log(1)</script>
- 1번 인코딩
http://localhost/php/double_enc2.php?name=%3Cscript%3Econsole.log%281%29%3C%2Fscript%3E
- 2번 인코딩 - htmlentities를 통한 스크립트 필터링이 무력화됨
http://localhost/php/double_enc2.php?name=%253Cscript%253Econsole.log%25281%2529%253C%252Fscript%253E
//-----------------------------------------------------------------------------
< 방어법 >
* 두번의 디코딩이 없는지 확인
- 디코딩을 코드상에서 한번해도 실제로는 2번한 것이 됨
- 사용자 입력이 들어올때 자동으로 1번 디코딩 된 상태
* 보안 검증전에 디코딩해서 검증
- 이후 코드에 사용되는 수준으로 완전히 디코딩된 상태에서 보안검증 코드를 실행한다.
//-------------------------------------
< 참고 >
https://en.wikipedia.org/wiki/Double_encoding
URL Encoded Attacks
https://www.cgisecurity.com/lib/URLEmbeddedAttacks.html
Double Encoding
https://owasp.org/www-community/Double_Encoding
JavaScript 삽입 공격 방지(VB)
https://learn.microsoft.com/ko-kr/aspnet/mvc/overview/older-versions-1/security/preventing-javascript-injection-attacks-vb
CWE-174: Double Decoding of the Same Data
https://cwe.mitre.org/data/definitions/174.html
CWE-180: Incorrect Behavior Order: Validate Before Canonicalize
https://cwe.mitre.org/data/definitions/180.html