Turso CLI, Insecure File Permission (World-Readable Credential), CVE-2024-XXXX (Medium) -DC-Jun2026-700

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 default configPermissions. 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 through configdir.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 including gh, aws, docker, gcloud, planetscale, neon, and `upstash` explicitly write credential files with `0o600` permissions.
The vulnerability was patched in commit tursodatabase/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:

  1. 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.
  2. 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

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top