The key names come from the log formats (AWS CloudTrail, Entra, Confluent, Okta), so no change to the rules can shorten them. The defect is in the engine, and the report below belongs on quadrantsec/sagan. The 14 affected rules in quadrantsec/sagan-rules cannot match until it is fixed.
A rules-side workaround exists and is deliberately not proposed: naming the key truncated to its first 30 characters does match, because that is what the parser stored. Writing that into the rules would encode the bug and break them the day it is fixed.
Issue title
JSON key paths over 30 characters are truncated, so rules naming them never match
Issue body
JSON_MAX_KEY_SIZE is 32 in src/sagan-defs.h, and src/parsers/json.c builds each nested path with:
snprintf(JSON_LOCAL->json_key[json_count], JSON_MAX_KEY_SIZE, "%s.%s",
JSON_LOCAL->json_key[i], key);
JSON_LOCAL->json_key[json_count][JSON_MAX_KEY_SIZE - 1] = '\0';
so a path longer than that is stored truncated. A rule naming the full path then compares against a name the parser never produced, and the condition can never be satisfied. Nothing is logged: the rule loads, runs, and quietly matches nothing.
Reproduction, against Sagan built from 3b9b0fa:
alert any any any -> any any (msg:"t"; program: test; \
json_content:".data.authorizationInfo.operation","CreateCloudCluster"; \
classtype: misc-activity; sid:1; rev:1;)
fed the event
{"data":{"authorizationInfo":{"operation":"CreateCloudCluster"}}}
does not alert. Shortening the path in the rule to its first 30 characters, .data.authorizationInfo.operati, does alert, which shows the stored key is that prefix.
The boundary is exact: a 30-character path matches, a 31-character one does not.
Nesting does not change it, since the whole dotted path counts.
Affected rules in quadrantsec/sagan-rules. Fourteen rules across five products name a key the parser cannot store:
| File |
Line |
SID |
Key |
Length |
aws-cloudtrail.rules |
76 |
5015096 |
userIdentity.sessionContext.sessionIssuer.userName |
50 |
azure-eventhub-ad.rules |
54 |
5004773 |
properties.riskLevelDuringSignIn |
32 |
azureEventHub_entra.rules |
55 |
5017933 |
properties.deviceDetail.isManaged |
33 |
azureEventHub_entra.rules |
55 |
5017933 |
properties.originalTransferMethod |
33 |
confluent.rules |
32, 58, 60, 62 |
5005921, 5005934, 5005935, 5005936 |
data.authorizationInfo.operation |
32 |
confluent.rules |
36, 38, 42, 44 |
5005923, 5005924, 5005926, 5005927 |
data.authenticationInfo.metadata.mechanism |
42 |
confluent.rules |
62, 76, 78 |
5005936, 5005943, 5005944 |
data.authorizationInfo.superUserAuthorization |
45 |
confluent.rules |
78 |
5005944 |
data.authorizationInfo.aclAuthorization.permissionType |
54 |
okta.rules |
2 |
5006600 |
debugContext.debugData.threatSuspected |
38 |
Fifty characters is not an unusual CloudTrail path, so the limit is likely to be met again as cloud rules are added.
Suggested fix
Raising JSON_MAX_KEY_SIZE would cover the paths above; JSON_MAX_OBJECTS is 256 and each entry holds a key and a value pointer, so the cost of a larger bound is modest. Failing that, logging when a key is truncated would at least make the failure visible, since today the only symptom is a rule that never fires.
The key names come from the log formats (AWS CloudTrail, Entra, Confluent, Okta), so no change to the rules can shorten them. The defect is in the engine, and the report below belongs on
quadrantsec/sagan. The 14 affected rules inquadrantsec/sagan-rulescannot match until it is fixed.A rules-side workaround exists and is deliberately not proposed: naming the key truncated to its first 30 characters does match, because that is what the parser stored. Writing that into the rules would encode the bug and break them the day it is fixed.
Issue title
JSON key paths over 30 characters are truncated, so rules naming them never matchIssue body
JSON_MAX_KEY_SIZEis 32 insrc/sagan-defs.h, andsrc/parsers/json.cbuilds each nested path with:so a path longer than that is stored truncated. A rule naming the full path then compares against a name the parser never produced, and the condition can never be satisfied. Nothing is logged: the rule loads, runs, and quietly matches nothing.
Reproduction, against Sagan built from
3b9b0fa:fed the event
{"data":{"authorizationInfo":{"operation":"CreateCloudCluster"}}}does not alert. Shortening the path in the rule to its first 30 characters,
.data.authorizationInfo.operati, does alert, which shows the stored key is that prefix.The boundary is exact: a 30-character path matches, a 31-character one does not.
Nesting does not change it, since the whole dotted path counts.
Affected rules in
quadrantsec/sagan-rules. Fourteen rules across five products name a key the parser cannot store:aws-cloudtrail.rulesuserIdentity.sessionContext.sessionIssuer.userNameazure-eventhub-ad.rulesproperties.riskLevelDuringSignInazureEventHub_entra.rulesproperties.deviceDetail.isManagedazureEventHub_entra.rulesproperties.originalTransferMethodconfluent.rulesdata.authorizationInfo.operationconfluent.rulesdata.authenticationInfo.metadata.mechanismconfluent.rulesdata.authorizationInfo.superUserAuthorizationconfluent.rulesdata.authorizationInfo.aclAuthorization.permissionTypeokta.rulesdebugContext.debugData.threatSuspectedFifty characters is not an unusual CloudTrail path, so the limit is likely to be met again as cloud rules are added.
Suggested fix
Raising
JSON_MAX_KEY_SIZEwould cover the paths above;JSON_MAX_OBJECTSis 256 and each entry holds a key and a value pointer, so the cost of a larger bound is modest. Failing that, logging when a key is truncated would at least make the failure visible, since today the only symptom is a rule that never fires.