Taint

Taint (오염 검사 확장)

XSS 같은 웹 취약점을 코드에서 찾아내고 싶을 때 유용한 확장이에요. 사용자 입력에서 들어온 문자열을 '오염된(tainted)' 문자열로 표시해 두고, 그 값이 위험한 지점(출력, SQL, 셸 명령, 파일 경로 등)에 도달하면 경고를 띄워 주죠. 단, 이건 개발·감사용 도구이고 실제 배포 환경용 방어는 아니라는 점을 꼭 기억해야 해요.

출처: Taint

본문

소개

Taint는 XSS 코드(오염된 문자열)를 탐지하는 확장이에요. SQL 인젝션, 셸 인젝션, 파일 경로 인젝션 같은 비슷한 취약점을 찾는 데도 쓸 수 있어요.

Taint를 켜면 요청 시작 시점에 사용자 입력에서 받은 문자열 — $_GET, $_POST, $_COOKIE — 이 오염된 것으로 표시되고, 그 표시가 문자열 연산을 따라 계속 추적돼요. 오염된 문자열이 위험한 sink(출력, SQL 쿼리, 셸 명령, 파일 경로 등)에 도달하면 Taint는 그 지점을 가리키는 경고를 띄워요. 자세한 목록은 Propagation과 Checked Sinks 문서를 참고하면 돼요.

중요한 점은, Taint는 런타임 방어가 아니라 개발·감사 도구라는 거예요. 가능한 문제를 보고할 뿐 데이터를 막거나 바꾸지 않아요. 의도적으로 보수적으로 동작해서 과다 보고할 수도 있고, 그래서 검사가 깨끗하다고 해서 '증명된 안전'이 아니라 'Taint가 볼 수 있는 것만 없다'는 뜻이에요. 프로덕션 환경에서는 절대 켜지 마세요.

예제

Example #1 Taint example

<?php
$a = trim($_GET['a']);

$file_name = '/tmp/' . $a;
$output    = "Welcome, {$a} !!!";
$sql       = "SELECT * FROM users WHERE name = " . $a;

echo $output;
print $output;
include $file_name;
mysqli_query($link, $sql);
?>

위 예제는 대략 다음과 같은 경고를 출력해요.

Warning: main() [echo]: Attempt to echo a string that might be tainted in /path/to/script.php on line 9

Warning: main() [print]: Attempt to print a string that might be tainted in /path/to/script.php on line 10

Warning: main() [include]: File path contains data that might be tainted in /path/to/script.php on line 11

Warning: main() [mysqli_query]: SQL statement contains data that might be tainted in /path/to/script.php on line 12

함수 참조

Taint Functions

  • is_tainted — Check whether a string is tainted
  • taint — Mark strings as tainted
  • untaint — Remove the taint mark from strings

더 알아보기

  • 정적 분석으로 웹 취약점을 미리 잡고 싶은 개발 환경에서 특히 유용해요. 다만 과다 보고 가능성이 있으니 결과를 그대로 믿기보다 코드 리뷰의 보조 도구로 쓰는 게 좋아요.