refactor: separate config service from jail config service
- Split config_service.py into config_service.py and jail_config_service.py - Update Docs/Tasks.md, Security.md, TROUBLESHOOTING.md
This commit is contained in:
@@ -96,3 +96,49 @@ See `backend/app/middleware/csrf.py` and `backend/app/middleware/rate_limit.py`
|
||||
- The SQLite database contains no sensitive data (no passwords, API keys, or tokens stored)
|
||||
- Database queries use parameterized statements to prevent SQL injection
|
||||
- See `backend/app/repositories/` for data access patterns
|
||||
|
||||
---
|
||||
|
||||
## Regex (ReDoS) Protection
|
||||
|
||||
BanGUI validates all user-supplied regex patterns before they are compiled or stored.
|
||||
|
||||
### How It Works
|
||||
|
||||
1. **Static analysis** via [regexploit](https://github.com/doyensec/regexploit) detects catastrophic backtracking patterns before compilation
|
||||
2. **Timeout enforcement** stops compilation if it exceeds 2 seconds (prevents hanging on pathological patterns)
|
||||
3. **Length limit** (1000 characters) prevents memory exhaustion via bloated patterns
|
||||
|
||||
### Protected Endpoints
|
||||
|
||||
All endpoints that accept regex patterns validate them:
|
||||
- Filter configuration (`prefregex`, `failregex`, `ignorregex`)
|
||||
- Action configuration (any regex used in actions)
|
||||
- Direct config editing
|
||||
|
||||
### ReDoS Pattern Examples
|
||||
|
||||
Patterns with nested quantifiers on overlapping text are blocked:
|
||||
|
||||
| Pattern | Why Blocked |
|
||||
|---------|-------------|
|
||||
| `(a+)+b` | Plus inside plus — exponential backtracking |
|
||||
| `([a-z]+)*d` | Quantifier inside quantifier |
|
||||
| `(x+)+y` | Nested quantifiers |
|
||||
| `a[bcd]*e[bcd]*e` | Multiple unbounded quantifiers |
|
||||
|
||||
### Legitimate Complex Patterns
|
||||
|
||||
Not all complex patterns are blocked. Email and IP validation patterns typically pass:
|
||||
|
||||
```python
|
||||
r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$" # OK
|
||||
r"^(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$" # OK
|
||||
```
|
||||
|
||||
### If Your Pattern Is Rejected
|
||||
|
||||
1. Rewrite to avoid nested quantifiers on the same text
|
||||
2. Use atomic groups or possessive quantifiers: `(?>a+)+b` instead of `(a+)+b`
|
||||
3. Test locally with Python's `re` module before deploying
|
||||
4. If you believe the pattern is safe, check with [regexploit](https://github.com/doyensec/regexploit) directly
|
||||
|
||||
@@ -301,6 +301,36 @@ sqlite3 /var/lib/bangui/bangui.db "PRAGMA integrity_check;"
|
||||
|
||||
---
|
||||
|
||||
## Regex Pattern Rejected
|
||||
|
||||
### Symptom: Filter or action configuration fails with "Invalid regex" error
|
||||
|
||||
**Cause:** The regex pattern is either syntactically invalid or detected as a ReDoS (Regular Expression Denial of Service) vulnerability.
|
||||
|
||||
**Diagnosis:**
|
||||
1. Check the error message — it indicates whether the pattern is syntactically invalid or flagged as dangerous
|
||||
2. Look for log events: `regex_redos_detected` or `regex_compilation_timeout`
|
||||
|
||||
**Common ReDoS patterns that are rejected:**
|
||||
| Pattern | Problem |
|
||||
|---------|---------|
|
||||
| `(a+)+b` | Nested quantifiers with overlap |
|
||||
| `([a-z]+)*d` | Quantifier inside quantifier |
|
||||
| `(x+)+y` | Nested plus operators |
|
||||
|
||||
**Solution:**
|
||||
1. Rewrite the pattern to avoid nested quantifiers on overlapping groups
|
||||
2. Use atomic groups or possessive quantifiers where possible: `(?>a+)+b`
|
||||
3. Simplify complex alternations
|
||||
|
||||
**Prevention:**
|
||||
- Test regex patterns in isolation before deploying
|
||||
- Avoid patterns with quantified groups inside other quantifiers
|
||||
- Prefer explicit character classes over `.*` where possible
|
||||
- Use [regexploit](https://github.com/doyensec/regexploit) to audit patterns
|
||||
|
||||
---
|
||||
|
||||
## Getting Help
|
||||
|
||||
If issues persist after following this guide:
|
||||
|
||||
@@ -1,52 +1,3 @@
|
||||
### Issue #15: MEDIUM - N+1 Query Pattern in Geo Lookups
|
||||
|
||||
**Where found**:
|
||||
- `backend/app/services/ban_service.py` (lines 650-680)
|
||||
- `_enrich_bans_with_geo()` calls resolver per IP in loop
|
||||
- 1000 bans = 1000 geo lookups
|
||||
|
||||
**Why this is needed**:
|
||||
Dashboard becomes slow with many bans:
|
||||
- Each geo lookup hits database or HTTP API
|
||||
- 1000 bans = 1000 lookups = seconds of latency
|
||||
- API rate limiting exceeded if fallback HTTP enabled
|
||||
|
||||
**Goal**:
|
||||
Batch geo lookups and implement caching to reduce database round-trips.
|
||||
|
||||
**What to do**:
|
||||
1. Implement batch geo resolution:
|
||||
```python
|
||||
async def enrich_bans_with_geo(bans):
|
||||
# Extract unique IPs
|
||||
unique_ips = set(ban.ip for ban in bans)
|
||||
|
||||
# Batch lookup
|
||||
geo_data = await self.geo_cache.resolve_batch(unique_ips)
|
||||
|
||||
# Attach to bans
|
||||
for ban in bans:
|
||||
ban.country = geo_data.get(ban.ip)
|
||||
```
|
||||
2. Use geo_cache for persistence (cache is already designed for batching)
|
||||
3. Add metrics for cache hit/miss ratio
|
||||
4. Implement pre-warming of common IPs
|
||||
5. Add tests with large ban lists
|
||||
|
||||
**Possible traps and issues**:
|
||||
- Batch lookup might be slower than individual if dataset is small
|
||||
- Cache invalidation on country name updates
|
||||
- Memory usage if caching all IPs
|
||||
|
||||
**Docs changes needed**:
|
||||
- Add performance optimization guide
|
||||
- Document geo cache architecture
|
||||
|
||||
**Doc references**:
|
||||
- DETAILED_FINDINGS.md - Issue #7 "N+1 Query Pattern"
|
||||
|
||||
---
|
||||
|
||||
### Issue #16: MEDIUM - Silent Failures in Error Handling (Broad Exception Handlers)
|
||||
|
||||
**Where found**:
|
||||
|
||||
Reference in New Issue
Block a user