voku/anti-xss
PHP AntiXSS library to sanitize untrusted HTML and prevent XSS attacks. Cleans input by removing dangerous tags/attributes, filters CSS/JS vectors, and supports UTF-8 and common encodings. Useful for safely handling user-generated content in apps.
"Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications. XSS enables attackers to inject client-side script into Web pages viewed by other users. A cross-site scripting vulnerability may be used by attackers to bypass access controls such as the same origin policy. Cross-site scripting carried out on websites accounted for roughly 84% of all security vulnerabilities documented by Symantec as of 2007." - http://en.wikipedia.org/wiki/Cross-site_scripting
http://anti-xss-demo.suckup.de/
Use filter_input() - don't use GLOBAL-Array (e.g. $_SESSION, $_GET, $_POST, $_SERVER) directly
Use html-sanitizer or HTML Purifier if you need a more configurable solution
Add "Content Security Policy's" -> Introduction to Content Security Policy
DO NOT WRITE YOUR OWN REGEX TO PARSE HTML!
READ THIS TEXT -> XSS (Cross Site Scripting) Prevention Cheat Sheet
TEST THIS TOOL -> Zed Attack Proxy (ZAP)
This package depends on voku/portable-utf8, which sets default_charset to UTF-8 via ini_set() during autoloading.
If you need to prevent this behavior, define the following constant before loading the Composer autoloader:
define('PORTABLE_UTF8__DISABLE_AUTO_ENCODING', true);
require_once __DIR__ . '/vendor/autoload.php';
composer require voku/anti-xss
use voku\helper\AntiXSS;
require_once __DIR__ . '/vendor/autoload.php'; // example path
$antiXss = new AntiXSS();
Example 1: (HTML Character)
$harm_string = "Hello, i try to <script>alert('Hack');</script> your site";
$harmless_string = $antiXss->xss_clean($harm_string);
// Hello, i try to alert('Hack'); your site
Example 2: (Hexadecimal HTML Character)
$harm_string = "<IMG SRC=javascript:alert('XSS')>";
$harmless_string = $antiXss->xss_clean($harm_string);
// <IMG >
Example 3: (Unicode Hex Character)
$harm_string = "<a href=' javascript:alert(1)'>CLICK</a>";
$harmless_string = $antiXss->xss_clean($harm_string);
// <a >CLICK</a>
Example 4: (Unicode Character)
$harm_string = "<a href=\"\u0001java\u0003script:alert(1)\">CLICK<a>";
$harmless_string = $antiXss->xss_clean($harm_string);
// <a >CLICK</a>
Example 5.1: (non Inline CSS)
$harm_string = '<li style="list-style-image: url(javascript:alert(0))">';
$harmless_string = $antiXss->xss_clean($harm_string);
// <li >
Example 5.2: (with Inline CSS)
$harm_string = '<li style="list-style-image: url(javascript:alert(0))">';
$antiXss->removeEvilAttributes(array('style')); // allow style-attributes
$harmless_string = $antiXss->xss_clean($harm_string);
// <li style="list-style-image: url(alert(0))">
Example 6: (check if an string contains a XSS attack)
$harm_string = "\x3cscript src=http://www.example.com/malicious-code.js\x3e\x3c/script\x3e";
$harmless_string = $antiXss->xss_clean($harm_string);
//
$antiXss->isXssFound();
// true
Example 7: (allow e.g. iframes)
$harm_string = "<iframe width="560" onclick="alert('xss')" height="315" src="https://www.youtube.com/embed/foobar?rel=0&controls=0&showinfo=0" frameborder="0" allowfullscreen></iframe>";
$antiXss->removeEvilHtmlTags(array('iframe'));
$harmless_string = $antiXss->xss_clean($harm_string);
// <iframe width="560" height="315" src="https://www.youtube.com/embed/foobar?rel=0&controls=0&showinfo=0" frameborder="0" allowfullscreen></iframe>
composer install
XDEBUG_MODE=coverage ./vendor/bin/phpunit -c phpunit.xml
CI runs Infection with PHPStan integration on the PHP 8.3 pull-request job. This uses infection.json5.dist, requires 100% MSI on the mutated diff, and fails on any timed-out mutant so sanitizer loops cannot silently regress.
To run the same toolchain locally on PHP 8.3+:
composer config --no-plugins allow-plugins.infection/extension-installer true
composer require --dev phpstan/phpstan:^2.1 infection/infection:^0.32.7 --no-update
composer update
XDEBUG_MODE=coverage ./vendor/bin/infection --configuration=infection.json5.dist
Use this prompt when you want an LLM to expand regression coverage around AntiXSS dictionaries without manually copying them into tests:
You are working in the voku/anti-xss repository.
1. Run the current PHPUnit suite first with:
XDEBUG_MODE=coverage ./vendor/bin/phpunit -c phpunit.xml
2. Inspect /src/voku/helper/AntiXSS.php for dictionary-style private arrays such as:
- _never_allowed_on_events_afterwards
- _evil_attributes_regex
- _naughty_javascript_patterns
- _naughty_javascript_patterns_strict
- _never_allowed_str_afterwards
3. For each dictionary that has a safe generic assertion shape, add or extend provider-based tests that iterate every current entry automatically.
4. Prefer reflection-backed test providers over copying the source dictionaries into test files, so newly added entries are covered automatically.
5. For each dictionary, test both the intended blocking behavior and at least one important boundary rule when relevant (for example strict vs. whitespace-separated JavaScript callbacks, or executable vs. non-executable event attribute forms).
6. Make the smallest possible production change only if the expanded dictionary coverage exposes a real regression.
7. Re-run PHPUnit after each small step and continue iterating across the targeted dictionaries until you find and fix at least one real regression for the task, or confirm that the remaining dictionaries are already covered.
↑ Add some strings to the "_do_not_close_html_tags"-array.
Parameters:
string[] $stringsReturn:
$this↑ Add some strings to the "_evil_attributes"-array.
Parameters:
string[] $stringsReturn:
$this↑ Add some strings to the "_evil_html_tags"-array.
Parameters:
string[] $stringsReturn:
$this↑ Add some strings to the "_never_allowed_call_strings"-array.
Parameters:
string[] $stringsReturn:
$this↑ Add some strings to the "_never_allowed_js_callback_regex"-array.
Parameters:
string[] $stringsReturn:
$this↑ Add some strings to the "_never_allowed_on_events_afterwards"-array.
Parameters:
string[] $stringsReturn:
$this↑ Add some strings to the "_never_allowed_regex"-array.
Parameters:
string[] $stringsReturn:
$this↑ Add some strings to the "_never_allowed_str_afterwards"-array.
Parameters:
string[] $stringsReturn:
$this↑ Add some strings to the "_naughty_javascript_patterns"-array.
Parameters:
string[] $stringsReturn:
$this↑ Check if the "AntiXSS->xss_clean()"-method found an XSS attack in the last run.
Parameters: nothing
Return:
bool|null <p>Will return null if the "xss_clean()" wasn't running at all.</p>↑ Remove some strings from the "_do_not_close_html_tags"-array.
Parameters:
string[] $stringsReturn:
$this↑ Remove some strings from the "_evil_attributes"-array.
Parameters:
string[] $stringsReturn:
$this↑ Remove some strings from the "_evil_html_tags"-array.
Parameters:
string[] $stringsReturn:
$this↑ Remove some strings from the "_never_allowed_call_strings"-array.
Parameters:
string[] $stringsReturn:
$this↑ Remove some strings from the "_never_allowed_js_callback_regex"-array.
Parameters:
string[] $stringsReturn:
$this↑ Remove some strings from the "_never_allowed_on_events_afterwards"-array.
Parameters:
string[] $stringsReturn:
$this↑ Remove some strings from the "_never_allowed_regex"-array.
Parameters:
string[] $stringsReturn:
$this↑ Remove some strings from the "_never_allowed_str_afterwards"-array.
Parameters:
string[] $stringsReturn:
$this↑ Set the replacement-string for not allowed strings.
Parameters:
string $stringReturn:
$this↑ Set the option to preserve content inside "pre" and "code" tags.
Parameters:
bool $boolReturn:
$this↑ Set the option to stripe 4-Byte chars.
Parameters:
bool $boolReturn:
$this↑ XSS Clean
Parameters:
TXssCleanInput $str <p>input data e.g. string or array of strings</p>Return:
string|string[]For support and donations please visit Github | Issues | PayPal | Patreon.
For status updates and release announcements please visit Releases | Twitter | Patreon.
For professional support please contact me.
How can I help you explore Laravel packages today?