Conversation
The filter deletes the KV output and rebuilds each field with a grok of three patterns: text up to the key, the value, and (?:\s+[A-Za-z_][A-Za-z0-9_]*=|$). The EventProcessor grok step trims whitespace before each pattern, treats an empty match as no match and writes nothing unless every pattern matches, so the third pattern never matches and none of the 208 extractors writes. In the real parser Sophos XG events get no status, type, addresses, ports or outcome. The date step's first pattern matches empty text at the start of the line, so the Sophos clock is never read, and the header grok cannot handle a line without a priority tag. Each extractor now reads a quoted value or an unquoted value up to the next space, with no trailing pattern. The date step consumes the text up to date= and captures the clock without that prefix; the five reformat steps read the new form. A second header grok handles lines that start with the first key. The current parser keeps underscores in KV keys, so the original key names are deleted as well, removing about 120 duplicate raw fields per event. The contract test now consumes grok patterns the way the executor does. The repository's 73 contracts fail 42 subtests on the unchanged filter and pass with this change; four edge cases were added. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The extractors read a quoted value, or an unquoted value up to the next space, without checking where the value ends. Real Sophos XG logs often carry empty values such as src_mac=, tran_src_ip= and tran_dst_ip=, and the grok step trims the text before each pattern, so an empty value took the next key=value pair as its value. src_mac and dst_mac feed origin.mac and target.mac. Multi-word unquoted values such as ether_type=Unknown (0x0000) were cut at the first space, and a quoted value followed directly by text was truncated instead of rejected. Each extractor now reads a quoted value, or unquoted words up to the next key=, and checks the end of the value within the same pattern. An empty value, or a quoted value followed directly by text, is left unset. Two contract cases cover both; they fail with the previous pattern. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The current
v11Sophos XG filter (from #2638) deletes the KV output and rebuilds each field with a grok of three patterns: the text up tokey=, the value, and(?:\s+[A-Za-z_][A-Za-z0-9_]*=|$). The EventProcessor grok step trims whitespace before each pattern, treats an empty match as no match, and writes nothing unless every pattern matches. The third pattern therefore never matches, and none of the 208 extractors writes anything. In the real parser, Sophos XG events get no status, type, subtype, addresses, ports oractionResult, so blocked, allowed and failed activity all look the same and threat-intelligence correlation has no address to check.Two other steps have the same kind of defect. The date step's first pattern matches empty text at the start of the line, so the Sophos clock is never read. The header grok's optional prefix matches empty text when a line starts with its first key, so such lines are not parsed at all.
Change
key=, and checks the end of the value within the same pattern. An empty value, or a quoted value followed directly by text, is left unset instead of taking the next pair.date=and captures the clock without that prefix; the five reformat steps read the new form.v1.1.35and later) keeps underscores in KV keys, so the original underscored key names are deleted as well. This removes about 120 duplicate raw fields per event. The existing underscore-free names stay in the list for older parsers.src_mac=,tran_src_ip=andtran_dst_ip=, so an empty value took the next pair as its value, which reachedorigin.macandtarget.mac. Multi-word values such asether_type=Unknown (0x0000)were cut at the first space.Validation
All results use the latest versions: EventProcessor
8a3ade7, with every parser and rule plugin on go-sdkv1.1.36, andv11d2479c1a.497bf53engine, so the defect does not come from the go-sdk change. This branch passed 42/42. Denials, allows, failures and the VPN and heartbeat cases got the expected outcome, and the source and destination addresses matched the stored ones, with no event errors. The replay also checks the hardware addresses, translated addresses andether_typeagainst each raw line: empty values stay unset, and all 16 multi-wordether_typevalues are complete.date=as the first key, an unquoted value at the end, empty values, and a quoted value followed directly by text. The unchanged filter passed 0/6, and one case produced event errors. This branch passed 6/6, including the device time.sophos_xg_contract_test.gonow consumes grok patterns in order, as the executor does. On the unchanged filter the repository's 73 contracts fail 42 subtests (27 onactionResult, 11 onstatusCode, 12 on addresses). With this change all 79 contracts pass, and the fullplugins/alertssuite passes. The two contracts added for the correction fail with the first version.sophos_xg_vpn_auth_failures.ymlandsophos_password_guessing_on_administrator_account.ymlreadactionResultand use history. Their trigger conditions were replayed with go-sdkv1.1.36on the parser output. The VPN rule matched the one real SSL VPN failed sign-in with this branch and nothing with the unchanged filter. The administrator rule was not exercised, because the sample had no failed administrator sign-in. History queries were not executed.Production context
The deployment in the sample still runs an older filter. Over three days it stored 2.7 million events as the nonstandard
acceptedand only about 120,000 asdenied, while about 931,000 events have theDeniedsubtype. Blocked web requests in the sample were stored asaccepted. Deploying the currentv11filter without this change would remove outcomes and addresses from Sophos XG events altogether.In a random sample of 1,500 records, an empty value directly followed by the next key appeared for
tran_src_ipin 864 records,tran_dst_ipin 617,src_macin 193 anddst_macin 192, andether_typeheld several words in 1,099.Limits
🤖 Generated with Claude Code