Add SIP message validation feature

Implements RFC 3261 compliance checking and security validation:

- Three validation modes: permissive (default), strict, paranoid
- Critical checks: null bytes, binary injection (immediate ban)
- RFC compliance: required headers (Via, From, To, Call-ID, CSeq, Max-Forwards)
- Format validation: CSeq range, Content-Length, Via branch format
- Paranoid mode: SQL injection patterns, excessive headers, long values
- Compact header form support (v, f, t, i, l, etc.)

Caddyfile configuration:
  validation {
      enabled true
      mode permissive
      max_message_size 65535
      ban_on_null_bytes true
      ban_on_binary_injection true
      disabled_rules via_invalid_branch
  }

New Prometheus metrics:
- sip_guardian_validation_violations_total{rule}
- sip_guardian_validation_results_total{result}
- sip_guardian_message_size_bytes (histogram)

Includes comprehensive unit tests covering all validation scenarios.
This commit is contained in:
Ryan Malloy 2025-12-07 15:57:26 -07:00
parent 95a794ba69
commit 976fdf53a5
5 changed files with 1485 additions and 1 deletions

View file

@ -121,6 +121,34 @@ var (
Buckets: []float64{5, 10, 15, 20, 30, 50, 100},
},
)
// Validation metrics
sipValidationViolations = prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: "sip_guardian",
Name: "validation_violations_total",
Help: "Total validation violations detected by rule",
},
[]string{"rule"}, // "null_bytes", "binary_injection", "missing_via", etc.
)
sipValidationResults = prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: "sip_guardian",
Name: "validation_results_total",
Help: "Total validation results by outcome",
},
[]string{"result"}, // "valid", "invalid", "ban"
)
sipMessageSizeBytes = prometheus.NewHistogram(
prometheus.HistogramOpts{
Namespace: "sip_guardian",
Name: "message_size_bytes",
Help: "Distribution of SIP message sizes in bytes",
Buckets: []float64{100, 500, 1000, 2000, 5000, 10000, 20000, 50000, 65535},
},
)
)
// metricsRegistered tracks if we've registered with Prometheus
@ -146,6 +174,9 @@ func RegisterMetrics() {
sipEnumerationDetections,
sipEnumerationTrackedIPs,
sipEnumerationUniqueExtensions,
sipValidationViolations,
sipValidationResults,
sipMessageSizeBytes,
)
}
@ -213,6 +244,21 @@ func RecordEnumerationExtensions(count int) {
sipEnumerationUniqueExtensions.Observe(float64(count))
}
// RecordValidationViolation records a validation violation by rule name
func RecordValidationViolation(rule string) {
sipValidationViolations.WithLabelValues(rule).Inc()
}
// RecordValidationResult records a validation result (valid, invalid, ban)
func RecordValidationResult(result string) {
sipValidationResults.WithLabelValues(result).Inc()
}
// RecordMessageSize records the size of a SIP message in bytes
func RecordMessageSize(bytes int) {
sipMessageSizeBytes.Observe(float64(bytes))
}
// MetricsHandler provides a Prometheus metrics endpoint for SIP Guardian
type MetricsHandler struct {
// Path prefix for metrics (default: /metrics)