fix: security hardening and code quality

- SQL query mode uses read-only SQLite connection with PRAGMA query_only=ON
- Lua sandbox removes dofile/loadfile/load after OpenBase to block file access
- Plugin manager sorts by priority once at load time; GetPlugins is a plain copy
- Proxy appends [body truncated] marker when body hits size limit
- App startup exits with os.Exit(1) on DB open failure
- tickCmd uses tea.Tick instead of time.Sleep in a goroutine
- ErrMsg with non-nil error shows notification then quits
- DB stores path for use by read-only query connection
- WAL journal mode + NORMAL synchronous set in migrate()
- config.go uses errors.Is(err, os.ErrNotExist)
- main.go uses os.UserHomeDir() and removes racy port pre-check
- findings renderer is cached and rebuilt only on width change

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Hadi
2026-05-19 13:38:10 +02:00
parent 41c0e489cf
commit 172a77e13b
11 changed files with 88 additions and 37 deletions
+6 -13
View File
@@ -2,7 +2,6 @@ package main
import (
"fmt"
"net"
"os"
"path/filepath"
"runtime/debug"
@@ -56,7 +55,8 @@ func main() {
}
if *flagAddDefaultPlugins {
cfgPath := filepath.Join(os.Getenv("HOME"), ".config", "spilltea", "config.yaml")
home, _ := os.UserHomeDir()
cfgPath := filepath.Join(home, ".config", "spilltea", "config.yaml")
if *flagConfig != "" {
cfgPath = *flagConfig
}
@@ -78,7 +78,8 @@ func main() {
}
if *flagAddDefaultConfig {
cfgPath := filepath.Join(os.Getenv("HOME"), ".config", "spilltea", "config.yaml")
home, _ := os.UserHomeDir()
cfgPath := filepath.Join(home, ".config", "spilltea", "config.yaml")
if *flagConfig != "" {
cfgPath = *flagConfig
}
@@ -95,7 +96,8 @@ func main() {
os.Exit(1)
}
cfgPath := filepath.Join(os.Getenv("HOME"), ".config", "spilltea", "config.yaml")
home, _ := os.UserHomeDir()
cfgPath := filepath.Join(home, ".config", "spilltea", "config.yaml")
if *flagConfig != "" {
cfgPath = *flagConfig
}
@@ -119,15 +121,6 @@ func main() {
config.Global.App.UpstreamProxy = *flagUpstreamProxy
}
addr := fmt.Sprintf("%s:%d", config.Global.App.Host, config.Global.App.Port)
// Check if the proxy port is available before starting the UI.
ln, err := net.Listen("tcp", addr)
if err != nil {
fmt.Fprintf(os.Stderr, "proxy: cannot bind to %s: %v\n", addr, err)
os.Exit(1)
}
ln.Close()
style.Init(config.Global)
icons.Init(config.Global)
keys.Init(config.Global)