# MEDIUM-002: Input Validation Strengthening - Detailed Fix Plan **Issue ID:** MEDIUM-002 **Category:** Security **Priority:** Medium **Status:** Not Started **Generated:** October 9, 2025 **Estimate:** 4-5 hours ## Overview This plan strengthens input validation throughout the codebase to prevent injection attacks, buffer overflows, and other security vulnerabilities. The focus is on enhancing ABI decoding validation, implementing comprehensive bounds checking, and creating robust input sanitization. ## Current Implementation Issues - Insufficient validation in ABI decoding and parsing modules - Missing bounds checking for external data - Potential for injection attacks through unvalidated inputs - Lack of comprehensive input sanitization for log messages ## Implementation Tasks ### 1. Enhance ABI Decoding Validation Throughout Parsing Modules **Task ID:** MEDIUM-002.1 **Time Estimate:** 1.5 hours **Dependencies:** None Strengthen ABI decoding validation with comprehensive checks: - Validate function signatures against known function selectors - Check input parameter types match expected schema - Validate length of dynamic parameters - Implement bounds checking for array parameters - Add strict validation of encoded data ```go type ABIValidator struct { knownFunctions map[string]bool maxLengths map[string]int // max length for different types } func (av *ABIValidator) ValidateFunctionCall(encodedData []byte) error { if len(encodedData) < 4 { return fmt.Errorf("encoded data too short for function selector") } // Extract function selector (first 4 bytes) selector := hex.EncodeToString(encodedData[:4]) // Validate function selector against known functions if !av.knownFunctions[selector] { return fmt.Errorf("unknown function selector: %s", selector) } // Validate remaining data length if len(encodedData) < 36 { // minimum for one parameter return fmt.Errorf("insufficient data for expected parameters") } return nil } func (av *ABIValidator) ValidateParameter(param interface{}, paramType string) error { switch paramType { case "address": if addr, ok := param.(common.Address); ok { if addr == (common.Address{}) { return fmt.Errorf("invalid empty address") } } else { return fmt.Errorf("invalid address type") } case "uint256": if val, ok := param.(*big.Int); ok { if val.Sign() < 0 { return fmt.Errorf("negative value for unsigned type") } // Check for maximum allowed value to prevent overflow maxVal := new(big.Int).Lsh(big.NewInt(1), 256) maxVal.Sub(maxVal, big.NewInt(1)) if val.Cmp(maxVal) > 0 { return fmt.Errorf("value exceeds uint256 maximum") } } else { return fmt.Errorf("invalid uint256 type") } case "string", "bytes": if str, ok := param.(string); ok { if len(str) > av.maxLengths["string"] { return fmt.Errorf("string parameter exceeds maximum length of %d", av.maxLengths["string"]) } } else { return fmt.Errorf("invalid string/bytes type") } } return nil } ``` ### 2. Add Comprehensive Bounds Checking for External Data **Task ID:** MEDIUM-002.2 **Time Estimate:** 1.5 hours **Dependencies:** MEDIUM-002.1 Implement bounds checking for all external data inputs: - Validate array lengths before processing - Check string lengths against maximum allowed values - Verify numeric ranges for expected parameters - Implement size limits for contract data - Add validation for transaction parameters ```go type BoundsChecker struct { maxArrayLength int maxStringLength int maxTransactionGas uint64 maxBlockNumber *big.Int } func (bc *BoundsChecker) ValidateArrayBounds(data interface{}) error { switch v := data.(type) { case []interface{}: if len(v) > bc.maxArrayLength { return fmt.Errorf("array length %d exceeds maximum allowed %d", len(v), bc.maxArrayLength) } case []byte: if len(v) > bc.maxArrayLength { return fmt.Errorf("byte array length %d exceeds maximum allowed %d", len(v), bc.maxArrayLength) } } return nil } func (bc *BoundsChecker) ValidateTransactionLimits(tx *types.Transaction) error { // Validate gas limit if tx.Gas() > bc.maxTransactionGas { return fmt.Errorf("gas limit %d exceeds maximum allowed %d", tx.Gas(), bc.maxTransactionGas) } // Validate gas price is reasonable gasPrice := tx.GasPrice() if gasPrice != nil && gasPrice.Cmp(big.NewInt(100000000000)) > 0 { // 100 gwei return fmt.Errorf("gas price %s exceeds reasonable maximum", gasPrice.String()) } // Validate value is not excessive value := tx.Value() maxEth := new(big.Int).Exp(big.NewInt(10), big.NewInt(21), nil) // 1000 ETH in wei if value != nil && value.Cmp(maxEth) > 0 { return fmt.Errorf("transaction value %s exceeds reasonable maximum", value.String()) } return nil } ``` ### 3. Implement Input Sanitization for Log Messages **Task ID:** MEDIUM-002.3 **Time Estimate:** 0.5 hours **Dependencies:** MEDIUM-002.1 Add sanitization for potentially unsafe data in log messages: - Sanitize addresses, private keys, and other sensitive data - Remove or mask potentially harmful content - Implement safe logging functions - Prevent log injection attacks ```go func SanitizeForLog(data string) string { // Remove or replace potentially harmful characters // Replace newlines to prevent log injection data = strings.ReplaceAll(data, "\n", "\\n") data = strings.ReplaceAll(data, "\r", "\\r") // Mask potential addresses or private keys // This is a simplified example - consider using regex for more sophisticated masking re := regexp.MustCompile(`0x[a-fA-F0-9]{40}|0x[a-fA-F0-9]{64}`) data = re.ReplaceAllStringFunc(data, func(match string) string { if len(match) == 42 { // Ethereum address return "0x" + match[2:6] + "..." + match[len(match)-4:] // Mask middle } else if len(match) == 66 { // Private key return "0x" + match[2:6] + "..." + match[len(match)-4:] // Mask middle } return match }) return data } // Safe structured logging function func SafeLog(l *Logger, level string, msg string, keyvals ...interface{}) { safeKeyvals := make([]interface{}, len(keyvals)) for i := 0; i < len(keyvals); i++ { if i%2 == 0 { // Key is even-indexed, expect string safeKeyvals[i] = keyvals[i] } else { // Value at odd index, sanitize if string if str, ok := keyvals[i].(string); ok { safeKeyvals[i] = SanitizeForLog(str) } else { safeKeyvals[i] = keyvals[i] } } } l.Log(level, msg, safeKeyvals...) } ``` ### 4. Create Fuzzing Test Suite for All Input Validation Functions **Task ID:** MEDIUM-002.4 **Time Estimate:** 1 hour **Dependencies:** MEDIUM-002.1, MEDIUM-002.2, MEDIUM-002.3 Develop comprehensive fuzzing tests for all input validation functions: - Fuzz ABI decoding functions with random inputs - Test bounds checking with extreme values - Validate sanitization functions against malicious inputs - Implement property-based tests for validation logic ```go func FuzzABIValidation(f *testing.F) { // Add interesting seeds for ABI validation f.Add([]byte{0x00, 0x00, 0x00, 0x00}) // Invalid function selector f.Add([]byte{0x12, 0x34, 0x56, 0x78}) // Random function selector f.Add([]byte{0x60, 0xFE, 0xED, 0xDE}) // Common function selector prefix f.Fuzz(func(t *testing.T, data []byte) { // Test that validation doesn't panic with random data validator := NewABIValidator() _ = validator.ValidateFunctionCall(data) }) } func FuzzSanitization(f *testing.F) { f.Add("normal string") f.Add("string\nwith\nnewlines") f.Add("0x1234567890123456789012345678901234567890") // Address format f.Add("0x1234567890123456789012345678901234567890123456789012345678901234") // Key format f.Fuzz(func(t *testing.T, input string) { // Test that sanitization doesn't panic result := SanitizeForLog(input) // Validate that result doesn't contain dangerous characters if strings.Contains(result, "\n") || strings.Contains(result, "\r") { t.Errorf("Sanitization failed to remove newlines from: %s", input) } }) } ``` ### 5. Implement Centralized Validation Framework **Task ID:** MEDIUM-002.5 **Time Estimate:** 0.5 hours **Dependencies:** MEDIUM-002.1, MEDIUM-002.2, MEDIUM-002.3 Create a centralized validation framework for consistent input validation: - Standardized validation interface - Reusable validation functions - Consistent error handling - Configuration for validation parameters ```go type Validator interface { Validate(data interface{}) error Sanitize(data interface{}) (interface{}, error) } type ValidatorChain struct { validators []Validator } func (vc *ValidatorChain) Validate(data interface{}) error { for _, v := range vc.validators { if err := v.Validate(data); err != nil { return fmt.Errorf("validation failed with validator %T: %w", v, err) } } return nil } // Usage example func ValidateTransactionInput(txData map[string]interface{}) error { validator := &ValidatorChain{ validators: []Validator{ &ABIValidator{}, &BoundsChecker{ maxArrayLength: 100, maxStringLength: 10000, }, &Sanitizer{}, }, } return validator.Validate(txData) } ``` ## Implementation Details ### Security Focus Areas - ABI decoding validation prevents malicious contract interactions - Bounds checking prevents buffer overflows and resource exhaustion - Log sanitization prevents log injection attacks - Comprehensive input validation prevents injection attacks ### Performance Considerations - Validation should have minimal performance impact - Caching for frequently validated patterns - Asynchronous validation for non-critical paths ## Testing Strategy - Unit tests for each validation function - Integration tests with real contract data - Fuzzing tests for robustness - Property-based testing for validation logic - Negative tests with malicious inputs ## Code Review Checklist - [ ] All external inputs are validated before processing - [ ] Bounds checking implemented for arrays and strings - [ ] ABI decoding validation prevents malicious inputs - [ ] Log sanitization prevents injection attacks - [ ] Fuzzing tests implemented for all validation functions - [ ] Error handling is consistent and informative - [ ] Performance impact is measured and acceptable ## Rollback Strategy If issues arise after deployment: 1. Temporarily disable enhanced validation 2. Revert to basic validation mechanisms 3. Monitor for any processing failures ## Success Metrics - Zero successful injection attacks through validated inputs - All input validation tests pass consistently - No performance degradation beyond acceptable thresholds - Proper error handling for all validation failures - Successful detection of malicious inputs