Implement comprehensive input validation security controls following OWASP best practices. Validates data at syntactic and semantic levels, implements allowlisting over denylisting, handles Unicode text safely, and prevents common injection attacks through proper input sanitization.
This skill guides you through implementing comprehensive input validation security controls following OWASP best practices for web applications.
Input validation ensures only properly formed data enters your application workflow, preventing malformed data from persisting in databases and triggering downstream component malfunctions. This skill implements defense-in-depth validation at both syntactic and semantic levels.
First, identify all application input points that require validation:
1. Use code search to find all HTTP request parameter handling (e.g., `request.getParameter()`, `req.body`, `$_POST`, etc.)
2. Identify API endpoints that accept external data
3. Locate file upload handlers
4. Find database query construction points
5. Document each input point with its expected data type and format
**CRITICAL: Use allowlisting, NOT denylisting**
For each input point, define exactly what IS authorized:
**For structured data (dates, SSNs, zip codes, emails):**
**For fixed sets (dropdowns, radio buttons):**
**For free-form Unicode text:**
Implement validation using these techniques:
**Native framework validators:**
```java
// Example: Using framework validators
@NotNull
@Size(min=5, max=9)
@Pattern(regexp="^\\d{5}(-\\d{4})?$")
private String zipCode;
```
**Type conversion with strict exception handling:**
```python
try:
age = int(user_input)
if not (0 <= age <= 150):
raise ValueError("Age out of valid range")
except ValueError:
return error_response("Invalid age format")
```
**Regular expressions for structured data:**
```java
private static final Pattern zipPattern = Pattern.compile("^\\d{5}(-\\d{4})?$");
public void validateZipCode(String zipCode) {
if (!zipPattern.matcher(zipCode).matches()) {
throw new ValidationException("Improper zipcode format");
}
}
```
**Range validation:**
```javascript
function validateAge(age) {
const numAge = parseInt(age, 10);
if (isNaN(numAge) || numAge < 0 || numAge > 150) {
throw new Error('Invalid age');
}
return numAge;
}
```
For file uploads, implement multi-layer validation:
**Upload verification:**
1. Check file extension against allowlist (not denylist)
2. Verify MIME type from Content-Type header
3. Validate file content matches declared type (magic number verification)
4. Enforce file size limits
5. Scan with antivirus if available
**Upload storage:**
1. Store files outside web root
2. Rename files to prevent path traversal (use generated names, not user-supplied)
3. Store original filename separately in database if needed
4. Set restrictive file permissions
**Example implementation:**
```python
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
MAX_FILE_SIZE = 5 * 1024 * 1024 # 5MB
def validate_upload(file):
# Check extension
ext = file.filename.rsplit('.', 1)[1].lower()
if ext not in ALLOWED_EXTENSIONS:
raise ValidationError("Invalid file type")
# Check size
file.seek(0, 2) # Seek to end
size = file.tell()
file.seek(0) # Reset
if size > MAX_FILE_SIZE:
raise ValidationError("File too large")
# Verify magic numbers (example for images)
header = file.read(12)
file.seek(0)
if not is_valid_image_header(header):
raise ValidationError("Invalid file content")
```
**Syntactic validation:**
**Semantic validation:**
**CRITICAL: Never rely solely on client-side validation**
1. Implement all validation logic on the server-side
2. Treat client-side validation as UX enhancement only
3. Assume all client-side checks can be bypassed
4. Process data only after server-side validation passes
When writing regular expressions:
1. Avoid nested quantifiers (e.g., `(a+)+`, `(a*)*`)
2. Avoid alternation with overlapping patterns (e.g., `(a|a)*`)
3. Test regex performance with long inputs
4. Set timeouts for regex operations
5. Use tools like https://devina.io/redos-checker to test patterns
Beyond format validation, check business logic constraints:
```java
public void validateDateRange(Date startDate, Date endDate) {
if (startDate.after(endDate)) {
throw new ValidationException("Start date must be before end date");
}
}
public void validatePrice(BigDecimal price) {
if (price.compareTo(MIN_PRICE) < 0 || price.compareTo(MAX_PRICE) > 0) {
throw new ValidationException("Price outside acceptable range");
}
}
```
Log validation failures for security monitoring:
```java
if (!isValid(input)) {
logger.warn("Validation failure: field={}, value={}, ip={}",
fieldName, sanitizeForLog(input), request.getRemoteAddr());
// High severity for fixed-set violations (potential tampering)
if (isFixedSetViolation(input)) {
logger.error("SECURITY: Possible tampering detected - field={}, ip={}",
fieldName, request.getRemoteAddr());
}
throw new ValidationException("Invalid input");
}
```
Write comprehensive tests:
1. Valid input test cases
2. Boundary value tests (min/max lengths, ranges)
3. Invalid format tests
4. Injection attempt tests (SQLi, XSS payloads)
5. Unicode and special character tests
6. Empty/null input tests
7. ReDoS attack pattern tests
**US State codes:**
```regex
^(AA|AE|AP|AL|AK|AS|AZ|AR|CA|CO|CT|DE|DC|FM|FL|GA|GU|HI|ID|IL|IN|IA|KS|KY|LA|ME|MH|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|MP|OH|OK|OR|PW|PA|PR|RI|SC|SD|TN|TX|UT|VT|VI|VA|WA|WV|WI|WY)$
```
**US Zip code:**
```regex
^\d{5}(-\d{4})?$
```
**Alphanumeric with length constraints:**
```regex
^[a-zA-Z0-9]{1,25}$
```
**Date (YYYY-MM-DD):**
```regex
^\d{4}-\d{2}-\d{2}$
```
After implementing this skill, you should have:
1. Comprehensive input validation for all untrusted data sources
2. Allowlist-based validation patterns for all structured input
3. Server-side validation for all input points
4. Secure file upload handling with multi-layer verification
5. Proper Unicode text validation with normalization
6. Semantic validation for business logic constraints
7. Security logging for validation failures
8. Test suite covering valid, invalid, and attack scenarios
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/owasp-input-validation-security/raw