nextlevelbuilder / nextlevelbuilder/goclaw
[Security] Agent Config Bypass via V3-Flags — Viewer Mutates Admin-Only Agent Config
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 3.6k
- Forks
- 1.1k
- Avg merge
- 3d 5h
- Merged PRs (30d)
- 24
Description
Source: https://gist.github.com/YLChen-007/701348c2dee3bc173b71f695a5eb89fe/raw
Advisory Details
Title: Agent Config Bypass via V3-Flags — Viewer Mutates Admin-Only Agent Config
Description:
Summary
A broken access control vulnerability in the PATCH /v1/agents/{agentID}/v3-flags endpoint allows any tenant member (including users with only a Viewer role) to modify administrative agent configuration. The endpoint improperly uses a weak authentication wrapper that auto-elevates users with a Gateway Token to RoleAdmin but completely fails to perform the mandatory tenant-level role validation. In multi-tenant environments, this allows unauthorized configuration changes that affect all users of the target agent.
Details
The root cause of this vulnerability lies in the combination of a weak authentication wrapper and a missing secondary tenant role validation.
In internal/http/v3_flags_handlers.go, the V3FlagsHandler uses the h.auth(next) wrapper:
func (h *V3FlagsHandler) auth(next http.HandlerFunc) http.HandlerFunc {
return requireAuth("", next)
}
When requireAuth("") is used with an empty minRole, the middleware auto-detects the minimum role from the HTTP method. For PATCH, this defaults to RoleOperator (level 2).
However, in environments where the GoClaw Gateway Token is used (the standard deployment model), the authentication layer (auth.go:resolveAuthWithBearer) automatically elevates any user who is a member of the tenant to a global RoleAdmin (level 3). Since RoleAdmin (3) >= RoleOperator (2), the first layer of authentication passes regardless of the user's actual role in the specific tenant.
Properly secured endpoints across the codebase that deal with tenant-scoped mutations (e.g., PUT /v1/tools/builtin/{name}/tenant-config) enforce a second layer of validation by calling requireTenantAdmin() within the business logic of the handler. This function checks the database to verify the user actually holds an owner or admin role inside that tenant.
Unfortunately, handleToggleFlags in internal/http/v3_flags_handlers.go skips this critical check completely, immediately updating the database (h.agents.Update) and allowing any Viewer to mutate the Agent's runtime flags (such as self_evolution_metrics).
PoC
Prerequisites
- Environment: A standard GoClaw deployment containing the
GOCLAW_GATEWAY_TOKEN(the default multi-tenant setup). - Target Network Access: The attacker needs HTTP access to the backend API.
- Attacker Identity: The attacker must possess the system gateway token (which is shared with all authenticated UI users) and have membership in the target tenant at any arbitrary level (e.g.,
Viewer).
Reproduction Steps
- Configure the local Docker environment by downloading the
docker-compose.yml: docker-compose.yml - Start the testing environment to bind the simulated server to
http://127.0.0.1:18799:docker compose up -d - Wait for the
postgresandgoclawcontainers to become healthy (approximately 10 seconds). - Download the exploit proof-of-concept script: poc_exploit.py
- Execute the proof of concept script:
(The script simulates an admin creating an agent, and then a Viewer bypassing authorization to change thepython3 poc_exploit.pyself_evolution_metricsvia thePATCH /v1/agents/{agentID}/v3-flagsendpoint). - Compare with the correctly secured endpoints using the control script: control-admin_gate_enforced.py
python3 control-admin_gate_enforced.py
Log of Evidence
=== EXPLOIT RUN ===
[SETUP] Created agent test-agent-8227fa48 (id=019dd19b-f5ed-7edb-b3cc-6f4219639f53)
[*] PATCH /v1/agents/019dd19b-f5ed-7edb-b3cc-6f4219639f53/v3-flags → 200
[*] Response: {"status":"ok"}
[EXPLOITED-EXTERNAL] Viewer mutated agent config via v3-flags bypass: {'v3_pipeline_enabled': False, 'v3_memory_enabled': False, 'v3_retrieval_enabled': False, 'self_evolution_metrics': True, 'self_evolution_suggestions': False}
=== CONTROL RUN ===
[*] PUT /v1/tools/builtin/web_search/tenant-config as Viewer → 403
[*] Response: {"error":"permission denied: tenant config"}
[CONTROL-PASS] Tenant-admin-protected endpoint correctly BLOCKED Viewer
Impact
This Broken Access Control (Improper Privilege Management) vulnerability allows unauthorized users to tamper with sensitive AI Agent behavior flags. By modifying properties like self_evolution_metrics, a low-privileged Viewer can interfere with the operation of the Agent. In an enterprise or multi-tenant deployment, this means any user who is granted read-only access to a workspace can silently degrade performance, manipulate underlying caching and evolution metrics, or maliciously consume backend LLM API quotas, affecting the whole organization utilizing the agent.
Affected products
- Ecosystem: go
- Package name: github.com/nextlevelbuilder/goclaw
- Affected versions: <= v3.11.3
- Patched versions:
Severity
- Severity: High
- Vector string: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L
Weaknesses
- CWE: CWE-285: Improper Authorization
Occurrences
| Permalink | Description |
|---|---|
| https://github.com/nextlevelbuilder/goclaw/blob/v3.11.3/internal/http/v3_flags_handlers.go#L27-L29 | The auth wrapper improperly resolves base roles with requireAuth("") allowing gateway token automatic elevation. |
| https://github.com/nextlevelbuilder/goclaw/blob/v3.11.3/internal/http/v3_flags_handlers.go#L54-L119 | The missing requireTenantAdmin vulnerability in the core HTTP handler for modifying V3-Flags, entirely skipping secondary validation before database write. |
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with internal/http/v3_flags_handlers.go, especially V3FlagsHandler and handleToggleFlags, then trace auth.go:resolveAuthWithBearer and requireTenantAdmin used by tenant-scoped mutations. Run the provided Docker setup and poc_exploit.py, comparing its result with control-admin_gate_enforced.py. Done means a Viewer can no longer modify v3-flags while authorized tenant administrators retain access.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, python
- Domain
- api, authentication, authorization, backend, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 52/100