Jekyll Minifier prioritizes security while maintaining backward compatibility. This document outlines the security measures implemented to protect against various attack vectors.
Prior to version 0.2.1, Jekyll Minifier was vulnerable to ReDoS (Regular Expression Denial of Service) attacks through the preserve_patterns
configuration option. Malicious regex patterns could cause the Jekyll build process to hang indefinitely, leading to denial of service.
Affected Code Location: lib/jekyll-minifier.rb
line 72 (pre-fix)
The vulnerability has been completely resolved with the following security measures:
The gem now validates regex patterns before compilation:
- Length Limits: Patterns longer than 1000 characters are rejected
- Nesting Depth: Patterns with more than 10 nested parentheses are rejected
- Quantifier Limits: Patterns with more than 20 quantifiers are rejected
- ReDoS Pattern Detection: Common ReDoS vectors are automatically detected and blocked
Regex compilation is protected by a timeout mechanism:
- 1-second timeout for pattern compilation
- Graceful failure when timeout is exceeded
- Thread-safe implementation to prevent resource leaks
When dangerous patterns are detected:
- Build continues successfully without failing
- Warning messages are logged for debugging
- Safe patterns are still processed normally
- Zero impact on existing functionality
The security fix maintains 100% backward compatibility:
- All existing
preserve_patterns
configurations continue working unchanged - No new required configuration options
- No breaking changes to the API
- Same behavior for all valid patterns
The following dangerous patterns are now automatically rejected:
# These patterns would cause ReDoS attacks (now blocked)
jekyll-minifier:
preserve_patterns:
- "(a+)+" # Nested quantifiers
- "(a*)*" # Nested quantifiers
- "(a|a)*" # Alternation overlap
- "(.*)*" # Exponential backtracking
These patterns continue to work normally:
# These patterns are safe and continue working
jekyll-minifier:
preserve_patterns:
- "<!-- PRESERVE -->.*?<!-- /PRESERVE -->"
- "<script[^>]*>.*?</script>"
- "<style[^>]*>.*?</style>"
- "<%.*?%>" # ERB tags
- "\{\{.*?\}\}" # Template variables
When creating preserve_patterns
:
- Use non-greedy quantifiers (
.*?
instead of.*
) - Anchor patterns with specific boundaries
- Avoid nested quantifiers like
(a+)+
or(a*)*
- Test patterns with sample content before deployment
- Keep patterns simple and specific
- Validate user input if accepting patterns from external sources
- Use allow-lists instead of block-lists when possible
- Monitor build performance for unusual delays
- Review patterns during security audits
- Run tests after changing preserve patterns
- Monitor logs for security warnings
- Update regularly to receive security patches
- Use specific versions in production (avoid floating versions)
If you discover a security vulnerability, please:
- Do not create a public issue
- Email the maintainers privately
- Provide detailed reproduction steps
- Allow reasonable time for response and patching
The gem includes comprehensive security tests:
- ReDoS attack simulation with known dangerous patterns
- Timeout validation to prevent hanging
- Pattern complexity testing for edge cases
- Backward compatibility verification
- Performance regression testing
Run security tests with:
bundle exec rspec spec/security_redos_spec.rb
- v0.2.0 and earlier: Vulnerable to ReDoS attacks via preserve_patterns
- v0.2.1: ReDoS vulnerability completely fixed with comprehensive protection
- Current: All security measures active with full backward compatibility
The security implementation follows:
- OWASP Top 10 guidelines for input validation
- CWE-1333 (ReDoS) prevention best practices
- Ruby security standards for regex handling
- Secure development lifecycle practices
For security-related questions or concerns, please contact the project maintainers through appropriate channels.
Note: This security documentation is maintained alongside the codebase to ensure accuracy and completeness.