Code/PHP

[php 웹보안] 이중 인코딩( Double encoding) 공격 방법과 대책

codens 2022. 11. 23. 03:54

    - 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"] ?? '';

// 보안 조치 : 위험 문자 변경,   <   =>   &lt;
// 하지만 < 가 %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

 

반응형