Skip to content

Fix request handling and add tests#51

Merged
devploit merged 1 commit intomainfrom
devploit/review-project
Feb 5, 2026
Merged

Fix request handling and add tests#51
devploit merged 1 commit intomainfrom
devploit/review-project

Conversation

@devploit
Copy link
Owner

@devploit devploit commented Feb 5, 2026

Changes

  • Fix stdin processing and autocalibration baseline handling.
  • Remove header data races and improve header parsing.
  • Correct timeouts (ms), validate URLs, and trim payload lines.
  • Safer midpath URL building; use full proxy URL for curl.
  • Align license header and README link.
  • Add unit tests for joinURL, parseFile, and header parsing.

Testing

  • go test ./...

if len(options.reqHeaders) > 0 && len(options.reqHeaders[0]) != 0 {
for _, header := range options.headers {
fmt.Printf("%s \t\t%s\n", "Headers:", header)
fmt.Printf("%s \t\t%s: %s\n", "Headers:", header.key, header.value)

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

Sensitive data returned by HTTP request headers
flows to a logging call.

Copilot Autofix

AI about 1 month ago

To fix the problem, the code should avoid printing potentially sensitive header values in clear text. The general approaches are: (a) omit sensitive headers entirely from logs, (b) mask/obfuscate their values (e.g., keep only prefix, replace rest with ***), or (c) only log header names. The safest and simplest fix that preserves functionality is to keep visibility of which headers are being used while redacting their values when printing configuration.

Concretely, we can change showInfo in cmd/requester.go so that it does not print header.value directly. A good balance is to log header names and a masked version of their values, and to treat well-known sensitive headers (e.g., Authorization, Cookie, Set-Cookie, X-Api-Key, X-API-KEY, Proxy-Authorization) as always fully redacted. For all headers, we can implement a small helper like maskHeaderValue that returns "***" or a partially masked string. This helper will be added in cmd/requester.go just above showInfo, and showInfo’s loop will be updated to call it instead of printing the raw header.value. No behavior outside logging output is changed, and no new external dependencies are needed.

Specifically:

  • In cmd/requester.go, define a helper function such as:
func maskHeaderValue(name, value string) string {
    // normalize name
    lower := strings.ToLower(strings.TrimSpace(name))
    switch lower {
    case "authorization", "proxy-authorization", "cookie", "set-cookie", "x-api-key", "x-api-key", "x-auth-token":
        return "***"
    }
    if len(value) <= 4 {
        return "***"
    }
    return value[:2] + "..." + "***"
}

(adjusted to the project’s style).

  • Modify the loop in showInfo from printing %s: %s with header.value to using maskHeaderValue(header.key, header.value).

This ensures that even if request files contain sensitive headers, they will not be logged in clear text.

Suggested changeset 1
cmd/requester.go

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/cmd/requester.go b/cmd/requester.go
--- a/cmd/requester.go
+++ b/cmd/requester.go
@@ -136,6 +136,23 @@
 	fmt.Printf("%s \t%20s %s\n", code, color.BlueString(resultContentLength), result.line)
 }
 
+// maskHeaderValue obfuscates potentially sensitive header values before logging.
+// It fully redacts well-known sensitive headers and partially masks others.
+func maskHeaderValue(name, value string) string {
+	headerName := strings.ToLower(strings.TrimSpace(name))
+	switch headerName {
+	case "authorization", "proxy-authorization", "cookie", "set-cookie", "x-api-key", "x-api-key", "x-auth-token":
+		return "***"
+	}
+	// For non-explicitly sensitive headers, avoid logging the full value.
+	trimmed := strings.TrimSpace(value)
+	if len(trimmed) <= 4 {
+		return "***"
+	}
+	// Show only a small prefix and mask the rest.
+	return trimmed[:2] + "...***"
+}
+
 // showInfo prints the configuration options used for the scan.
 func showInfo(options RequestOptions) {
 	var statusCodeStrings []string
@@ -148,7 +165,8 @@
 		fmt.Printf("%s \t\t%s\n", "Target:", options.uri)
 		if len(options.reqHeaders) > 0 && len(options.reqHeaders[0]) != 0 {
 			for _, header := range options.headers {
-				fmt.Printf("%s \t\t%s: %s\n", "Headers:", header.key, header.value)
+				maskedValue := maskHeaderValue(header.key, header.value)
+				fmt.Printf("%s \t\t%s: %s\n", "Headers:", header.key, maskedValue)
 			}
 		} else {
 			fmt.Printf("%s \t\t%s\n", "Headers:", "false")
EOF
@@ -136,6 +136,23 @@
fmt.Printf("%s \t%20s %s\n", code, color.BlueString(resultContentLength), result.line)
}

// maskHeaderValue obfuscates potentially sensitive header values before logging.
// It fully redacts well-known sensitive headers and partially masks others.
func maskHeaderValue(name, value string) string {
headerName := strings.ToLower(strings.TrimSpace(name))
switch headerName {
case "authorization", "proxy-authorization", "cookie", "set-cookie", "x-api-key", "x-api-key", "x-auth-token":
return "***"
}
// For non-explicitly sensitive headers, avoid logging the full value.
trimmed := strings.TrimSpace(value)
if len(trimmed) <= 4 {
return "***"
}
// Show only a small prefix and mask the rest.
return trimmed[:2] + "...***"
}

// showInfo prints the configuration options used for the scan.
func showInfo(options RequestOptions) {
var statusCodeStrings []string
@@ -148,7 +165,8 @@
fmt.Printf("%s \t\t%s\n", "Target:", options.uri)
if len(options.reqHeaders) > 0 && len(options.reqHeaders[0]) != 0 {
for _, header := range options.headers {
fmt.Printf("%s \t\t%s: %s\n", "Headers:", header.key, header.value)
maskedValue := maskHeaderValue(header.key, header.value)
fmt.Printf("%s \t\t%s: %s\n", "Headers:", header.key, maskedValue)
}
} else {
fmt.Printf("%s \t\t%s\n", "Headers:", "false")
Copilot is powered by AI and may make mistakes. Always verify output.
headers = append(headers, header{headerSplit[0], strings.Join(headerSplit[1:], "")})
headerSplit := strings.SplitN(_header, ":", 2)
if len(headerSplit) < 2 {
log.Printf("Invalid header format: %s\n", _header)

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

Sensitive data returned by HTTP request headers
flows to a logging call.

Copilot Autofix

AI about 1 month ago

In general, to fix clear-text logging of sensitive information in this context, avoid logging full header lines (which include both names and values) when they originate from untrusted sources. Instead, log only non-sensitive metadata, such as whether parsing failed and, at most, the header name (without value), or use a redacted version.

In this specific case, the problematic logging is:

if len(headerSplit) < 2 {
    log.Printf("Invalid header format: %s\n", _header)
    continue
}

_header can contain the entire header including its value. To keep functionality unchanged while avoiding leakage:

  1. Parse out what looks like a header name anyway (best-effort split on :), but ignore the value completely for logging.
  2. If a plausible name can be extracted, log only that name; otherwise, log a generic message without including user-controlled content.
  3. Keep the continue so that malformed headers are still skipped.

Concretely, within setupRequestOptions in cmd/requester.go, replace the log line to avoid printing _header, and optionally attempt to log only the trimmed header name if present. No new imports or types are required.


Suggested changeset 1
cmd/requester.go

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/cmd/requester.go b/cmd/requester.go
--- a/cmd/requester.go
+++ b/cmd/requester.go
@@ -879,7 +879,13 @@
 		for _, _header := range reqHeaders {
 			headerSplit := strings.SplitN(_header, ":", 2)
 			if len(headerSplit) < 2 {
-				log.Printf("Invalid header format: %s\n", _header)
+				// Avoid logging potentially sensitive header values; log only the header name when possible.
+				headerName := strings.TrimSpace(headerSplit[0])
+				if headerName != "" {
+					log.Printf("Invalid header format for header name: %s\n", headerName)
+				} else {
+					log.Printf("Invalid header format encountered; header name is empty\n")
+				}
 				continue
 			}
 			headers = append(headers, header{strings.TrimSpace(headerSplit[0]), strings.TrimSpace(headerSplit[1])})
EOF
@@ -879,7 +879,13 @@
for _, _header := range reqHeaders {
headerSplit := strings.SplitN(_header, ":", 2)
if len(headerSplit) < 2 {
log.Printf("Invalid header format: %s\n", _header)
// Avoid logging potentially sensitive header values; log only the header name when possible.
headerName := strings.TrimSpace(headerSplit[0])
if headerName != "" {
log.Printf("Invalid header format for header name: %s\n", headerName)
} else {
log.Printf("Invalid header format encountered; header name is empty\n")
}
continue
}
headers = append(headers, header{strings.TrimSpace(headerSplit[0]), strings.TrimSpace(headerSplit[1])})
Copilot is powered by AI and may make mistakes. Always verify output.
@devploit devploit merged commit df9fdda into main Feb 5, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant