Security Features
Valicomb is designed with security as a core principle. This guide covers the built-in security features and best practices for secure validation.
ReDoS Protection
Section titled “ReDoS Protection”Regular Expression Denial of Service (ReDoS) attacks exploit inefficient regex patterns that cause catastrophic backtracking.
Automatic Protection
Section titled “Automatic Protection”The regex rule includes automatic protection by setting strict execution limits:
use Frostybee\Valicomb\Validator;
$v = new Validator(['field' => 'aaaaaaaaaaaa!']);
// This throws RuntimeException when backtrack limit is exhausted$v->rule('regex', 'field', '/^(a+)+$/');$v->validate(); // RuntimeException: Regex execution failed: Backtrack limit exhaustedThe protection works by:
- Setting
pcre.backtrack_limitandpcre.recursion_limitto 1000 during execution - Throwing a
RuntimeExceptionif limits are exceeded - Restoring original INI settings after execution
Safe Pattern Guidelines
Section titled “Safe Pattern Guidelines”Good patterns:
$v->rule('regex', 'field', '/^[a-zA-Z0-9]+$/'); // Simple character class$v->rule('regex', 'field', '/^\d{3}-\d{4}$/'); // Fixed quantifiers$v->rule('regex', 'field', '/^[A-Z]{2}\d{6}$/'); // Bounded patternsDangerous patterns to avoid:
// Nested quantifiers'/^(a+)+$/''/^(a*)*$/''/^(a+)*$/'
// Overlapping groups'/^(a|aa)+$/'
// Unbounded repetition with alternatives'/^([a-zA-Z]+)*$/'Type Juggling Prevention
Section titled “Type Juggling Prevention”PHP’s type juggling can lead to security vulnerabilities. Valicomb uses strict comparisons throughout.
Strict Equality
Section titled “Strict Equality”All comparisons use === to prevent type juggling:
$v = new Validator([ 'field1' => '0e123456', // "Scientific notation" string 'field2' => '0e789012']);
// In PHP, these would loosely equal 0 == 0// Valicomb uses strict comparison, so this correctly returns false$v->rule('equals', 'field1', 'field2');Boolean Validation
Section titled “Boolean Validation”The boolean rule accepts only explicit boolean values:
$v = new Validator(['active' => '1']);$v->rule('boolean', 'active'); // true - '1' is accepted
$v = new Validator(['active' => 'yes']);$v->rule('boolean', 'active'); // false - 'yes' is not a boolean
// Use 'accepted' for checkbox-style values$v->rule('accepted', 'terms'); // Accepts 'yes', 'on', 1, '1', trueURL Validation Security
Section titled “URL Validation Security”URL validation includes multiple security checks.
Prefix Validation
Section titled “Prefix Validation”URLs must start with allowed protocols - not just contain them:
// FAIL - protocol not at start (potential redirect attack)$v = new Validator(['url' => 'evil.com?redirect=http://trusted.com']);$v->rule('url', 'url'); // false
// PASS - proper URL with protocol at start$v = new Validator(['url' => 'https://trusted.com']);$v->rule('url', 'url'); // trueAllowed Protocols
Section titled “Allowed Protocols”Only safe protocols are allowed by default:
http://https://ftp://
Dangerous protocols like javascript: and data: are not allowed.
Path Traversal Protection
Section titled “Path Traversal Protection”Language file loading validates against directory traversal attacks using multiple layers of protection:
// Path components are stripped, then validated against whitelistnew Validator([], [], '../../etc/passwd');// Throws: InvalidArgumentException: Invalid language 'passwd'. Allowed: ar, cs, da, ...
new Validator([], [], '../../../evil');// Throws: InvalidArgumentException: Invalid language 'evil'. Allowed: ar, cs, da, ...How It Works
Section titled “How It Works”basename()strips directory traversal attempts (../../etc/passwd→passwd)- Result is validated against a strict whitelist of allowed language codes
realpath()normalizes the language directory path
Allowed Language Codes
Section titled “Allowed Language Codes”Only whitelisted language codes are accepted:
- Allowed:
ar,cs,da,de,en,es,fa,fi,fr,hu,id,it,ja,nl,no,pl,pt,ru,sv,tr,uk,zh - Rejected: Any other value, including path traversal attempts
Email Security
Section titled “Email Security”Email validation includes comprehensive security measures:
RFC 5321 Compliance
Section titled “RFC 5321 Compliance”- Maximum total length: 254 characters
- Maximum local part (before @): 64 characters
- Maximum domain part (after @): 255 characters
Injection Prevention
Section titled “Injection Prevention”Dangerous characters that could be used for injection are rejected:
- Null bytes
- Newlines
- Carriage returns
- Invalid control characters
Example
Section titled “Example”$v = new Validator(['email' => 'user@example.com']);$v->rule('email', 'email');
// These would fail:// - "user\0@example.com" (null byte)// - "user\n@example.com" (newline injection)// - Excessively long emailsInteger Validation Fixes
Section titled “Integer Validation Fixes”The integer validation properly handles all numeric formats:
$v = new Validator(['num' => '1000']);$v->rule('integer', 'num'); // true - works with multi-digit numbers
$v = new Validator(['num' => '1000']);$v->rule('integer', 'num', true); // Strict mode - proper numeric formStrict Mode
Section titled “Strict Mode”Strict mode rejects redundant formatting:
// Strict mode rejects redundant plus sign$v = new Validator(['num' => '+27']);$v->rule('integer', 'num', true); // false
// Negative numbers are accepted$v = new Validator(['num' => '-27']);$v->rule('integer', 'num', true); // trueHigh-Precision Comparisons
Section titled “High-Precision Comparisons”When BCMath is available, numeric comparisons use high-precision arithmetic:
// With BCMath, this comparison is precise$v = new Validator(['price' => '0.1']);$v->rule('min', 'price', 0.1); // Correctly returns true
// Without BCMath, floating-point issues could occurSecurity Best Practices
Section titled “Security Best Practices”1. Always Validate Input
Section titled “1. Always Validate Input”// Never trust user input$v = new Validator($_POST);$v->rule('required', ['email', 'password']);$v->rule('email', 'email');$v->rule('lengthMin', 'password', 8);2. Use Specific Rules
Section titled “2. Use Specific Rules”// Specific is better than generic$v->rule('email', 'email'); // Good - validates email format$v->rule('lengthMax', 'email', 5); // Bad - just checks length3. Validate Before Use
Section titled “3. Validate Before Use”if ($v->validate()) { // Only use data after validation passes $email = $v->data()['email'];}4. Don’t Expose Internal Errors
Section titled “4. Don’t Expose Internal Errors”if (!$v->validate()) { // Return user-friendly errors $errors = $v->errors();
// Log detailed errors internally error_log(json_encode($errors));}5. Whitelist, Don’t Blacklist
Section titled “5. Whitelist, Don’t Blacklist”// Whitelist allowed values$v->rule('in', 'status', ['active', 'inactive', 'pending']);
// Rather than trying to block bad values6. Validate File Uploads Separately
Section titled “6. Validate File Uploads Separately”Valicomb validates data, not files. For file uploads:
- Validate MIME types server-side
- Use a dedicated file validation library
- Never trust client-provided file extensions
Reporting Security Issues
Section titled “Reporting Security Issues”If you discover a security vulnerability in Valicomb:
- Do NOT create a public GitHub issue
- Create a private security advisory on GitHub
- Or email the maintainer directly
Provide details about:
- The vulnerability
- Steps to reproduce
- Potential impact