Taint is a PHP extension, used for detecting XSS codes
A PHP extension to detect XSS codes(tainted strings). It can also be used to spot SQL injection vulnerabilities, shell injection, etc.
The idea comes from https://wiki.php.net/rfc/taint, and I implemented it as a PHP extension, so no core patch is needed.
Please do not enable this extension in production environments, since it will slow down your app.
EXPERIMENTAL. Taint is a research-grade detection tool, not a security product. Detection coverage, warning behavior and INI settings may change between releases without any backward-compatibility guarantees.
master branch)Strings received from user input are marked "tainted" at request startup, and the mark is tracked through string operations. When a tainted string reaches a dangerous sink (output, SQL query, shell command, file path, ...), taint raises a warning.
Taint sources are: $_GET, $_POST and $_COOKIE.
zend_string), not on the variable. It carries no
information about which context (HTML, SQL, shell, ...) the string will end
up in, and taint never tries to analyze whether a value is "actually safe"
for that context.htmlspecialchars() — returns
a fresh, unmarked string. Checks stay shallow on purpose: only top-level
string arguments of sink calls are inspected.Good fits:
Not a good fit:
Taint works by installing user opcode handlers and swapping internal function handlers. That makes it incompatible with the OPcache JIT — but not with OPcache itself:
OPcache (the opcode cache) works fine together with taint.
OPcache JIT cannot run at the same time: JIT-compiled code bypasses user
opcode handlers, so the PHP engine refuses to start the JIT whenever an
extension (like taint) has registered handlers. If opcache.jit is
configured, PHP prints this warning at process startup and simply runs
without the JIT:
Warning: JIT is incompatible with third party extensions that setup user opcode handlers. JIT disabled.Taint itself keeps working normally — you just get no JIT speedups while it is loaded. This is enforced by the engine; there is nothing to configure.
Xdebug hooks the executor as well; do not enable taint and xdebug together (the test suite runs with opcache and xdebug disabled).
Taint is a detection tool for development use and is not designed for production deployment anyway.
Taint is a PECL extension, simply install it by:
$ pecl install taint$ /path/to/phpize
$ ./configure
$ makeWhen taint is enabled, if you pass a tainted string(which comes from $_GET, $_POST or $_COOKIE) to some dangerous functions, taint will warn you about that.
…`php taint(string &$string, string &...$strings): bool
Manually mark variables as tainted (by reference). Always returns `true`.
Only non-empty strings are marked; other types and empty strings are silently
ignored. When `taint.enable` is off, this is a no-op (still returns `true`).
The mark lives on the string itself, so assignments just share it.
````php
untaint(string &$string, string &...$strings): boolClear the mark. Since the bit lives on the string itself, every copy/reference
sharing the same string becomes clean at once. Always returns true.
is_tainted(string $string): boolCheck whether a value carries the taint mark. Only strings can be tainted,
other types return false. Always returns false when taint.enable is off.
<?php
$a = $_GET['a'];
taint($a); /* manually mark as tainted (by reference) */
var_dump(is_tainted($a)); /* true */
untaint($a); /* clear the mark */| Name | Default | Changeable | Description |
|---|---|---|---|
taint.enable |
0 |
PHP_INI_SYSTEM |
master switch |
taint.error_level |
512 (E_USER_WARNING) |
PHP_INI_ALL |
error level used for warnings |
If you need to hide the errors for a particular script, you can:
ini_set('taint.error_level', 0);Taint is distributed under the PHP-3.01 license.
No open issues yet, or sync has not completed.