Decrypt values with the same key at different levels from base64

Viewed 113

My input is like below. I want to search for SearchString key (you can see that we can't use a fixed index for it) and when the key appears decrypt its value from base64 (perhaps using @base64d filter). Is this possible with JQ? If so, how?

[
  {
    "Name": "searchblock",
    "Priority": 3,
    "Statement": {
      "RateBasedStatement": {
        "Limit": 100,
        "AggregateKeyType": "IP",
        "ScopeDownStatement": {
          "ByteMatchStatement": {
            "SearchString": "Y2F0YWxvZ3NlYXJjaA==",
            "FieldToMatch": {
              "UriPath": {}
            },
            "TextTransformations": [
              {
                "Priority": 0,
                "Type": "LOWERCASE"
              }
            ],
            "PositionalConstraint": "CONTAINS"
          }
        }
      }
    },
    "Action": {
      "Block": {}
    },
    "VisibilityConfig": {
      "SampledRequestsEnabled": true,
      "CloudWatchMetricsEnabled": true,
      "MetricName": "searchblock"
    }
  },
  {
    "Name": "bot-block",
    "Priority": 4,
    "Statement": {
      "ByteMatchStatement": {
        "SearchString": "Ym90",
        "FieldToMatch": {
          "SingleHeader": {
            "Name": "user-agent"
          }
        },
        "TextTransformations": [
          {
            "Priority": 0,
            "Type": "LOWERCASE"
          }
        ],
        "PositionalConstraint": "CONTAINS"
      }
    },
    "Action": {
      "Allow": {}
    },
    "VisibilityConfig": {
      "SampledRequestsEnabled": true,
      "CloudWatchMetricsEnabled": true,
      "MetricName": "user-agent"
    }
  }
]
2 Answers

We use path, paths, getpath, and setpath built-ins for such operations when a fixed path is not available.

getpath(paths | select(.[-1] == "SearchString")) |= @base64d

Online demo

walk is quite intuitive for this kind of task:

walk(if type == "object" and .SearchString 
     then .SearchString |= @base64d else . end)

Using this approach, it's also trivial to modify the program to make it more robust, e.g. to check that .SearchString is a string:

walk(if type == "object" and (.SearchString|type) == "string" 
     then .SearchString |= @base64d else . end)

Note: if your jq does not include walk, you can simply copy its def from any reputable web site, or from https://github.com/stedolan/jq/blob/master/src/builtin.jq

Related