Skip to content

JSON key paths longer than 30 characters are silently truncated #696

Description

@NRGLine4Sec

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions