HexBrain

Browse / CVEs / CVE-2026-90817

CVE-2026-90817· vanderbilt / redcap· CWE-73, CWE-94

REDCap >= 13.3.0 - Unauthenticated Remote Code Execution via Survey Passthru

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

REDCap versions 13.3.0 through 16.0.48 LTS, 17.3.9 LTS, and 17.4.3 Standard contain an unauthenticated remote code execution vulnerability. The application is vulnerable to an authentication bypass via a double-URL-decoded __passthru parameter (%2569ndex.php -> index.php) on public survey endpoints, which routes requests to internal authenticated controllers. An unauthenticated attacker can abuse this routing flaw combined with PHP filter chains to inject and execute arbitrary code through the Laravel Blade template cache.

Impact

Unauthenticated remote attackers can execute arbitrary code on the underlying server with the privileges of the web application, leading to complete compromise of sensitive clinical and patient data.

Fix

Upgrade REDCap to versions 16.0.49 LTS, 17.3.10 LTS, 17.4.4 Standard or later.

How to confirm it

Send: GET {{BaseURL}}
Positive when: status_code == 200 and contains(body, "surveys/?s=") || contains(body, "surveys/index.php?s=")
Send: GET {{RootURL}}{{survey_path}}?s={{survey_hash}}&__passthru=%2569ndex.php&route=ParcelController%3Ashow
Positive when: status_code == 200 and contains(body, "no parcel ID was provided")

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

The full check
id: CVE-2026-90817

info:
  name: REDCap >= 13.3.0 - Unauthenticated Remote Code Execution via Survey Passthru
  author: sudo-a-man
  severity: critical
  description: |
    REDCap versions 13.3.0 through 16.0.48 LTS, 17.3.9 LTS, and 17.4.3 Standard contain an unauthenticated remote code execution vulnerability. The application is vulnerable to an authentication bypass via a double-URL-decoded __passthru parameter (%2569ndex.php -> index.php) on public survey endpoints, which routes requests to internal authenticated controllers. An unauthenticated attacker can abuse this routing flaw combined with PHP filter chains to inject and execute arbitrary code through the Laravel Blade template cache.
  impact: |
    Unauthenticated remote attackers can execute arbitrary code on the underlying server with the privileges of the web application, leading to complete compromise of sensitive clinical and patient data.
  remediation: |
    Upgrade REDCap to versions 16.0.49 LTS, 17.3.10 LTS, 17.4.4 Standard or later.
  reference:
    - https://www.securifera.com/blog/2026/09/27/survey-says-remote-code-execution-cve-2026-90817/
    - https://github.com/securifera/CVE-2026-90817
    - https://github.com/Farih123/CVE-2026-90817
    - https://github.com/PaloAltoNetworks/Unit42-timely-threat-intel/blob/main/2026-10-07-XMRig-campaign-through-CVE-2026-90817.txt
    - https://www.cve.org/CVERecord?id=CVE-2026-90817
    - https://nvd.nist.gov/vuln/detail/CVE-2026-90817
  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-90817
    epss-score: 0.03749
    epss-percentile: 0.89964
    cwe-id: CWE-73,CWE-94
  metadata:
    verified: true
    max-request: 2
    vendor: vanderbilt
    product: redcap
    shodan-query: http.title:"REDCap"
    fofa-query: title="REDCap" || body="redcap_version" || body="/surveys/?s="
  tags: cve,cve2026,redcap,rce,php-filter-chain,vkev,unauth,intrusive,vuln

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

http:
  - method: GET
    path:
      - "{{BaseURL}}"

    host-redirects: true
    max-redirects: 2

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'contains(body, "surveys/?s=") || contains(body, "surveys/index.php?s=")'
        condition: and
        internal: true

    extractors:
      - type: regex
        name: survey_path
        group: 1
        internal: true
        regex:
          - '(?s)\A.*?(?:https?://[^/"''\s<>]+)?((?:/[^/"''\s<>?#]+)*/surveys/)(?:index\.php)?\?s=[a-zA-Z0-9]+'

      - type: regex
        name: survey_hash
        group: 1
        internal: true
        regex:
          - '(?s)\A.*?/surveys/(?:index\.php)?\?s=([a-zA-Z0-9]+)'

  - method: GET
    path:
      - "{{RootURL}}{{survey_path}}?s={{survey_hash}}&__passthru=%2569ndex.php&route=ParcelController%3Ashow"

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'contains(body, "no parcel ID was provided")'
        condition: and

References

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