Advisories
Security vulnerabilities, privacy incidents, safety concerns, and policy updates affecting LLMs and AI agents.
Security vulnerabilities, privacy incidents, safety concerns, and policy updates affecting LLMs and AI agents.
3,134 items
In Dradis Community Edition, the ProvidersController and AgentsController skip their admin_required check because it is gated on defined?(Dradis::Pro), a constant never defined in CE. Any authenticated non-admin user can therefore create an AI provider pointing to an arbitrary HTTP or HTTPS address, including internal hosts such as http://169.254.169.254, and reassign the built-in Roslin agent to use it. When an AI interaction runs, the server requests the attacker-supplied URL, and non-2xx response bodies are reflected verbatim to the attacker through ActionCable/Turbo Stream error messages, making the SSRF readable.
CVE-2026-78379 is a consent bypass in the python_repl tool of the strands-agents-tools package, used with the Strands Agents Python SDK, in versions before 0.8.5. A crafted prompt can forward non_interactive_mode as a keyword argument through the batch tool, skipping the operator approval gate. Remote actors can then execute arbitrary Python code on the agent's host.
Fix: Fixed in 0.8.5 or later. Upgrade strands-agents-tools to version 0.8.5 or newer.
AWS Security Bulletinsbrowse-mcp, an MCP server, has an arbitrary file write flaw in `browser_download`, `browser_save_state` and `browser_load_state`. Their `save_dir` and `path` arguments are not validated, so a caller controlling the MCP arguments can write attacker-supplied response bytes to any path the process can reach, such as `~/.bashrc` or a cron file, which can lead to host code execution. The `force_fetch` fallback also bypassed the `BROWSE_MCP_ALLOWED_ORIGINS` origin fence. The estimated CVSS 3.1 score is around 7.8 (High) for the local, agent-mediated case.
The qwed package (version 5.1.1) passes attacker-controlled input directly to SymPy's parse_expr() without a restricted namespace, and parse_expr() internally calls Python's eval(). Any authenticated tenant can therefore run arbitrary Python code in the API server process, reached through POST /verify/math and POST /verify/batch. Any user can obtain an account through the default-enabled /auth/signup endpoint, so the precondition is only a standard user account.
X-AnyLabeling's download_with_retry in anylabeling/services/auto_labeling/model.py builds an unverified SSL context with ssl._create_unverified_context() and passes it to urllib.request.urlopen, so model downloads from the release host skip certificate and hostname checks. An interceptor can substitute a model, and the only post-download check, safe_check_model, validates format rather than provenance. For .pth or .pt targets, torch.load without weights_only can then execute attacker-chosen code on PyTorch releases predating the weights_only default.
Vocos, through its instantiate_class function in vocos/pretrained.py, imports and calls whatever class_path a configuration file names, with arguments from its init_args, and applies no allowlist. Vocos.from_pretrained passes a config.yaml downloaded from a caller-named Hugging Face repository straight to from_hparams. Loading a model from a repository the user does not control therefore runs code chosen by that repository's owner.
CVE-2026-55640 affects the Nextcloud MCP Server before 0.117.2. The POST /webhooks/nextcloud endpoint in nextcloud_mcp_server/vector/webhook_receiver.py accepts unauthenticated requests when WEBHOOK_SECRET is unset, which is the default, because startup validation does not require it. The payload["user"]["uid"] field from webhook_parser.py is attacker-controlled and used for Qdrant operations without an authenticated-session cross-check, so a network attacker can delete or trigger re-indexing of vector embeddings for any user and destroy the semantic search index with forged deletion events.
The utcp-http package's HttpCommunicationProtocol.call_tool validates only the initial tool URL, then issues the request with aiohttp's default allow_redirects=True and no per-hop revalidation. An attacker-controlled endpoint can return a 3xx redirect to an internal service, including the cloud metadata endpoint, and the response body is returned to the tool caller. The flaw bypasses the mitigation added in GHSA-39j6-4867-gg4w, which checked only the invocation-time URL.
mcp-shell at commit 17ac0eef5c9a5a42b8fb132d3d034973d55a5433 ships with its security layer disabled: config.go sets SecurityConfig Enabled to false, and the from-source install path and MCP client example never set MCP_SHELL_SEC_CONFIG_FILE, so any connected LLM can call shell_exec with arbitrary commands. Separately, the official security.yaml baked into the Docker image lists /bin/bash and /usr/bin/python3 in allowed_executables, so secure mode can be bypassed by calling /bin/bash -i, which passes validation and yields an interactive shell.
mcp-shell's default Docker configuration (security.yaml) includes /bin/bash in allowed_executables, and the command validator in security.go checks only the first token, so it does not block shell flags such as -c. Any MCP tool caller can send command=/bin/bash -c <arbitrary-command> to shell_exec, with no authentication or configuration changes needed, and run binaries outside the allowlist as mcpuser inside the container.
mcp-shell's secure mode, which restricts execution to an allowlist defined in security.yaml, can be bypassed through the shell_exec MCP tool. The default allowlist includes /usr/bin/git, and the metacharacter validator in security.go omits the ! character, which Git uses for shell aliases, so passing /usr/bin/git -c alias.pwn=!<command> yields arbitrary OS command execution as the mcp-shell process user, with no authentication required in the default Docker deployment.
qwed-mcp v0.2.0 passes attacker-controlled strings to SymPy's parse_expr() in src/qwed_mcp/engines/math_engine.py without restricting global_dict or validating the expression's AST. Because parse_expr() calls eval() and Python injects __builtins__ by default, an attacker can embed expressions such as __import__('os').system(...) to run OS commands in the running process. The source reports confirmed root-level execution in a Docker container, requiring no authentication or special configuration.
The PraisonAI MCP server's HTTP-stream transport, started with praisonai mcp serve --transport http-stream, validates Origin with a startswith prefix match against http://localhost and http://127.0.0.1. An attacker can therefore host a page on a hostname such as localhost.attacker.com, and when a victim visits it, the server accepts and executes unauthenticated cross-site requests, including a tools/call that creates a rule file with activation "always" to inject persistent prompt instructions into later agent runs. The request can be sent as a CORS simple request with Content-Type: text/plain, requiring no preflight, and no session is needed for tools/call. This is a blind CSRF against a local agent runtime.
PraisonAI's async Jobs API, the FastAPI service in `praisonai/jobs/`, registers its `/api/v1/runs` router with no authentication middleware, router-level dependency or per-route check. Any caller who can reach the server can submit jobs that run against the operator's configured LLM credentials, list and read other jobs' results, cancel running jobs and delete terminal jobs. The advisory describes this as a distinct, still-unpatched sibling of CVE-2026-44338, which fixed only the legacy Flask server at version 4.6.51.
PraisonAI's `praisonai serve agents` and `praisonai serve unified` accept `--api-key` but never wire it into the FastAPI app, so no middleware or header check runs. The server stays open regardless of the key, as confirmed on 4.6.50 and likely since 4.6.34, affecting `src/praisonai/praisonai/cli/features/serve.py`.
The `praisonai serve agents` command accepts `--api-key` and forwards it to `ServeHandler`, but `_create_agents_app()` never reads `config["api_key"]` and attaches no auth dependency or middleware to its direct routes. As a result, unauthenticated network callers can invoke registered agents through `POST /agents` and `POST /agents/{agent_name}` even when the operator sets `--api-key`, and requests with missing, wrong, or empty credentials all reach `agent.start()`. The existing `verify_token` dependency in `praisonai.api.agent_invoke` protects the `/api/v1/...` routes in the same app, but the direct routes do not use it, and `verify_token` reads the `CALL_SERVER_TOKEN` environment variable rather than the CLI option.
PraisonAI's `praisonai.code` tool wrappers, exported as `CODE_TOOLS`, enforce a `workspace` boundary unsoundly. The containment helper `is_path_within_directory()` uses `os.path.abspath()` rather than resolving symlinks, so a symlink inside the workspace pointing outside passes the check and `open()` follows it. `list_files()` never calls the helper, and `execute_command()` and `code_execute_command()` never validate `cwd`, letting an attacker who can influence an agent read, write, list and execute outside the configured workspace, limited only by the process user's filesystem permissions.
The `ast_grep_rewrite` function in `praisonaiagents/tools/ast_grep_tool.py` lacks the `@require_approval` decorator that every sibling file-mutation and code-execution tool in `praisonaiagents/tools/` applies. With `dry_run=False`, an LLM-controllable call runs `sg ... --update-all` through `subprocess.run`, rewriting every file under `path` that matches the pattern, with no approval gate, no `_validate_path` workspace check, and no `cwd=` sandboxing. The function returns the string `No changes made` even when files were modified.
The web_crawl tool in praisonaiagents checks only the initial URL for private, loopback and link-local addresses, resolving the hostname once with socket.gethostbyname. The fetcher then follows redirects through httpx.Client(follow_redirects=True) or urllib.request.urlopen and re-resolves DNS at connect time without re-checking. An attacker can bypass the check with a redirect to internal hosts such as 169.254.169.254 or with DNS rebinding, so an agent can read internal HTTP services and instance-metadata endpoints, with the response body returned in tool output.
PraisonAI's `praisonai serve agents` command accepts `--api-key`, but the key is never enforced on the `POST /agents` and `POST /agents/{agent_name}` compatibility routes. Any network-reachable caller can invoke agents without credentials, even when the server is started with `--api-key` and bound to `0.0.0.0`. The advisory confirms v4.6.48 and v4.6.34 as vulnerable and gives a likely affected range of `>= 4.6.34, <= 4.6.48`.
Fix: Fixed in 0.8.2. Upgrade to browse-mcp 0.8.2. The fix confines `save_dir` under `~/.browse-mcp/downloads` and the state `path` under `~/.browse-mcp/state`, rejects absolute paths and `..` escapes, reduces download filenames to a bare basename, and makes `force_fetch` honor the origin fence. Workaround: restrict `BROWSE_MCP_TOOLS` to exclude `browser_download`, `browser_save_state` and `browser_load_state`, noting this does not stop a malicious MCP client from calling them by name.
Fix: Fixed in 0.117.2.
Fix: Flip the default to SecurityConfig{Enabled: true}, making secure mode the operating default, and keep unrestricted mode behind an affirmative opt-in flag or environment variable such as --allow-unsafe.
Fix: Resolve the hostname once, validate that IP, and connect to that exact validated IP (pin it) rather than re-resolving. Disable redirect following (follow_redirects=False; for urllib use a redirect handler that re-validates), or re-validate every redirect hop's resolved IP. Apply the deny check to both the validator and the actual socket target. file_tools.py:364 already uses follow_redirects=False and is the correct pattern to propagate.