Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessAttain local UID on shared or CI host
-
DeliveryLocate settings.json at ~/.config/turso/settings.json
-
ExploitRead world-readable file (mode 0o644)
-
ExecutionExtract plaintext JWT from JSON
-
PersistAuthenticate to Turso platform API as victim
-
ImpactExfiltrate data or destroy databases across victim's organizations
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A01:2025 - Broken Access Control
ASVS 5.0
V13 - Configuration Default permission hardening
MITRE ATT&CK
1 technique across 1 tactic: Privilege Escalation The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up. |
| Exploitation Conditions | The attacker must hold any valid local UID on the same host as the turso-cli user and must be able to read the victim's configuration directory - satisfied by default on Linux and macOS where home directories are typically mode 0o755. The victim must have previously completed turso auth login, causing the OAuth callback to write the JWT to settings.json. No privilege escalation is required beyond a basic local account. Exploitation is bounded to local-access scenarios only - there is no remote network vector. Risk is significantly amplified in: CI runners where the host home directory is bind-mounted into the job environment; containers with a mounted host home volume; shared multi-user developer hosts or jumpboxes; and cron daemons or system services running as a different UID with read access to the filesystem. Single-user workstations with full-disk encryption and no shared accounts represent substantially lower real-world risk. |
| Impact | The NVD CVSS 3.1 score of 5.5 with vector AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N accurately represents the local-access prerequisite and high-confidentiality impact. EPSS data is not present in the provided input, so exploitation probability cannot be quantified. No CISA KEV listing exists. A working proof-of-concept is embedded in the advisory itself, making exploitation trivially reproducible by any local user. Real-world risk is amplified well beyond a typical local-access finding in environments where CI/CD runners mount the host home directory, containers bind-mount home volumes, or shared jumpboxes host multiple developer accounts - all common in modern cloud-native development workflows. The JWT's scope (full platform control across all user organizations) means the downstream blast radius is disproportionate to the local access required. The vulnerability represents a genuine priority for teams running turso-cli on shared or containerized hosts, while single-user workstations present substantially lower risk. No conflicts between available signals were identified. |
| Exploit ScenarioDerived | A co-tenant on a shared Linux developer host or a CI job running on a runner with a mounted home directory executes cat ~/.config/turso/settings.json and trivially recovers the plaintext JWT. The attacker then presents the token as a Bearer credential against the Turso platform API to enumerate, query, or delete all databases across any organization the victim belongs to, or rotates credentials to lock the legitimate user out. A proof-of-concept demonstrating the 0o644 mode using the same Viper version pinned by turso-cli is included verbatim in the advisory. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Jun 26, 2026
Credential exposure in turso-cli versions 1.0.25 and earlier allows any local user on the same host to read the Turso platform JWT stored world-readable at mode 0o644 in settings.json, granting full access to all Turso organizations the victim belongs to. The root cause is turso-cli's failure to override Viper's insecure default configPermissions before writing credentials - a deviation from the explicit 0o600 baseline established by comparable CLIs including gh, aws, docker, and gcloud. A proof-of-concept demonstrating the 0o644 mode is included in the advisory; no active exploitation is listed in CISA KEV.
RemediationAI
Upgrade turso-cli to version 1.0.26, which includes the vendor-released patch at https://github.com/tursodatabase/turso-cli/commit/ffb914849216ef5a86353b3fa6cee66f33af3b66, adding viper.SetConfigPermissions(0o600) to the Viper initialization block in internal/settings/settings.go. Critically, viper.SetConfigPermissions applies only on file creation - existing settings.json files with 0o644 mode are not automatically tightened by upgrading alone. After upgrading, run chmod 600 ~/.config/turso/settings.json && chmod 700 ~/.config/turso on Linux, or chmod 600 "$HOME/Library/Application Support/turso/settings.json" && chmod 700 "$HOME/Library/Application Support/turso" on macOS. This manual step must also be repeated after any turso auth login that recreates the file on an unpatched installation. As defense in depth, the vendor advisory recommends also adding os.Chmod(configFile, 0o600) after TryToPersistChanges to self-heal pre-existing files with overly broad modes, following the pattern used by the PlanetScale CLI.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 2 packages in go, euvd
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
turso-cli is a Go-based command-line tool for the Turso hosted SQLite platform, using the Viper configuration library (v1.21.0, pinned in go.mod) for settings persistence. Viper initializes its internal configPermissions field to os.FileMode(0o644) at viper.go:198 and passes this mode directly to os.OpenFile at viper.go:1688 when writing config files. The turso-cli auth flow captures the platform JWT in the OAuth callback (internal/cmd/auth.go:205-214), writes it via viper.Set('token', jwt) through the settings layer (internal/settings/settings.go:124-127), and persists it with viper.WriteConfig() (internal/settings/settings.go:96-101) - without ever calling viper.SetConfigPermissions(0o600) to override the insecure default. A code audit confirmed zero occurrences of Chmod, 0o600, or 0600 on the auth-config write path under internal/. CWE-276 (Incorrect Default Permissions) is the primary root cause, with CWE-732 (Incorrect Permission Assignment for Critical Resource) also applicable given the credential nature of the file. The affected package is pkg:go/github.com/tursodatabase/turso-cli at versions <= 1.0.25.
Know when Docker gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Local file read requires an existing local account (AV:L, PR:L); 0o644 default needs no special conditions (AC:L); credential theft yields full confidentiality loss with no integrity or availability impact on the local system.
Primary rating from Vendor (https://github.com/tursodatabase/turso-cli).
CVSS VectorVendor: https://github.com/tursodatabase/turso-cli
DescriptionCVE.org
Summary
turso-cli persists the user's Turso platform JWT to settings.json using Viper's default configPermissions of 0o644, leaving the credential file world-readable on standard Linux and macOS systems. Any other local UID on the host can read the file and recover the platform JWT, which grants full Turso platform access scoped to the user's organizations.
Impact
The token in settings.json grants the holder full Turso platform access - create or destroy databases, rotate credentials, exfiltrate data, change billing settings - for any organization the user belongs to.
Because the file is world-readable, the credential is reachable by:
- Cron jobs or daemons running as a different system user on the same host
- Sandboxed CI runners with a mounted home directory
- Containers with a bind-mounted host home
- Co-tenants on a shared multi-user developer or jumpbox host
The file path resolves through configdir.LocalConfig("turso"):
- macOS:
~/Library/Application Support/turso/settings.json - Linux:
~/.config/turso/settings.json(or$XDG_CONFIG_HOME/turso/settings.json)
It contains the platform JWT in plaintext JSON alongside organization and username fields.
Comparable CLIs (gh, aws, docker, gcloud, plus close peers planetscale, neon, upstash) write credential files at 0o600 explicitly, so this is a deviation from the cross-vendor baseline rather than a deliberate trade-off.
Details
The OAuth callback handler stores the platform JWT via the settings layer:
// internal/cmd/auth.go:205-214
jwt, err := callbackServer.Result()
...
settings.SetToken(jwt)SetToken writes through Viper:
// internal/settings/settings.go:124-127
func (s *Settings) SetToken(token string) {
viper.Set("token", token)
s.changed = true
}Persistence runs through viper.WriteConfig:
// internal/settings/settings.go:96-101
func TryToPersistChanges() error {
if err := viper.WriteConfig(); err != nil {
return fmt.Errorf("failed to persist turso settings file: %w", err)
}
return nil
}Viper v1.21.0 (pinned in turso-cli go.mod) initializes configPermissions to os.FileMode(0o644) at viper.go:198 and passes that mode straight to os.OpenFile at viper.go:1688. Without a call to viper.SetConfigPermissions(0o600), the resulting settings.json is created at 0o644.
A grep over the auth-config write path under internal/ returns zero hits for Chmod, 0o600, or 0600, confirming there is no follow-up tightening of the file mode anywhere on the persistence path.
Proof of concept
Minimal reproducer using the same Viper version turso-cli pins (github.com/spf13/viper v1.21.0):
package main
import (
"fmt"
"os"
"path/filepath"
"github.com/spf13/viper"
)
func main() {
dir, _ := os.MkdirTemp("", "viperpoc-*")
defer os.RemoveAll(dir)
viper.SetConfigName("settings")
viper.SetConfigType("json")
viper.AddConfigPath(dir)
viper.Set("token", "FAKE_TURSO_JWT_xxxxxxxxxxxxxxxxxxxx")
viper.Set("organization", "exampleorg")
viper.SafeWriteConfig()
st, _ := os.Stat(filepath.Join(dir, "settings.json"))
fmt.Printf("mode: %o\n", st.Mode()&0o777)
}$ go run main.go mode: 644
The same SafeWriteConfig / WriteConfig calls turso-cli uses produce the same 0o644 mode in a real turso auth login flow.
Remediation
One-line fix at the existing Viper configuration site in internal/settings/settings.go (around lines 48-50):
viper.SetConfigName("settings")
viper.SetConfigType("json")
viper.AddConfigPath(configPath)
viper.SetConfigPermissions(0o600) // restrict settings.json to owner onlyDefense in depth:
- Add
os.Chmod(configFile, 0o600)afterTryToPersistChanges, or on read (as PlanetScale does ininternal/config/config.go- theyStatthe token file and self-heal ifMode() &^ 0o600is nonzero).viper.SetConfigPermissionsapplies only on file creation, so an existing wider-mode file is not tightened otherwise. - Add
os.Chmod(configPath, 0o700)afterconfigdir.MakePath(configPath)(line 43) to close the equivalent gap on the enclosing directory, which is otherwise created under the default umask.
Patch: https://github.com/tursodatabase/turso-cli/commit/ffb914849216ef5a86353b3fa6cee66f33af3b66
Workarounds
Until upgraded, users can tighten the existing files manually:
# Linux
chmod 600 ~/.config/turso/settings.json
chmod 700 ~/.config/turso
# macOS
chmod 600 "$HOME/Library/Application Support/turso/settings.json"
chmod 700 "$HOME/Library/Application Support/turso"This must be repeated after any operation that recreates the file (e.g. turso auth login) until the patched version is installed.
Resources
- Patch commit: https://github.com/tursodatabase/turso-cli/commit/ffb914849216ef5a86353b3fa6cee66f33af3b66
- Viper
configPermissionsdefault: https://github.com/spf13/viper/blob/v1.21.0/viper.go#L198 - Viper write path: https://github.com/spf13/viper/blob/v1.21.0/viper.go#L1688
- CWE-276: https://cwe.mitre.org/data/definitions/276.html
- CWE-732: https://cwe.mitre.org/data/definitions/732.html
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Privilege escalation occurs when an attacker leverages flaws in access control mechanisms to gain permissions beyond what they were originally granted.
An issue was discovered in Appsmith before 1.52. Rated critical severity (CVSS 9.8), this vulnerability is remotely expl
runc through version 1.0-rc6 (used in Docker before 18.09.2) contains a container escape vulnerability that allows attac
Netmaker makes networks with WireGuard. Rated high severity (CVSS 7.5), this vulnerability is remotely exploitable, no a
Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/
The News & Blog Designer Pack - WordPress Blog Plugin - (Blog Post Grid, Blog Post Slider, Blog Post Carousel, Blog Post
Path traversal in JFrog Artifactory (CWE-22) enables an authenticated low-privilege user to write data outside the inten
Docker 1.3.2 allows remote attackers to execute arbitrary code with root privileges via a crafted (1) image or (2) build
Remote code execution in Gogs through 0.14.2 allows authenticated users (and unauthenticated attackers on default-config
Unauthenticated remote command injection in SGWBOX N3 firmware 2.0.25 lets attackers execute arbitrary operating-system
Remote code execution in Flowise before 3.1.2 allows any authenticated user (or API caller with chatflow view/update per
Remote code execution in NocoBase Workflow Script Node (npm @nocobase/plugin-workflow-javascript) allows authenticated l
Docker Desktop Community Edition before 2.1.0.1 allows local users to gain privileges by placing a Trojan horse docker-c
Same weakness CWE-276 – Incorrect Default Permissions
View allSame technique Privilege Escalation
View allVendor StatusVendor
SUSE
Severity: Moderate| Product | Status |
|---|---|
| SUSE Linux Enterprise Server 16.1 | Affected |
| SUSE Linux Enterprise Server for SAP applications 16.1 | Affected |
| SUSE Linux Enterprise Module for Package Hub 15 SP5 | Affected |
| SUSE Linux Enterprise Module for Package Hub 15 SP6 | Affected |
| openSUSE Leap 15.5 | Affected |
| openSUSE Leap 15.6 | Affected |
EUVD-2026-56787
GHSA-57f6-pvx8-hwj6
NVD
CVE.org
EPSS
VulDB
Exploit-DB