| प्लगइन का नाम | AddFunc Head & Footer Code |
|---|---|
| कमजोरियों का प्रकार | क्रॉस-साइट स्क्रिप्टिंग (XSS) |
| CVE संख्या | CVE-2026-2305 |
| तात्कालिकता | कम |
| CVE प्रकाशन तिथि | 2026-04-10 |
| स्रोत URL | CVE-2026-2305 |
AddFunc Head & Footer Code XSS (CVE-2026-2305): What WordPress Site Owners Need to Know
सारांश: An authenticated stored cross-site scripting (XSS) issue in AddFunc Head & Footer Code (versions up to 2.3) allows a contributor-level user to save script-like payloads via custom fields that may later be rendered unsanitized. This note provides a pragmatic, practitioner-focused breakdown of the risk, detection, cleanup and mitigation steps from the perspective of a Hong Kong-based security expert.
Executive summary — what happened and why it matters
- The plugin allowed user-supplied content from post custom fields to be included in output without sufficient sanitization or escaping.
- An authenticated user with Contributor privileges (able to create or edit posts and add custom fields) could save content containing script tags or event handlers.
- If that content is later rendered on the front-end or inside admin screens without proper escaping, the stored script executes in the viewer’s browser.
- Impact depends on render context:
- Front-end execution can affect visitors (malicious redirects, form spoofing, crypto‑miner injection, content manipulation).
- Execution in admin pages can target higher-privilege users and lead to account takeover, changes to settings, plugin/theme modifications, or backdoors.
- The plugin was patched in version 2.4. Updating to 2.4+ is the correct and primary remediation.
Why a Contributor can be dangerous — real-world threat model
Site owners often assume Contributors are low risk because they cannot publish. That’s true for publishing workflows, but Contributors can typically create posts, edit drafts and add custom fields (site configuration permitting). Stored XSS in custom fields is dangerous because the payload is persistent and will execute whenever rendered without escaping.
मुख्य बिंदु:
- Persistency: malicious content is stored in the database and can be triggered later.
- Privilege amplification: if admin users view the infected content in the dashboard, an attacker can pivot using the admin’s authenticated session.
- Real attack vectors include CSRF combined with XSS to perform privileged actions (create admin accounts, change options, install code).
Typical exploitation flow (high level, non-actionable)
- Attacker registers or compromises a Contributor account.
- Attacker saves a post or draft and injects malicious content into a custom field (e.g., <script>…</script> or attribute payloads such as onerror=…).
- Content is stored in postmeta.
- When the post is rendered in a context that outputs the field unsanitized (front-end, admin preview, meta box), the browser executes the JavaScript.
- If an administrator views the affected admin screen, the script may perform privileged actions using the admin’s session (exfiltrate cookies, create admin users, modify files, install backdoors).
Some advisories list “User Interaction Required” — in practice the interaction can be as simple as opening the post editor or a crafted preview link.
Practical steps to protect your site — immediate actions (checklist)
- प्लगइन को अपडेट करें — If you use AddFunc Head & Footer Code, update to 2.4 or later immediately. This is the canonical fix.
- यदि आप तुरंत अपडेट नहीं कर सकते
- Temporarily remove or disable the plugin.
- Restrict Contributors from adding or editing custom fields until patched.
- Apply virtual patching at the WAF level if you have that capability (see WAF guidance below).
- Scan for malicious content in custom fields
Use WP-CLI or direct DB queries (with a backup) to find meta values containing <script, onerror=, javascript:, and other suspicious HTML patterns.
- उपयोगकर्ता खातों का ऑडिट करें — Verify Contributors and Editors; remove stale or suspicious accounts. Enforce strong passwords and 2FA for privileged roles.
- समझौते के संकेतों की जांच करें — unknown admin accounts, unexpected plugin/theme files, modified files, scheduled tasks, or outbound connections.
- क्रेडेंशियल्स को घुमाएं if compromise is suspected — reset admin passwords, revoke API keys, and invalidate sessions.
- सफाई से पहले बैकअप — take a full files+DB backup before making remediation changes to preserve evidence and allow rollback.
- Harden custom fields — require sanitization on save and escaping on output (see developer guidance below).
How to find malicious stored XSS entries safely
Always work from a full backup and start with read-only queries to identify suspicious entries, then review them manually.
# Find postmeta that contains <script
wp db query "SELECT meta_id, post_id, meta_key FROM wp_postmeta WHERE meta_value LIKE '%<script%';"
# Search for inline event handlers
wp db query "SELECT meta_id, post_id, meta_key FROM wp_postmeta WHERE meta_value LIKE '%onerror=%' OR meta_value LIKE '%onload=%';"
Export suspicious meta values, inspect them and decide whether to sanitize or remove.
Cleaning suspicious entries
If you identify malicious meta values:
- Remove obviously malicious entries (full <script> blocks).
- If the entry contains useful data with injected tags, sanitize the value before saving back:
<?php
// Example: sanitize a saved custom field value
$clean = wp_kses(
$raw_meta_value,
array(
'a' => array( 'href' => true, 'title' => true, 'rel' => true ),
'strong' => array(),
'em' => array(),
'p' => array(),
'br' => array()
)
);
update_post_meta( $post_id, $meta_key, $clean );
?>
If you’re not comfortable editing the DB directly, engage a trusted developer or your hosting provider’s support team.
Developer guidance: save-time sanitization and output escaping
Root causes for this class of bug are typically missing sanitization on input and missing escaping on output. Apply both:
- Sanitize on save so stored data is safe.
- Escape on output so rendering never trusts database content.
Recommended patterns:
<?php
// Save callback for meta box or REST endpoint
function myplugin_save_postmeta( $post_id ) {
if ( ! isset( $_POST['my_custom_field'] ) ) {
return;
}
// Nonce & capability checks
if ( ! wp_verify_nonce( $_POST['my_custom_field_nonce'], 'save_my_custom_field' ) ) {
return;
}
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
// Sanitize input - allow only simple text
$value = sanitize_text_field( wp_unslash( $_POST['my_custom_field'] ) );
// Or if you need limited HTML:
// $value = wp_kses( $_POST['my_custom_field'], array('a' => array('href' => true)) );
update_post_meta( $post_id, '_my_custom_field', $value );
}
add_action( 'save_post', 'myplugin_save_postmeta' );
?>
<?php
// Output examples
// In HTML body context:
echo esc_html( get_post_meta( $post->ID, '_my_custom_field', true ) );
// In attribute context:
echo esc_attr( get_post_meta( $post->ID, '_my_custom_field', true ) );
// If you deliberately allow HTML, whitelist and use:
echo wp_kses_post( get_post_meta( $post->ID, '_my_custom_field', true ) );
?>
Also consider registering meta with a sanitize callback so REST requests are cleaned automatically:
<?php
register_post_meta( 'post', '_my_custom_field', array(
'single' => true,
'show_in_rest' => true,
'sanitize_callback' => 'sanitize_text_field',
) );
?>
WAF and virtual patching — immediate network-level protection
When updating immediately is not possible, a well-configured Web Application Firewall (WAF) can provide virtual patching by blocking exploit attempts before they reach vulnerable code. Typical WAF mitigations for this stored XSS include:
- Blocking POST requests that include suspicious script payloads in known meta field names (postmeta, meta[], acf, etc.).
- Blocking or sanitizing requests containing <script> tags, event attributes (onerror=, onload=), javascript: URIs, base64-encoded script, or obfuscation patterns.
- Rate-limiting POSTs that create/update posts from low-privileged users.
Conceptual pseudo-rule example (illustrative only):
# If POST to post edit or REST posts endpoint and any parameter name looks like meta/postmeta/acf
# and parameter value contains <script or on[a-z]+= or javascript:
# then block and log as possible stored XSS payload.
If you operate a host-based or cloud WAF, create a rule that inspects request bodies for these patterns and blocks them for Contributor/Author roles as an interim measure. Test carefully to avoid false positives.
WAF rule examples — ModSecurity-style (example, tune for your environment)
Illustrative patterns to use as a starting point (test on staging):
# Example ModSecurity rule to detect <script> tags in POST body
SecRule REQUEST_METHOD "POST" "phase:2,chain,id:100001,deny,log,msg:'Stored XSS attempt - script tag in postmeta or post content',severity:2"
SecRule ARGS_NAMES|ARGS "@rx (meta|postmeta|_custom|acf|meta\[\w+\])" "chain"
SecRule ARGS "@rx <\s*script" "t:none"
# Example rule to detect event attributes like onerror= or onload=
SecRule REQUEST_METHOD "POST" "phase:2,chain,id:100002,deny,log,msg:'Stored XSS attempt - event handler attribute',severity:2"
SecRule ARGS_NAMES|ARGS "@rx (meta|postmeta|_custom|acf|meta\[\w+\])" "chain"
SecRule ARGS "@rx on[a-z]+\s*=" "t:none"
Always tune rules to your site to reduce false positives; log-only mode is useful for an initial tuning period.
Detection — logs and indicators of exploitation
- Check server access logs for POSTs to /wp-admin/post.php or /wp-json/wp/v2/posts that create or modify posts.
- Inspect application logs for suspicious POST parameters.
- Run a malware scan with a reputable scanner to find modified plugin/theme files or webshells.
- Check admin users for unexpected new accounts and review recent cron jobs and scheduled tasks.
- Look for outbound connections from the server to unknown hosts.
After an infection — remediation and hardening
- अलग करें the site if compromise is confirmed (take offline or restrict access).
- साक्ष्य को संरक्षित करें — snapshot files and DB, and retain logs.
- Identify persistence — added admin users, modified core, malicious plugins/themes, cron entries.
- साफ करें — remove malicious files and DB entries; restore from a known clean backup if unsure.
- क्रेडेंशियल बदलें — reset passwords, revoke API keys, rotate SSH keys.
- पैच — update WordPress core, plugins and themes to latest releases.
- मजबूत करें — restrict file permissions and disable file editing in wp-config.php:
define('DISALLOW_FILE_EDIT', true);Enforce 2FA for admins and apply least privilege. - निगरानी करें — enable file integrity monitoring and alerts for critical events.
Long-term controls — reduce risk from role misuse and untrusted HTML
- Minimise the number of accounts that can edit content; apply least privilege.
- Require moderation workflows for user-submitted content where possible.
- Restrict which roles can add custom fields or use plugins that render custom field content.
- Educate contributors about the dangers of embedding HTML in fields.
- Use a Content Security Policy (CSP) to reduce the impact of injected scripts where practical.
Practical WAF tuning notes (reduce false positives)
- Consider excluding trusted admin IPs from aggressive blocking only after weighing the security trade-offs.
- Match parameter names commonly used for meta fields (meta[], postmeta, acf) rather than blocking all <script> globally.
- Run rules in log-only mode first to observe legitimate traffic patterns and tune signatures before blocking.
Example incident response playbook (concise)
- Update AddFunc Head & Footer Code to 2.4+ where possible.
- If immediate update is impossible: disable the plugin and enable virtual patching rules that inspect POST bodies for script/event attributes targeting postmeta parameters.
- Query the DB for suspicious meta values and export results for review.
- Remove confirmed malicious entries and sanitize ambiguous ones.
- Reset admin passwords and enforce 2FA.
- Scan filesystem for modified or unknown PHP files.
- Restore from a clean backup if remediation is uncertain.
- पुनरावृत्ति प्रयासों के लिए लॉग की निगरानी करें और दोषी आईपी को ब्लॉक करें।.
Developer-friendly recommendations to eliminate this class of bug
- Always sanitize on save and escape on output.
- Use WordPress APIs: register_post_meta with sanitize callbacks, sanitize_text_field, wp_kses_post, esc_html, esc_attr.
- Use nonces and capability checks on admin save operations.
- Avoid storing raw HTML unless necessary; constrain allowed tags/attributes with wp_kses.
- Integrate security into CI/CD: static analysis, dependency checks, and security reviews before releases.
How to verify your site is no longer vulnerable
- Ensure AddFunc Head & Footer Code is updated to 2.4 or later.
- Confirm there are no postmeta entries containing <script> or event attributes that could execute.
- Verify custom field output is properly escaped in front-end and admin contexts.
- Check WAF logs for blocked attempts and ensure logging/alerting is enabled.
- Run a full malware scan and verify file integrity.
समापन विचार
From the viewpoint of a Hong Kong security practitioner: this vulnerability highlights how even low-privilege roles and small plugins can introduce outsized risk when data is stored and later rendered without sanitization. The pragmatic path is clear — update the plugin, scan and clean postmeta, harden save-time sanitization and output escaping, and use network-level mitigations as a temporary compensating control while you fix the root cause.
If you need assistance implementing WAF rules, virtual patching, or post-incident cleanup, contact your chosen security provider or a trusted developer who understands WordPress-specific request patterns and REST endpoints.
Stay vigilant: treat custom fields as untrusted input — sanitize, escape, and review.
— हांगकांग सुरक्षा विशेषज्ञ