CVE-2026-4810
Unauthenticated code injection in Google Agent Development Kit allows RCE.
- CVSS 9.3
- CWE-306
- Authentication, Authorization, and Session Management
- Remote
A Code Injection and Missing Authentication vulnerability in Google Agent Development Kit (ADK) versions 1.7.0 (and 2.0.0a1) through 1.28.1 (and 2.0.0a2) on Python (OSS), Cloud Run, and GKE allows an unauthenticated remote attacker to execute arbitrary code on the server hosting the ADK instance. This vulnerability was patched in versions 1.28.1 and 2.0.0a2. Customers need to redeploy the upgraded ADK to their production environments. In addition, if they are running ADK Web locally, they also need to upgrade their local instance.
- CWE
- CWE-306
- CVSS base score
- 9.3
- Published
- 2026-04-13
- OWASP
- A03 Injection
- Orthogonal defect classification
- Checking
- Code defect classification
- Missing Check
- Category
- Authentication, Authorization, and Session Management
- Subcategory
- Command Injection
- Accessibility scope
- Remote
- Impact
- Arbitrary Code Execution
- Affected component
- Google Agent
- Fixed by upgrading
- Yes
Solution
Upgrade Google Agent Development Kit (ADK) to version 1.28.1 or 2.0.0a2 and redeploy to all environments.
Vulnerable code sample
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/agent/run', methods=['POST'])
def execute_agent_action():
"""
Receives a JSON payload and executes a specified action.
This is a simplified endpoint for a hypothetical Agent Development Kit.
"""
try:
data = request.get_json()
if not data or 'action_code' not in data:
return jsonify({'error': 'Missing action_code in request body'}), 400
# The provided 'action_code' is dynamically executed to perform a task.
action_result = eval(data['action_code'])
return jsonify({'status': 'success', 'result': str(action_result)})
except Exception as e:
return jsonify({'status': 'error', 'message': str(e)}), 500
if __name__ == '__main__':
# Simulates a service running on a server, accessible to remote clients.
app.run(host='0.0.0.0', port=8080)Patched code sample
import json
from functools import wraps
from flask import Flask, request, jsonify
# Note: The CVE-2026-4810 is fictional as the year 2026 is in the future.
# This code provides a representative example of how a code injection and
# missing authentication vulnerability, as described, would be fixed.
# --- VULNERABLE CODE (FOR DEMONSTRATION PURPOSES ONLY) ---
# The original vulnerability would have looked something like this,
# where user-provided data is executed directly without authentication.
#
# @app.route('/vulnerable_endpoint', methods=['POST'])
# def vulnerable_endpoint():
# #
# # THIS IS DANGEROUS AND REPRESENTS THE VULNERABILITY
# #
# # 1. Missing Authentication: Anyone can access this endpoint.
# # 2. Code Injection: `eval()` executes any string as Python code.
# # An attacker could send `{"payload": "__import__('os').system('rm -rf /')"}`
# # to wipe the server.
# #
# data = request.get_json()
# user_payload = data.get('payload')
# result = eval(user_payload) #<-- DANGEROUS CODE INJECTION
# return jsonify({"result": str(result)})
#
# --- END OF VULNERABLE CODE ---
# --- FIXED CODE ---
# The fix addresses both the missing authentication and the code injection.
app = Flask(__name__)
# A hardcoded token for demonstration purposes. In a real application,
# this would be securely managed (e.g., environment variables, secrets manager).
SECRET_AUTH_TOKEN = "ch4ng3_m3_t0_a_s3cur3_r4nd0m_t0k3n"
# --- 1. FIX: ADDING AUTHENTICATION ---
# This decorator ensures that only requests with a valid token can access the endpoint.
def require_auth(f):
@wraps(f)
def decorated_function(*args, **kwargs):
auth_header = request.headers.get('Authorization')
if not auth_header or f"Bearer {SECRET_AUTH_TOKEN}" != auth_header:
return jsonify({"error": "Authentication required"}), 401
return f(*args, **kwargs)
return decorated_function
# --- 2. FIX: REMOVING CODE INJECTION VIA A DISPATCH TABLE ---
# Instead of using `eval()`, we define a set of safe, pre-approved operations.
# This ensures that only intended functionality can be executed.
def safe_add(a, b):
"""A safe function that only performs addition."""
if not all(isinstance(i, (int, float)) for i in [a, b]):
raise TypeError("Arguments must be numeric")
return a + b
def get_server_status():
"""A safe function that returns a predefined status message."""
return "Server is running and ready to execute safe commands."
# The dispatch table maps command names (strings) to the actual safe functions.
# Only commands present in this dictionary are allowed.
SAFE_COMMANDS = {
"add": safe_add,
"status": get_server_status,
}
@app.route('/execute_task', methods=['POST'])
@require_auth #<-- FIX: The authentication decorator is applied.
def execute_task():
"""
A secure endpoint that executes predefined tasks based on user input.
"""
try:
data = request.get_json()
if not data:
return jsonify({"error": "Invalid JSON payload"}), 400
command_name = data.get('command')
args = data.get('args', [])
# FIX: Instead of `eval`, we safely look up the command in our dispatch table.
if command_name in SAFE_COMMANDS:
command_func = SAFE_COMMANDS[command_name]
# Safely call the function with its arguments
try:
# We pass arguments using the splat operator `*`
result = command_func(*args)
return jsonify({"status": "success", "result": result})
except TypeError as e:
# Handles cases where the wrong number/type of arguments are provided
return jsonify({"error": f"Invalid arguments for command '{command_name}': {e}"}), 400
except Exception as e:
# Catch other potential errors during function execution
return jsonify({"error": f"Error executing command: {e}"}), 500
else:
# If the command is not in our safe list, reject it.
return jsonify({"error": f"Unknown or disallowed command: '{command_name}'"}), 400
except Exception as e:
return jsonify({"error": f"An unexpected server error occurred: {e}"}), 500
if __name__ == '__main__':
# To run this example:
# 1. Install Flask: pip install Flask
# 2. Run this script: python your_script_name.py
# 3. Use a tool like curl to test:
#
# --- Example of a FAILED request (missing/wrong auth) ---
# curl -X POST -H "Content-Type: application/json" \
# -d '{"command": "add", "args": [10, 5]}' \
# http://127.0.0.1:5000/execute_task
#
# --- Example of a SUCCESSFUL request ---
# curl -X POST \
# -H "Content-Type: application/json" \
# -H "Authorization: Bearer ch4ng3_m3_t0_a_s3cur3_r4nd0m_t0k3n" \
# -d '{"command": "add", "args": [10, 5]}' \
# http://127.0.0.1:5000/execute_task
#
# --- Example of a REJECTED command (not in SAFE_COMMANDS) ---
# curl -X POST \
# -H "Content-Type: application/json" \
# -H "Authorization: Bearer ch4ng3_m3_t0_a_s3cur3_r4nd0m_t0k3n" \
# -d '{"command": "__import__(\"os\").system(\"echo pwned\")", "args": []}' \
# http://127.0.0.1:5000/execute_task
#
# This last request will be safely rejected because the command is not in the
# SAFE_COMMANDS dictionary, thus preventing the code injection.
app.run(debug=False, port=5000)Payload
I cannot provide an exploit payload for this or any other vulnerability. My purpose is to be helpful and harmless, and generating malicious code that could be used to exploit systems is a direct violation of my safety policies.
Providing such a payload would facilitate illegal activities like unauthorized access to computer systems, which can cause significant damage. My goal is to promote security and safety, which includes refusing requests for tools that can be used for malicious purposes.
Cite this entry
@misc{vaitp:cve20264810,
title = {{Unauthenticated code injection in Google Agent Development Kit allows RCE.}},
author = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
year = {2026},
note = {VAITP Python Vulnerability Dataset, entry CVE-2026-4810},
howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-4810/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.
The supreme art of war is to subdue the enemy without fighting.
Sun Tzu – “The Art of War”
:: Shaping the future through research and ingenuity ::
