Documentation
¶
Index ¶
- func AtomicWrite(path string, data []byte, perm os.FileMode) error
- func AtomicWriteFromReader(path string, reader io.Reader, perm os.FileMode) (int64, error)
- func EncodePathSegment(s string) string
- func NewDownloadHTTPClient(base *http.Client, opts DownloadHTTPClientOptions) *http.Client
- func RejectCRLF(value, fieldName string) error
- func RejectControlChars(value, flagName string) error
- func ResourceName(name, flagName string) error
- func SafeInputPath(path string) (string, error)
- func SafeLocalFlagPath(flagName, value string) (string, error)
- func SafeOutputPath(path string) (string, error)
- func SanitizeForTerminal(text string) string
- func StripQueryFragment(path string) string
- func ValidateDownloadSourceURL(ctx context.Context, rawURL string) error
- type DownloadHTTPClientOptions
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AtomicWrite ¶
AtomicWrite writes data to path atomically by creating a temp file in the same directory, writing and fsyncing the data, then renaming over the target. It replaces os.WriteFile for all config and download file writes.
os.WriteFile truncates the target before writing, so a process kill (CI timeout, OOM, Ctrl+C) between truncate and completion leaves the file empty or partial. AtomicWrite avoids this: on any failure the temp file is cleaned up and the original file remains untouched.
func AtomicWriteFromReader ¶
AtomicWriteFromReader atomically copies reader contents into path.
func EncodePathSegment ¶
EncodePathSegment percent-encodes user input for safe use as a single URL path segment (e.g. / → %2F, ? → %3F, # → %23), ensuring the value cannot alter the URL routing structure when interpolated into an API path.
This provides defense-in-depth alongside ResourceName: ResourceName rejects known dangerous patterns at the input layer, while EncodePathSegment acts as a fallback at the concatenation layer — if ResourceName rules are relaxed in the future, or if an API path bypasses ResourceName validation (e.g. cmd/service/ generic calls), encoding still prevents special characters from being interpreted as path separators or query parameters.
Convention: all user-provided variables in fmt.Sprintf API paths within shortcuts/ MUST be wrapped with this function.
func NewDownloadHTTPClient ¶
func NewDownloadHTTPClient(base *http.Client, opts DownloadHTTPClientOptions) *http.Client
NewDownloadHTTPClient clones base client and enforces download-safe redirect and connection rules for untrusted URLs.
func RejectCRLF ¶
RejectCRLF rejects strings containing carriage return (\r) or line feed (\n). These characters enable MIME/HTTP header injection and must never appear in header field names, values, Content-ID, or filename parameters.
func RejectControlChars ¶
RejectControlChars rejects C0 control characters (except \t and \n) and dangerous Unicode characters from user input.
Control characters cause subtle security issues: null bytes truncate strings at the C layer, \r\n enables HTTP header injection Unicode characters allow visual spoofing (e.g. making "report.exe" display as "report.txt").
func ResourceName ¶
ResourceName validates an API resource identifier (messageId, fileToken, etc.) before it is interpolated into a URL path via fmt.Sprintf. It rejects path traversal (..), URL metacharacters (?#%), percent-encoded bypasses (%2e%2e), control characters, and dangerous Unicode.
Without this check, an input like "../admin" or "?evil=true" in a message ID would alter the API endpoint the request is sent to. Works alongside EncodePathSegment for defense-in-depth.
func SafeInputPath ¶
SafeInputPath validates an upload/read source path for --file flags. It applies the same rules as SafeOutputPath — rejecting absolute paths, resolving symlinks, and enforcing working directory containment — to prevent an AI Agent from being tricked into reading sensitive files like /etc/passwd.
func SafeLocalFlagPath ¶
SafeLocalFlagPath validates a flag value as a local file path. Empty values and http/https URLs are returned unchanged without validation, allowing the caller to handle non-path inputs (e.g. API keys, URLs) upstream. For all other values, SafeInputPath rules apply. The original relative path is returned unchanged (not resolved to absolute) so upload helpers can re-validate at the actual I/O point via SafeUploadPath.
func SafeOutputPath ¶
SafeOutputPath validates a download/export target path for --output flags. It rejects absolute paths, resolves symlinks to their real location, and verifies the canonical result is still under the current working directory. This prevents an AI Agent from being tricked into writing files outside the working directory (e.g. "../../.ssh/authorized_keys") or following symlinks to sensitive locations.
The returned absolute path MUST be used for all subsequent I/O to prevent time-of-check-to-time-of-use (TOCTOU) race conditions.
func SanitizeForTerminal ¶
SanitizeForTerminal strips ANSI escape sequences, C0 control characters (except \n and \t), and dangerous Unicode from text, preserving the actual readable content. It should be applied to table format output and stderr messages, but NOT to json/ndjson output where programmatic consumers need the raw data.
API responses may contain injected ANSI sequences that clear the screen, fake a colored "OK" status, or change the terminal title. In AI Agent scenarios, such injections can also pollute the LLM's context window with misleading output.
func StripQueryFragment ¶
StripQueryFragment removes any ?query or #fragment suffix from a URL path. API parameters must go through structured --params flags, not embedded in the path, to prevent parameter injection and behaviour confusion.
Types ¶
type DownloadHTTPClientOptions ¶
type DownloadHTTPClientOptions struct {
// AllowHTTP controls whether plain HTTP URLs are permitted.
// If false, any HTTP URL (initial or redirect target) is rejected.
AllowHTTP bool
// MaxRedirects limits follow-up redirects. Zero or negative uses default.
MaxRedirects int
}
DownloadHTTPClientOptions controls redirect and scheme behavior for untrusted-source downloads.