nextlevelbuilder / nextlevelbuilder/goclaw

[Security] Agent Config Bypass via V3-Flags — Viewer Mutates Admin-Only Agent Config

Open
#1,119 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

agent-settings agent:github-maintain area:security bug maintain:triaged P1-high
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
  1. Configure the local Docker environment by downloading the docker-compose.yml: docker-compose.yml
  2. Start the testing environment to bind the simulated server to http://127.0.0.1:18799:
    docker compose up -d
    
  3. Wait for the postgres and goclaw containers to become healthy (approximately 10 seconds).
  4. Download the exploit proof-of-concept script: poc_exploit.py
  5. Execute the proof of concept script:
    python3 poc_exploit.py
    
    (The script simulates an admin creating an agent, and then a Viewer bypassing authorization to change the self_evolution_metrics via the PATCH /v1/agents/{agentID}/v3-flags endpoint).
  6. 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.