# Arcane: Missing admin authorization on global variables endpoint

Arcane's global variables endpoint lacked an admin check, letting any authenticated user overwrite .env.global and hijack every project's compose substitution.

- Payout: Research
- Severity: high
- Program: Arcane
- Found by: offset
- Disclosed: 2026-05-23
- CVE: CVE-2026-47125
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-jpjh-jm2p-39hh
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-jpjh-jm2p-39hh
- Tags: area:web domain:api domain:web impact:data-leak impact:integrity impact:rce kind:research platform:ghsa sev:high tech:go technique:source-review vuln:access-control vuln:auth-bypass vuln:crlf-injection vuln:privilege-escalation

**Target:** PUT /api/environments/{id}/templates/variables API endpoint
**Root cause:** The UpdateGlobalVariables handler omits the checkAdmin() call that every other admin-sensitive handler in the codebase uses; auth middleware only verifies authentication, not role. The key field is also only TrimSpace'd, permitting newline injection.
**Steps:**
1. Authenticate as any non-admin user (Bearer JWT or API key).
2. Send `PUT /api/environments/0/templates/variables` with body containing variables such as `REGISTRY` pointed at an attacker-controlled registry.
3. Optionally inject extra lines via a key containing `\n` (e.g. `FOO\nINJECTED`) since only TrimSpace is applied.
4. Service writes values to `<projectsDirectory>/.env.global`.
5. On next deploy of any project, EnvLoader merges the file into envMap and injectionVars, so `${REGISTRY}` resolves to the attacker value and the attacker image is pulled and run.
**How found:** Code review: noticed templates.go handler lacked the `checkAdmin(ctx)` guard present in users.go, events.go, swarm.go, settings.go, apikeys.go, environments.go, notifications.go, container_registries.go, git_repositories.go and system.go; corroborated by customize.go hiding the variables/registries categories from non-admins.
**Exploitation:** A non-admin writes attacker-controlled keys/values into .env.global; every project's compose substitution and container injection then uses them, redirecting image pulls to an attacker registry (RCE on the Docker host) or redirecting DATABASE_URL/SMTP_HOST/WEBHOOK_URL to attacker servers to capture credentials on next deploy.
**Escalation:** Chained from a low-privilege authenticated account to cross-tenant supply-chain RCE on the Docker host and credential theft from other users' projects.
**Insight:** When a codebase centralizes role checks in per-handler helpers rather than middleware, diff every handler against the admin-sensitive set — the one missing the guard is the bug. UI-side category filtering is a strong hint of intended admin-only surfaces.

