When I write a detection with Panther, how do I retrieve a value from a field in ingested data when the field is nested in other JSON fields?
You can use the Python helper function deep_get
for this. It returns a value nested in data at any depth. It is used in many of Panther's built-in detections and helpers, such as this one.
To use deep_get
:
At the top of your detection code, add from panther_base_helpers import deep_get
Example JSON data:
... "client": { "device": "Computer", "geographicalcontext": { "country": "United States", "geolocation": { "lat": "39.5022", "lon": "-106.1497" }, }, "useragent": { "browser": "CHROME", "os": "Mac OS X", "rawuseragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML" } }, ...
Examples (see data above):
print(str(deep_get(event, "client", "device"))) # prints Computer
print(str(deep_get(event, "client", "geographicalcontext", "geolocation", "lat"))) # prints 39.5022
You may not need to convert the returned value to a string as shown, depending on what you're doing with it.
In the case where deep_get
doesn't find the field it's looking for, it returns the Python None
instead of the value of the field. For example, when using this JSON:
{ "event": { "outcome": { "result": "SUCCESS" } } }
this Python prints SUCCESS
print(deep_get(data, "event", "outcome", "result"))
and this Python prints None
print(deep_get(data, "event", "outcome", "resulterino"))