Listen to this Post
Note: A public CVE identifier has not yet been assigned to this vulnerability. The security advisory is tracked under GitHub Security Advisory ID
GSA_kwCzR0hTQS01N2Y2LXB2eDgtaHdqNs4ABZnU.
The Turso CLI (turso-cli) contains a vulnerability that exposes user credentials due to insecure default file permissions. When a user authenticates with the Turso platform, the CLI stores the resulting platform JWT (JSON Web Token) in a local `settings.json` file. This file is written using the Viper configuration library’s default file permissions of `0o644` (readable by all users on the system).
The vulnerability arises because the Turso CLI does not override Viper’s defaultconfigPermissions. Viper v1.21.0 initializes `configPermissions` to `os.FileMode(0o644)` and passes this mode directly to `os.OpenFile` when creating the configuration file. The CLI code contains no subsequent `os.Chmod` call to tighten permissions, leaving the file world-readable.
The JWT stored in this file grants full Turso platform access scoped to the user’s organizations, allowing an attacker to create or destroy databases, rotate credentials, exfiltrate data, and modify billing settings. On multi-user systems, shared development environments, or CI/CD runners with mounted home directories, any other local user can read this file and recover the token.
The file is stored at platform-specific paths resolved throughconfigdir.LocalConfig("turso"):
– macOS: `~/Library/Application Support/turso/settings.json`
– Linux: `~/.config/turso/settings.json` (or$XDG_CONFIG_HOME/turso/settings.json)
This behavior deviates from industry standards—comparable CLIs includinggh,aws,docker,gcloud,planetscale,neon, and `upstash` explicitly write credential files with `0o600` permissions.
The vulnerability was patched in committursodatabase/turso-cli@ffb9148, which adds `viper.SetConfigPermissions(0o600)` to restrict the settings file to the owner only.
DailyCVE Form
Platform: `Linux/macOS`
Version: `<= 1.0.25`
Vulnerability: `World-readable JWT`
Severity: `Medium`
Date: `2026-06-26`
Prediction: `Patched in v1.0.26`
What Undercode Say
Analytics & Verification
The vulnerability can be verified by inspecting the file permissions after authentication:
Check permissions on Linux ls -la ~/.config/turso/settings.json Expected output: -rw-r--r-- (644) Check permissions on macOS ls -la "$HOME/Library/Application Support/turso/settings.json" Expected output: -rw-r--r-- (644)
The file contains the JWT in plaintext JSON:
cat ~/.config/turso/settings.json
Output resembles:
{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...","organization":"exampleorg","username":"user"}
A minimal reproducer using the same Viper version confirms the behavior:
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)
}
// Output: mode: 644
The same SafeWriteConfig/WriteConfig calls used by `turso-cli` produce the `0o644` mode during a real `turso auth login` flow.
A `grep` over the auth-config write path under `internal/` returns zero hits for Chmod, 0o600, or 0600, confirming no follow-up permission tightening exists.
Exploit
An attacker with local access to the system can read the JWT credential:
On Linux cat ~/.config/turso/settings.json | jq -r '.token' On macOS cat "$HOME/Library/Application Support/turso/settings.json" | jq -r '.token'
Once extracted, the JWT can be used to authenticate against the Turso Platform API, granting the attacker the same permissions as the victim user—including database creation, deletion, credential rotation, data exfiltration, and billing changes.
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
Protection
Immediate Workarounds
Until upgrading to the patched version, manually tighten file permissions:
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"
Important: This must be repeated after any operation that recreates the file (e.g.,
turso auth login) until the patched version is installed.
Permanent Fix
Upgrade to `turso-cli` version 1.0.26 or later, which includes the patch.
The one-line fix adds `viper.SetConfigPermissions(0o600)` 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 only
Defense in Depth
For additional security, consider:
- File-level hardening: Add `os.Chmod(configFile, 0o600)` after
TryToPersistChanges, or on read (as PlanetScale does—they `Stat` the token file and self-heal if `Mode() &^ 0o600` is nonzero). Note that `viper.SetConfigPermissions` applies only on file creation, so an existing wider-mode file is not tightened otherwise. - Directory-level hardening: 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.
Impact
| Aspect | Details |
|–||
| Confidentiality | High — JWT credentials are exposed to any local user |
| Integrity | High — Attacker can create, modify, or delete databases and rotate credentials |
| Availability | High — Databases can be destroyed, and billing settings can be altered |
| Attack Vector | Local — Requires local filesystem access on the same host |
| Scope | Full Turso platform access scoped to the victim’s organizations |
| Affected Versions | All versions <= 1.0.25 |
| Fixed Version | 1.0.26 |
The token 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. On multi-user systems, this effectively means any local user can escalate to the victim’s Turso privileges without authentication.
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

