diff --git a/dashboard/backend/routers/security.py b/dashboard/backend/routers/security.py index c961afd..fe7476b 100644 --- a/dashboard/backend/routers/security.py +++ b/dashboard/backend/routers/security.py @@ -13,8 +13,15 @@ _tz_cst = timezone(timedelta(hours=8)) # Suspicious path patterns (scanners, exploits, etc.) _SUSPICIOUS_PATHS = re.compile( - r"(\.env|\.git|wp-login|wp-admin|phpmy|/admin|/cgi-bin|/shell|/eval|" - r"\.php|\.asp|/etc/passwd|/proc/self|\.sql|/actuator|/debug|/config\.json)", + r"(\.env|\.git/|wp-login|wp-admin|phpmy|/cgi-bin|/shell|/eval|" + r"\.asp|/etc/passwd|/proc/self|\.sql|/actuator|/debug|/config\.json|" + r"xmlrpc\.php|wp-cron\.php|wp-includes|/\.well-known/security)", + re.IGNORECASE, +) + +# Known internal API paths that should not be flagged +_INTERNAL_PATHS = re.compile( + r"^/(api/|rest/|backend/|_next/|static/|assets/|favicon)", re.IGNORECASE, ) @@ -71,8 +78,12 @@ def _parse_caddy_logs(lines: str, limit: int) -> list[dict]: uri = obj.get("uri", obj.get("request", {}).get("uri", "")) remote_ip = obj.get("remote_ip", obj.get("request", {}).get("remote_ip", "")) - # Flag: 4xx/5xx or suspicious path - is_suspicious = status >= 400 or _SUSPICIOUS_PATHS.search(uri) + # Flag: suspicious path (skip known internal paths), or 4xx on unknown paths + is_suspicious = False + if _SUSPICIOUS_PATHS.search(uri): + is_suspicious = not _INTERNAL_PATHS.match(uri) + elif status >= 400 and not _INTERNAL_PATHS.match(uri): + is_suspicious = True if not is_suspicious: continue