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 taintedtaint— Mark strings as tainteduntaint— Remove the taint mark from strings
더 알아보기
- 정적 분석으로 웹 취약점을 미리 잡고 싶은 개발 환경에서 특히 유용해요. 다만 과다 보고 가능성이 있으니 결과를 그대로 믿기보다 코드 리뷰의 보조 도구로 쓰는 게 좋아요.