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
+8
View File
@@ -66,6 +66,11 @@ func (s *Server) Run() error {
}
}
// maxLSPMessageBytes caps the body size accepted from an LSP client.
// A legitimate editor message is never this large; enforcing the cap prevents
// a crafted Content-Length from triggering a multi-gigabyte allocation.
const maxLSPMessageBytes = 64 << 20 // 64 MiB
// readMessage reads one Content-Lengthframed JSON-RPC message from the stream.
func (s *Server) readMessage() (*Message, error) {
var contentLength int
@@ -92,6 +97,9 @@ func (s *Server) readMessage() (*Message, error) {
if contentLength == 0 {
return nil, fmt.Errorf("missing or zero Content-Length header")
}
if contentLength > maxLSPMessageBytes {
return nil, fmt.Errorf("Content-Length %d exceeds maximum %d", contentLength, maxLSPMessageBytes)
}
body := make([]byte, contentLength)
if _, err := io.ReadFull(s.in, body); err != nil {