feat(security): security hardening, proxy support, and GL045 HTTP include warning
ci / vet, staticcheck, test, build (push) Failing after 2m32s
release / Build and publish release (push) Successful in 1m17s

Security fixes:
- Path traversal guard in include: local: — paths with ../ that escape
  the repo root are rejected instead of reading arbitrary host files
- HTTP timeout (30 s) on all fetcher requests to prevent indefinite hangs
- Response size cap (10 MiB) via io.LimitReader to prevent memory exhaustion
- Cache directory and file permissions tightened to 0700/0600
- LSP Content-Length cap (64 MiB) to guard against DoS from a malicious client

New feature:
- --proxy flag on check, graph, and lsp subcommands; also proxy: key in
  .glint.yml; overrides system HTTP_PROXY / HTTPS_PROXY env vars when set;
  cmdGraph and cmdLSP now also load .glint.yml for proxy/token/url fallbacks

New lint rule:
- GL045 (Warning): include: remote: using plain http:// instead of https://

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-26 21:52:57 +02:00
parent 4972adb213
commit f79c64cd44
22 changed files with 422 additions and 18 deletions
+25
View File
@@ -71,3 +71,28 @@ func TestCacheWrite_MkdirAll(t *testing.T) {
t.Errorf("directory not created: %v", err)
}
}
func TestCacheWrite_FilePermissions(t *testing.T) {
dir := t.TempDir()
cacheWrite(dir, "seckey", []byte("secret"))
info, err := os.Stat(cachePath(dir, "seckey"))
if err != nil {
t.Fatalf("stat cache file: %v", err)
}
if mode := info.Mode().Perm(); mode != 0o600 {
t.Errorf("cache file mode = %04o; want 0600", mode)
}
}
func TestCacheWrite_DirPermissions(t *testing.T) {
parent := t.TempDir()
dir := filepath.Join(parent, "glint-cache")
cacheWrite(dir, "k", []byte("v"))
info, err := os.Stat(dir)
if err != nil {
t.Fatalf("stat cache dir: %v", err)
}
if mode := info.Mode().Perm(); mode != 0o700 {
t.Errorf("cache dir mode = %04o; want 0700", mode)
}
}