fix(security): consolidation & securite phase 1 (#84, BUG-021 a BUG-034)
- sanitizer XSS serveur (markdown + page de partage) [BUG-021/022] - rate-limit/lockout MFA [BUG-023] - isolation vaults par segments [BUG-024] - caps regex ReDoS [BUG-025] - SSRF webhooks + secrets externalises [BUG-026] - rotation/revocation des jetons [BUG-027] - politique de mot de passe + invalidation sessions [BUG-028] - verrous users.json [BUG-029] - IP reelle dans les audits [BUG-030] - rate-limit par compte [BUG-031] - symlinks hors vault ignores [BUG-032] - recherche simple via inverted index [BUG-033] - token en memoire + cookie HttpOnly, CSP durcie [BUG-034] Tests: pytest 961 passed / 6 skipped, ruff 0, mypy 0, frontend vert.
This commit is contained in:
@@ -433,22 +433,33 @@ def replace_in_files(
|
||||
"""
|
||||
import re as re_mod
|
||||
|
||||
from backend.services.regex_safety import MAX_REGEX_MATCHES, validate_regex
|
||||
from backend.services.search import advanced_search_vaults
|
||||
|
||||
if not find:
|
||||
raise ServiceError("Query is required", code="invalid_arguments", status=400)
|
||||
|
||||
search_results = advanced_search_vaults(
|
||||
find,
|
||||
vault=vault,
|
||||
case_sensitive=case_sensitive,
|
||||
whole_word=whole_word,
|
||||
regex=regex,
|
||||
include_paths=include_paths,
|
||||
exclude_paths=exclude_paths,
|
||||
limit=500,
|
||||
sort="relevance",
|
||||
)
|
||||
# BUG-025: validate the pattern before it is compiled / applied in bulk.
|
||||
if regex:
|
||||
try:
|
||||
validate_regex(find)
|
||||
except ValueError as e:
|
||||
raise ServiceError(str(e), code="invalid_arguments", status=400) from e
|
||||
|
||||
try:
|
||||
search_results = advanced_search_vaults(
|
||||
find,
|
||||
vault=vault,
|
||||
case_sensitive=case_sensitive,
|
||||
whole_word=whole_word,
|
||||
regex=regex,
|
||||
include_paths=include_paths,
|
||||
exclude_paths=exclude_paths,
|
||||
limit=500,
|
||||
sort="relevance",
|
||||
)
|
||||
except ValueError as e:
|
||||
raise ServiceError(str(e), code="invalid_arguments", status=400) from e
|
||||
|
||||
if not search_results["results"]:
|
||||
return {"matches": [], "total_matches": 0, "dry_run": dry_run}
|
||||
@@ -480,7 +491,7 @@ def replace_in_files(
|
||||
except OSError:
|
||||
continue
|
||||
|
||||
occurrences = list(pattern.finditer(original))
|
||||
occurrences = list(pattern.finditer(original))[:MAX_REGEX_MATCHES]
|
||||
if not occurrences:
|
||||
continue
|
||||
|
||||
|
||||
Reference in New Issue
Block a user