Skip to main content

turso-cli CVE-2026-48790

| EUVDEUVD-2026-56787 MEDIUM
Incorrect Default Permissions (CWE-276)
2026-06-26 https://github.com/tursodatabase/turso-cli GHSA-57f6-pvx8-hwj6
5.5
CVSS 3.1 · Vendor: https://github.com/tursodatabase/turso-cli
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Attain local UID on shared or CI host
  2. Delivery
    Locate settings.json at ~/.config/turso/settings.json
  3. Exploit
    Read world-readable file (mode 0o644)
  4. Execution
    Extract plaintext JWT from JSON
  5. Persist
    Authenticate to Turso platform API as victim
  6. Impact
    Exfiltrate 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.

This Month Plan within 30 days. Why: MEDIUM severity (CVSS 4.0-6.9).
Patch available 0.1% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – 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

turso-cli < 1.0.26

Affected Packages

go github.com/tursodatabase/turso-cli fix: 1.0.26
euvd turso_cli fix: 1.0.26

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

Vendor (https://github.com/tursodatabase/turso-cli) PRIMARY 5.5 MEDIUM
AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
vuln.today AI 5.5 MEDIUM

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.

3.1 AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
4.0 AV:L/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:H/SI:H/SA:N
SUSE MEDIUM

Primary rating from Vendor (https://github.com/tursodatabase/turso-cli).

CVSS VectorVendor: https://github.com/tursodatabase/turso-cli

Attack Vector
Local
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
None
Availability
None

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:

go
// internal/cmd/auth.go:205-214
jwt, err := callbackServer.Result()
...
settings.SetToken(jwt)

SetToken writes through Viper:

go
// internal/settings/settings.go:124-127
func (s *Settings) SetToken(token string) {
    viper.Set("token", token)
    s.changed = true
}

Persistence runs through viper.WriteConfig:

go
// 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):

go
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):

go
viper.SetConfigName("settings")
viper.SetConfigType("json")
viper.AddConfigPath(configPath)
viper.SetConfigPermissions(0o600) // restrict settings.json to owner only

Defense in depth:

  • Add os.Chmod(configFile, 0o600) after TryToPersistChanges, or on read (as PlanetScale does in internal/config/config.go - they Stat the token file and self-heal if Mode() &^ 0o600 is nonzero). viper.SetConfigPermissions applies only on file creation, so an existing wider-mode file is not tightened otherwise.
  • Add os.Chmod(configPath, 0o700) after configdir.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:

sh
# 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 configPermissions default: 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

EPSS Score
0.1%
Top 99% exploitable
Prevalence
Low
niche developer CLI for a hosted SQLite platform, limited enterprise footprint
Threat Intel
1
1 source
Exploit
POC
Public exploit code exists
Social Media
1
Sightings
Data Quality
7 sources
Confidence: High

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.

SignalValue
Severity MEDIUM
CISA KEV No
Public POC Yes
EPSS 0.1%
Patch available Yes
Active threat No
Deciding rule
MEDIUM severity (CVSS 4.0-6.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision· derived
Scheduled
Exploitation· derived
Poc
System Exposure· derived
Small
Automatable· derived
No
Human Impact· derived
Medium

Priority Score

48
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +28
PoC: +20
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

Privilege escalation occurs when an attacker leverages flaws in access control mechanisms to gain permissions beyond what they were originally granted.

More in Docker

View all
CVE-2024-55964 CRITICAL POC
9.8 Mar 26

An issue was discovered in Appsmith before 1.52. Rated critical severity (CVSS 9.8), this vulnerability is remotely expl

CVE-2019-5736 HIGH POC
8.6 Feb 11

runc through version 1.0-rc6 (used in Docker before 18.09.2) contains a container escape vulnerability that allows attac

CVE-2023-32077 HIGH POC
7.5 Aug 24

Netmaker makes networks with WireGuard. Rated high severity (CVSS 7.5), this vulnerability is remotely exploitable, no a

CVE-2026-39987 CRITICAL POC
9.3 Apr 08

Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/

CVE-2023-5815 HIGH POC
8.1 Nov 22

The News & Blog Designer Pack - WordPress Blog Plugin - (Blog Post Grid, Blog Post Slider, Blog Post Carousel, Blog Post

CVE-2026-66384 MEDIUM POC
5.3 Aug 12

Path traversal in JFrog Artifactory (CWE-22) enables an authenticated low-privilege user to write data outside the inten

CVE-2014-9357 CRITICAL
10.0 Dec 16

Docker 1.3.2 allows remote attackers to execute arbitrary code with root privileges via a crafted (1) image or (2) build

CVE-2026-52806 CRITICAL POC
9.9 Jun 23

Remote code execution in Gogs through 0.14.2 allows authenticated users (and unauthenticated attackers on default-config

CVE-2025-14707 HIGH POC
8.9 Dec 15

Unauthenticated remote command injection in SGWBOX N3 firmware 2.0.25 lets attackers execute arbitrary operating-system

CVE-2026-56274 HIGH POC
8.7 Jun 23

Remote code execution in Flowise before 3.1.2 allows any authenticated user (or API caller with chatflow view/update per

CVE-2026-34156 CRITICAL POC
9.9 Mar 30

Remote code execution in NocoBase Workflow Script Node (npm @nocobase/plugin-workflow-javascript) allows authenticated l

CVE-2019-15752 HIGH POC
7.8 Aug 28

Docker Desktop Community Edition before 2.1.0.1 allows local users to gain privileges by placing a Trojan horse docker-c

Vendor 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

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy