// Illustrative hunt; not executed in a live Sentinel or Falcon tenant. // Falcon Next-Gen SIEM, CPS web logs. REQUIRED time picker: last 1 hour. // Replace parser, source IP and host. Requires user.id (principal, never a raw token). // Resource identifiers must be in url.path; query-selected objects need an extra canonical resource key. // Only PUT/PATCH pairs; POST creation needs separate Location/object-ID correlation. // The oldest 10,000 matching input events are retained: split busy windows; output at most 100 groups. #type="REPLACE_WITH_WEB_PARSER" source.ip="REPLACE_WITH_SOURCE_IP" url.domain="REPLACE_WITH_APP_HOST" user.id=* url.path=* | sort(@timestamp, order=asc, limit=10000) | t := @timestamp | groupBy([source.ip, url.domain, url.path, user.id], function=neighbor(include=[t, http.request.method, http.response.status_code], prefix=prev), limit=max) | http.request.method=/^GET$/i prev.http.request.method=/^(PUT|PATCH)$/i | prev.http.response.status_code=/^2[0-9]{2}$/ http.response.status_code=/^2[0-9]{2}$/ | gap := t - prev.t | test(gap > 0 and gap <= 5000) | groupBy([source.ip, url.domain, user.id], function=[count(as=ReadBacks), collect([url.path], limit=10)], limit=100) | ReadBacks >= 3 | head(limit=100)