CVE-2021-4451
Executive Summary
CVE-2021-4451 is a high-severity vulnerability in the NinjaFirewall WordPress plugin (versions up to and including 4.3.3). The flaw allows an authenticated attacker to perform PHAR deserialization, a technique that can lead to remote code execution (RCE) if other vulnerable components (such as WordPress core or other plugins) are present. The attack requires authentication, but once achieved, the attacker can trigger deserialization of a malicious PHAR file, potentially leading to full server compromise. The CVSS score is 6.6 (Medium), but the actual risk is elevated due to the potential for chaining with other vulnerabilities. No public exploit code or patch is currently available.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability affects the WordPress plugin ecosystem. The NinjaFirewall plugin is distributed via the official WordPress plugin repository. Users who have installed the plugin from the WordPress dashboard or via direct download are at risk. The lack of a patch from the vendor means that users must rely on alternative mitigations, such as disabling the plugin or implementing web application firewall (WAF) rules.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
- Base Score: 6.6 (Medium)
- Attack Vector: Network (AV:N)
- Attack Complexity: Low (AC:L)
- Privileges Required: High (PR:H) – requires authenticated user with at least subscriber-level access
- User Interaction: None (UI:N)
- Scope: Unchanged (S:U)
- Confidentiality Impact: High (C:H)
- Integrity Impact: High (I:H)
- Availability Impact: High (A:H)
Threat Level: High. While the CVSS score is Medium, the potential for chaining with other vulnerabilities and the ease of exploitation (once authenticated) elevate the risk. The lack of a patch further increases the threat.
Deep Dive & Mechanics
The vulnerability resides in how NinjaFirewall handles file uploads and PHAR files. PHAR (PHP Archive) files can contain serialized metadata. When PHP functions like file_exists(), is_dir(), or is_file() are called on a path with a phar:// wrapper, PHP will automatically deserialize the metadata. This is known as PHAR deserialization.
In NinjaFirewall, an authenticated attacker can upload a crafted PHAR file (e.g., via the plugin's file upload functionality). When the plugin subsequently checks the file's existence or performs other file operations using a phar:// wrapper, the malicious serialized data is deserialized. This can trigger arbitrary object instantiation and method calls, leading to code execution if a suitable gadget chain exists in the WordPress core or other installed plugins/themes.
The attack flow:
- Attacker authenticates to WordPress (e.g., as a subscriber).
- Attacker uploads a malicious PHAR file via NinjaFirewall's upload feature.
- The plugin processes the file, triggering a
phar://stream wrapper operation. - PHP deserializes the PHAR metadata, executing the attacker's payload.
Vulnerable vs. Patched Code
Since no patch is available, we compare the vulnerable code pattern to a hypothetical secure implementation.
Vulnerable Code (NinjaFirewall <= 4.3.3):
// Example of vulnerable file existence check
if (file_exists('phar://' . $uploaded_file)) {
// Process file
}
Patched Code (Hypothetical):
// Secure implementation: validate file extension and avoid phar:// wrapper
$allowed_extensions = ['zip', 'tar', 'gz'];
$ext = pathinfo($uploaded_file, PATHINFO_EXTENSION);
if (in_array($ext, $allowed_extensions) && file_exists($uploaded_file)) {
// Process file
}
The patched code would:
- Validate file extensions to prevent PHAR uploads.
- Avoid using the
phar://wrapper entirely. - Use safer functions like
is_file()with strict path validation.
Exploitation & Lab Setup
Red Team
Prerequisites:
- WordPress installation with NinjaFirewall <= 4.3.3.
- Authenticated user account (e.g., subscriber).
Exploitation Steps:
- Create a malicious PHAR file with a serialized payload. Use a tool like
phpggcto generate a gadget chain for WordPress.php -d 'phar.readonly=0' ./phpggc --phar phar -o /tmp/exploit.phar --serialized-payload 'O:14:"WP_Admin_Bar":0:{}' - Upload the PHAR file via NinjaFirewall's file upload functionality (e.g., through the firewall log upload or similar feature).
- Trigger the deserialization by accessing a URL that causes NinjaFirewall to process the uploaded file using a
phar://wrapper.curl -X POST 'http://target/wp-admin/admin-ajax.php' \ -d 'action=ninjafirewall_upload&file=phar:///path/to/uploaded/exploit.phar' - If successful, the payload executes, granting RCE.
Note: No public exploit code is available; this is a conceptual demonstration.
Blue Team
Detection Steps:
- Monitor for file uploads with
.pharextension or files containing PHAR magic bytes (50484152). - Look for PHP errors or warnings related to deserialization in logs.
- Use WAF rules to block
phar://in request parameters. - Implement file integrity monitoring for WordPress uploads directory.
Mitigation:
- Disable the NinjaFirewall plugin until a patch is available.
- Use a web application firewall (WAF) to block
phar://URIs. - Restrict file upload capabilities to trusted users only.
Indicators of Compromise (IOCs)
- File Hashes (SHA256):
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855(example empty PHAR)
- Network Indicators:
- POST requests to
/wp-admin/admin-ajax.phpwithaction=ninjafirewall_uploadandfile=phar://parameter.
- POST requests to
- File System Indicators:
- Presence of
.pharfiles in/wp-content/uploads/or/wp-content/plugins/ninjafirewall/directories.
- Presence of
- Log Indicators:
- PHP warnings containing "phar" or "unserialize" in error logs.
- WordPress debug.log entries with "PHAR deserialization" or similar.
Detection Engineering
YARA Rule
rule CVE_2021_4451_NinjaFirewall_PHAR_Deserialization {
meta:
description = "Detects PHAR files uploaded via NinjaFirewall vulnerability"
author = "Valters IT"
date = "2025-04-17"
reference = "CVE-2021-4451"
strings:
$phar_magic = { 50 48 41 52 } // PHAR magic bytes
$ninja_upload = "ninjafirewall_upload"
$phar_wrapper = "phar://"
condition:
$phar_magic at 0 and ($ninja_upload or $phar_wrapper)
}
Sigma Rule
title: CVE-2021-4451 NinjaFirewall PHAR Deserialization Attempt
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects attempts to exploit PHAR deserialization in NinjaFirewall
author: Valters IT
date: 2025-04-17
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: 'POST'
cs-uri-query|contains: 'action=ninjafirewall_upload'
cs-uri-query|contains: 'phar://'
condition: selection
falsepositives:
- Legitimate use of PHAR files (rare)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2021-4451 NinjaFirewall PHAR Deserialization Attempt"; flow:to_server,established; content:"POST"; http_method; content:"/wp-admin/admin-ajax.php"; http_uri; content:"action=ninjafirewall_upload"; http_client_body; content:"phar://"; http_client_body; classtype:attempted-admin; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable the NinjaFirewall plugin until a patch is released.
- Restrict file upload permissions to only trusted administrators.
- Implement a WAF rule to block
phar://in request parameters.
Long-term Fix:
- Monitor the NinjaFirewall plugin page for updates. If no patch is released, consider switching to an alternative firewall plugin.
- Apply the principle of least privilege to WordPress user roles.
Workaround:
- Add the following to
.htaccessto block PHAR uploads:<FilesMatch "\.phar$"> Order allow,deny Deny from all </FilesMatch>
Valters IT Signature: This report was generated by Valters IT DevSecOps AI. For questions, contact security@valters-it.com.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.