Files
Charon/backend/internal/util/sanitize.go
akanealw eec8c28fb3
Some checks failed
Go Benchmark / Performance Regression Check (push) Has been cancelled
Cerberus Integration / Cerberus Security Stack Integration (push) Has been cancelled
Upload Coverage to Codecov / Backend Codecov Upload (push) Has been cancelled
Upload Coverage to Codecov / Frontend Codecov Upload (push) Has been cancelled
CodeQL - Analyze / CodeQL analysis (go) (push) Has been cancelled
CodeQL - Analyze / CodeQL analysis (javascript-typescript) (push) Has been cancelled
CrowdSec Integration / CrowdSec Bouncer Integration (push) Has been cancelled
Docker Build, Publish & Test / build-and-push (push) Has been cancelled
Quality Checks / Auth Route Protection Contract (push) Has been cancelled
Quality Checks / Codecov Trigger/Comment Parity Guard (push) Has been cancelled
Quality Checks / Backend (Go) (push) Has been cancelled
Quality Checks / Frontend (React) (push) Has been cancelled
Rate Limit integration / Rate Limiting Integration (push) Has been cancelled
Security Scan (PR) / Trivy Binary Scan (push) Has been cancelled
Supply Chain Verification (PR) / Verify Supply Chain (push) Has been cancelled
WAF integration / Coraza WAF Integration (push) Has been cancelled
Docker Build, Publish & Test / Security Scan PR Image (push) Has been cancelled
Repo Health Check / Repo health (push) Has been cancelled
History Rewrite Dry-Run / Dry-run preview for history rewrite (push) Has been cancelled
Prune Renovate Branches / prune (push) Has been cancelled
Renovate / renovate (push) Has been cancelled
Nightly Build & Package / sync-development-to-nightly (push) Has been cancelled
Nightly Build & Package / Trigger Nightly Validation Workflows (push) Has been cancelled
Nightly Build & Package / build-and-push-nightly (push) Has been cancelled
Nightly Build & Package / test-nightly-image (push) Has been cancelled
Nightly Build & Package / verify-nightly-supply-chain (push) Has been cancelled
Update GeoLite2 Checksum / update-checksum (push) Has been cancelled
Container Registry Prune / prune-ghcr (push) Has been cancelled
Container Registry Prune / prune-dockerhub (push) Has been cancelled
Container Registry Prune / summarize (push) Has been cancelled
Supply Chain Verification / Verify SBOM (push) Has been cancelled
Supply Chain Verification / Verify Release Artifacts (push) Has been cancelled
Supply Chain Verification / Verify Docker Image Supply Chain (push) Has been cancelled
Monitor Caddy Major Release / check-caddy-major (push) Has been cancelled
Weekly Nightly to Main Promotion / Verify Nightly Branch Health (push) Has been cancelled
Weekly Nightly to Main Promotion / Create Promotion PR (push) Has been cancelled
Weekly Nightly to Main Promotion / Trigger Missing Required Checks (push) Has been cancelled
Weekly Nightly to Main Promotion / Notify on Failure (push) Has been cancelled
Weekly Nightly to Main Promotion / Workflow Summary (push) Has been cancelled
Weekly Security Rebuild / Security Rebuild & Scan (push) Has been cancelled
changed perms
2026-04-22 18:19:14 +00:00

58 lines
1.5 KiB
Go
Executable File

// Package util provides utility functions used across the application.
package util
import (
"net"
"regexp"
"strings"
)
// SanitizeForLog removes control characters and newlines from user content before logging.
func SanitizeForLog(s string) string {
if s == "" {
return s
}
s = strings.ReplaceAll(s, "\r\n", " ")
s = strings.ReplaceAll(s, "\n", " ")
re := regexp.MustCompile(`[\x00-\x1F\x7F]+`)
s = re.ReplaceAllString(s, " ")
return s
}
// CanonicalizeIPForSecurity normalizes an IP string for security decisions
// (rate limiting keys, allow-list CIDR checks, etc.). It preserves Gin's
// trust proxy behavior by operating on the already-resolved client IP string.
//
// Normalizations:
// - IPv6 loopback (::1) -> 127.0.0.1 (stable across IPv4/IPv6 localhost)
// - IPv4-mapped IPv6 (e.g. ::ffff:127.0.0.1) -> 127.0.0.1
func CanonicalizeIPForSecurity(ipStr string) string {
ipStr = strings.TrimSpace(ipStr)
if ipStr == "" {
return ipStr
}
// Defensive normalization in case the input is not a plain IP string.
// Gin's Context.ClientIP() should return an IP, but in proxy/test setups
// we may still see host:port or comma-separated values.
if idx := strings.IndexByte(ipStr, ','); idx >= 0 {
ipStr = strings.TrimSpace(ipStr[:idx])
}
if host, _, err := net.SplitHostPort(ipStr); err == nil {
ipStr = host
}
ipStr = strings.Trim(ipStr, "[]")
ip := net.ParseIP(ipStr)
if ip == nil {
return ipStr
}
if v4 := ip.To4(); v4 != nil {
return v4.String()
}
if ip.IsLoopback() {
return "127.0.0.1"
}
return ip.String()
}