CVE-2020-13756 Overview
CVE-2020-13756 is a critical code injection vulnerability in Sabberworm PHP CSS Parser before version 8.3.1. The vulnerability exists because the library calls eval() on uncontrolled data, potentially leading to remote code execution (RCE) when an attacker can influence input to the allSelectors() or getSelectorsBySpecificity() functions.
Critical Impact
Attackers can achieve remote code execution by injecting malicious PHP code through CSS selector specificity parameters, enabling complete server compromise.
Affected Products
- Sabberworm PHP CSS Parser versions prior to 8.3.1
- Applications using the vulnerable allSelectors() function with user-controlled input
- Applications using the vulnerable getSelectorsBySpecificity() function with user-controlled input
Discovery Timeline
- 2020-06-03 - CVE-2020-13756 published to NVD
- 2025-11-03 - Last updated in NVD database
Technical Details for CVE-2020-13756
Vulnerability Analysis
This vulnerability represents a classic Code Injection flaw (CWE-94) resulting from the unsafe use of PHP's eval() function. The vulnerable code constructs a comparison string dynamically using user-supplied specificity search parameters and then passes this string directly to eval(). When an attacker controls the input to getSelectorsBySpecificity() or allSelectors(), they can inject arbitrary PHP code that will be executed on the server.
The dangerous pattern involves constructing a string like $bRes = {$specificity} {$userInput}; and executing it with eval(). An attacker can escape the intended comparison logic and inject additional PHP statements, such as system commands or file operations.
Root Cause
The root cause is the use of eval() on dynamically constructed strings that include user-controllable data. The original implementation in CSSBlockList.php built a comparison expression string by concatenating the selector's specificity value with the user-provided $sSpecificitySearch parameter, then executed it via eval(). This approach inherently trusts user input to be a safe comparison operator and value, which is a fundamental security violation.
Attack Vector
The attack vector is network-based, requiring no authentication or user interaction. An attacker who can influence the specificity search parameter passed to getSelectorsBySpecificity() or allSelectors() can inject malicious PHP code. For example, if an application allows users to specify CSS selector filtering criteria that gets passed to these functions, the attacker can craft a payload that breaks out of the intended comparison and executes arbitrary code.
The vulnerable code pattern before the patch:
// VULNERABLE CODE - Before patch (lib/Sabberworm/CSS/CSSList/CSSBlockList.php)
// Source: https://github.com/sabberworm/PHP-CSS-Parser/commit/2ebf59e8bfbf6cfc1653a5f0ed743b95062c62a4
if ($sSpecificitySearch === null) {
$aResult[] = $oSelector;
} else {
- $sComparison = "\$bRes = {$oSelector->getSpecificity()} $sSpecificitySearch;";
- eval($sComparison);
- if ($bRes) {
The security patch replaces the dangerous eval() call with a safe switch-based comparison:
// PATCHED CODE - After fix (lib/Sabberworm/CSS/CSSList/CSSBlockList.php)
// Source: https://github.com/sabberworm/PHP-CSS-Parser/commit/2ebf59e8bfbf6cfc1653a5f0ed743b95062c62a4
+ $sComparator = '===';
+ $aSpecificitySearch = explode(' ', $sSpecificitySearch);
+ $iTargetSpecificity = $aSpecificitySearch[0];
+ if(count($aSpecificitySearch) > 1) {
+ $sComparator = $aSpecificitySearch[0];
+ $iTargetSpecificity = $aSpecificitySearch[1];
+ }
+ $iTargetSpecificity = (int)$iTargetSpecificity;
+ $iSelectorSpecificity = $oSelector->getSpecificity();
+ $bMatches = false;
+ switch($sComparator) {
+ case '<=':
+ $bMatches = $iSelectorSpecificity <= $iTargetSpecificity;
+ break;
+ case '<':
+ $bMatches = $iSelectorSpecificity < $iTargetSpecificity;
+ break;
+ case '>=':
+ $bMatches = $iSelectorSpecificity >= $iTargetSpecificity;
+ break;
+ case '>':
+ $bMatches = $iSelectorSpecificity > $iTargetSpecificity;
+ break;
+ default:
Detection Methods for CVE-2020-13756
Indicators of Compromise
- Unusual PHP process spawning or command execution from web server processes
- Web server logs showing requests with unusual CSS-related parameters containing PHP code fragments
- File system modifications or new file creation by web application processes
- Outbound network connections initiated by web server processes to unexpected destinations
Detection Strategies
- Monitor application logs for requests containing PHP code patterns in CSS parser-related endpoints
- Implement web application firewall (WAF) rules to detect code injection attempts in specificity parameters
- Use static analysis tools to identify applications using vulnerable versions of Sabberworm PHP CSS Parser
- Deploy runtime application self-protection (RASP) to detect eval() execution with malicious payloads
Monitoring Recommendations
- Enable verbose logging for PHP applications using CSS parsing functionality
- Monitor for unexpected child processes spawned by web server workers
- Implement file integrity monitoring on web application directories
- Set up alerts for network anomalies originating from web application servers
How to Mitigate CVE-2020-13756
Immediate Actions Required
- Upgrade Sabberworm PHP CSS Parser to version 8.3.1 or later immediately
- Audit all code paths that pass user input to getSelectorsBySpecificity() or allSelectors() functions
- Implement input validation on any parameters that could reach CSS parsing functions
- Review application dependencies using composer audit or similar tools to identify vulnerable versions
Patch Information
The vulnerability is fixed in Sabberworm PHP CSS Parser version 8.3.1. The patch removes the dangerous eval() call and replaces it with a safe whitelist-based comparison using a switch statement. This ensures that only valid comparison operators (<=, <, >=, >, ===) are processed, and the specificity value is properly cast to an integer before comparison.
Update via Composer:
composer require sabberworm/php-css-parser:^8.3.1
For additional details, see the GitHub Release 8.3.1 and the security patch commit.
Workarounds
- If upgrading is not immediately possible, avoid passing user-controlled input to getSelectorsBySpecificity() or allSelectors() functions
- Implement strict input validation to only allow numeric values and valid comparison operators in specificity search parameters
- Consider temporarily removing or disabling functionality that relies on these vulnerable functions until patching is complete
- Deploy a web application firewall (WAF) with rules to block requests containing PHP code patterns in CSS-related parameters
# Check installed version of php-css-parser
composer show sabberworm/php-css-parser | grep versions
# Update to patched version
composer require "sabberworm/php-css-parser:>=8.3.1"
# Verify the update
composer show sabberworm/php-css-parser
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

