fix: serialize HTTP headers as JSON so tool detection and bounty extraction work
templates/decnet_logging.py calls str(v) on all SD-PARAM values, turning a
headers dict into Python repr ('{'User-Agent': ...}') rather than JSON.
detect_tools_from_headers() called json.loads() on that string and silently
swallowed the error, returning [] for every HTTP event. Same bug prevented
the ingester from extracting User-Agent bounty fingerprints.
- templates/http/server.py: wrap headers dict in json.dumps() before passing
to syslog_line so the value is a valid JSON string in the syslog record
- behavioral.py: add ast.literal_eval fallback for existing DB rows that were
stored with the old Python repr format
- ingester.py: parse headers as JSON string in _extract_bounty so User-Agent
fingerprints are stored correctly going forward
- tests: add test_json_string_headers and test_python_repr_headers_fallback
to exercise both formats in detect_tools_from_headers
This commit is contained in:
@@ -106,7 +106,17 @@ async def _extract_bounty(repo: BaseRepository, log_data: dict[str, Any]) -> Non
|
||||
})
|
||||
|
||||
# 2. HTTP User-Agent fingerprint
|
||||
_headers = _fields.get("headers") if isinstance(_fields.get("headers"), dict) else {}
|
||||
_h_raw = _fields.get("headers")
|
||||
if isinstance(_h_raw, dict):
|
||||
_headers = _h_raw
|
||||
elif isinstance(_h_raw, str):
|
||||
try:
|
||||
_parsed = json.loads(_h_raw)
|
||||
_headers = _parsed if isinstance(_parsed, dict) else {}
|
||||
except (json.JSONDecodeError, ValueError):
|
||||
_headers = {}
|
||||
else:
|
||||
_headers = {}
|
||||
_ua = _headers.get("User-Agent") or _headers.get("user-agent")
|
||||
if _ua:
|
||||
await repo.add_bounty({
|
||||
|
||||
Reference in New Issue
Block a user