fix: sanitize user input for log injection protection in ProxyHostHandler
This commit is contained in:
15
.github/codeql-custom-model.yml
vendored
15
.github/codeql-custom-model.yml
vendored
@@ -42,3 +42,18 @@ extensions:
|
||||
# TestURLConnectivity validates URLs internally via security.ValidateExternalURL
|
||||
# and ssrfSafeDialer - it's a terminating function, not a pass-through
|
||||
- ["github.com/Wikid82/charon/backend/internal/utils", "TestURLConnectivity", "manual"]
|
||||
|
||||
# Mark log sanitization functions as sanitizers for log injection (CWE-117)
|
||||
# These functions remove newlines and control characters from user input before logging
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
# util.SanitizeForLog sanitizes strings by:
|
||||
# 1. Replacing \r\n and \n with spaces
|
||||
# 2. Removing all control characters [\x00-\x1F\x7F]
|
||||
# Input: Argument[0] (unsanitized string)
|
||||
# Output: ReturnValue[0] (sanitized string - safe for logging)
|
||||
- ["github.com/Wikid82/charon/backend/internal/util", "SanitizeForLog", "Argument[0]", "ReturnValue[0]", "taint", "manual"]
|
||||
# handlers.sanitizeForLog is a local sanitizer with same behavior
|
||||
- ["github.com/Wikid82/charon/backend/internal/api/handlers", "sanitizeForLog", "Argument[0]", "ReturnValue[0]", "taint", "manual"]
|
||||
|
||||
@@ -332,44 +332,46 @@ func (h *ProxyHostHandler) Update(c *gin.Context) {
|
||||
// Security Header Profile: update only if provided
|
||||
if v, ok := payload["security_header_profile_id"]; ok {
|
||||
logger := middleware.GetRequestLogger(c)
|
||||
logger.WithField("host_uuid", uuidStr).WithField("raw_value", v).Debug("Processing security_header_profile_id update")
|
||||
// Sanitize user-provided values for log injection protection (CWE-117)
|
||||
safeUUID := sanitizeForLog(uuidStr)
|
||||
logger.WithField("host_uuid", safeUUID).WithField("raw_value", fmt.Sprintf("%v", v)).Debug("Processing security_header_profile_id update")
|
||||
|
||||
if v == nil {
|
||||
logger.WithField("host_uuid", uuidStr).Debug("Setting security_header_profile_id to nil")
|
||||
logger.WithField("host_uuid", safeUUID).Debug("Setting security_header_profile_id to nil")
|
||||
host.SecurityHeaderProfileID = nil
|
||||
} else {
|
||||
conversionSuccess := false
|
||||
switch t := v.(type) {
|
||||
case float64:
|
||||
logger.WithField("host_uuid", uuidStr).WithField("type", "float64").WithField("value", t).Debug("Received security_header_profile_id as float64")
|
||||
logger.WithField("host_uuid", safeUUID).WithField("type", "float64").WithField("value", t).Debug("Received security_header_profile_id as float64")
|
||||
if id, ok := safeFloat64ToUint(t); ok {
|
||||
host.SecurityHeaderProfileID = &id
|
||||
conversionSuccess = true
|
||||
logger.WithField("host_uuid", uuidStr).WithField("profile_id", id).Info("Successfully converted security_header_profile_id from float64")
|
||||
logger.WithField("host_uuid", safeUUID).WithField("profile_id", id).Info("Successfully converted security_header_profile_id from float64")
|
||||
} else {
|
||||
logger.WithField("host_uuid", uuidStr).WithField("value", t).Warn("Failed to convert security_header_profile_id from float64: value is negative or not a valid uint")
|
||||
logger.WithField("host_uuid", safeUUID).WithField("value", t).Warn("Failed to convert security_header_profile_id from float64: value is negative or not a valid uint")
|
||||
}
|
||||
case int:
|
||||
logger.WithField("host_uuid", uuidStr).WithField("type", "int").WithField("value", t).Debug("Received security_header_profile_id as int")
|
||||
logger.WithField("host_uuid", safeUUID).WithField("type", "int").WithField("value", t).Debug("Received security_header_profile_id as int")
|
||||
if id, ok := safeIntToUint(t); ok {
|
||||
host.SecurityHeaderProfileID = &id
|
||||
conversionSuccess = true
|
||||
logger.WithField("host_uuid", uuidStr).WithField("profile_id", id).Info("Successfully converted security_header_profile_id from int")
|
||||
logger.WithField("host_uuid", safeUUID).WithField("profile_id", id).Info("Successfully converted security_header_profile_id from int")
|
||||
} else {
|
||||
logger.WithField("host_uuid", uuidStr).WithField("value", t).Warn("Failed to convert security_header_profile_id from int: value is negative")
|
||||
logger.WithField("host_uuid", safeUUID).WithField("value", t).Warn("Failed to convert security_header_profile_id from int: value is negative")
|
||||
}
|
||||
case string:
|
||||
logger.WithField("host_uuid", uuidStr).WithField("type", "string").WithField("value", t).Debug("Received security_header_profile_id as string")
|
||||
logger.WithField("host_uuid", safeUUID).WithField("type", "string").WithField("value", sanitizeForLog(t)).Debug("Received security_header_profile_id as string")
|
||||
if n, err := strconv.ParseUint(t, 10, 32); err == nil {
|
||||
id := uint(n)
|
||||
host.SecurityHeaderProfileID = &id
|
||||
conversionSuccess = true
|
||||
logger.WithField("host_uuid", uuidStr).WithField("profile_id", id).Info("Successfully converted security_header_profile_id from string")
|
||||
logger.WithField("host_uuid", safeUUID).WithField("profile_id", id).Info("Successfully converted security_header_profile_id from string")
|
||||
} else {
|
||||
logger.WithField("host_uuid", uuidStr).WithField("value", t).WithError(err).Warn("Failed to parse security_header_profile_id from string")
|
||||
logger.WithField("host_uuid", safeUUID).WithField("value", sanitizeForLog(t)).WithError(err).Warn("Failed to parse security_header_profile_id from string")
|
||||
}
|
||||
default:
|
||||
logger.WithField("host_uuid", uuidStr).WithField("type", fmt.Sprintf("%T", v)).WithField("value", v).Warn("Unsupported type for security_header_profile_id")
|
||||
logger.WithField("host_uuid", safeUUID).WithField("type", fmt.Sprintf("%T", v)).WithField("value", fmt.Sprintf("%v", v)).Warn("Unsupported type for security_header_profile_id")
|
||||
}
|
||||
|
||||
if !conversionSuccess {
|
||||
|
||||
Reference in New Issue
Block a user