CyberArena / app /core /security.py
Hussien Haider
H
80a4a65
Raw
History Blame Contribute Delete
1.74 kB
"""Normalization helpers used by the evaluators.
Each function is intentionally tiny and side-effect-free so the
1v1 verifier and the regular /evaluate endpoint can call the same code
and stay in lock-step.
"""
import re
def normalize_vuln_key(s: str) -> str:
"""Canonicalise a typed vulnerability key.
Rules:
- lowercase
- trim
- replace spaces / underscores with dashes
- strip surrounding punctuation
"""
if not s:
return ""
s = s.strip().lower()
s = re.sub(r"[\s_]+", "-", s)
s = re.sub(r"[^a-z0-9\-]", "", s)
return s
def normalize_str(s: str) -> str:
return (s or "").strip().lower()
def ip_matches(user_ip: str, expected_ip: str) -> bool:
"""Loose IP match: trim, lowercase, ignore trailing port or zone id."""
u = normalize_str(user_ip).split("/")[0]
e = normalize_str(expected_ip).split("/")[0]
return u == e and u != ""
def ioc_matches(user_ioc: str, expected_ioc: str) -> bool:
"""IOC match: case-insensitive substring."""
u = normalize_str(user_ioc)
e = normalize_str(expected_ioc)
if not u or not e:
return False
return e in u or u in e
def timestamp_close(user_ts: str, expected_ts: str) -> bool:
"""Timestamp match: exact OR every alphanumeric token of the expected
timestamp appears in the user input (lenient by design)."""
u = normalize_str(user_ts)
e = normalize_str(expected_ts)
if not u or not e:
return False
if u == e:
return True
# Try day-hour match (e.g., "15/Dec" or "Mar 12" or "2024-11-08")
e_tokens = re.findall(r"[a-zA-Z]+|\d+", e)
if not e_tokens:
return False
return all(tok.lower() in u for tok in e_tokens[:2])