How-To: Block requests that exploit Log4j CVE-2021-44228 on Apigee

In an earlier community post, we have walked through how to detect the attempts to Exploit CVE-2021-44228 on Apigee.

Note: If you are running on Apigee X / Latest version of Apigee Hybrid / Apigee Edge / Latest version of Apigee OPDK, you are not vulnerable. (status page) . This guide is relevant if you have uploaded vulnerable versions of log4j in the proxy code, or if you want to block the exploit requests on precautionary measure.

 

Now that we are able to get the the regex that detects the requests of exploit

 

"(?i)(\$|\%24)(\{|\%7b).*j.*n.*d.*i.*(\:|\%3a)"

 

 

 

Let’s add Raise Fault and reject the requests that match this regex. Here is the overall proxy structure:

  1. RegularExpressionProtection policy
  2. Raise Fault policy
  3. Ensure the RegularExpressionProtection policy is placed in PreFlow and RaiseFault policy is placed in a FaultRules.

The example structure can be downloaded at apigee github /sample-proxies/regex-protection .

 

For RegularExpressionProtection, we want to scan for the exploit pattern in some specific request headers, querystring and path. You can access them by using the following flow variables in Apigee:

  • request.message.header.user-agent
  • request.message.header.referer
  • request.message.querystring
  • request.message.path

 

Hence the RegularExpressionProtection policy definition would look like this:

 

<RegularExpressionProtection async="false" continueOnError="false" enabled="true" name="RegexProtection">
    <DisplayName>RegexProtection</DisplayName>
    <Properties/>
    <Source>request</Source>
    <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
    <Header name="user-agent">
       <Pattern>(?i)(\$|\%24)(\{|\%7b).*j.*n.*d.*i.*(\:|\%3a)</Pattern>
   </Header>
  <Header name="referer">
       <Pattern>(?i)(\$|\%24)(\{|\%7b).*j.*n.*d.*i.*(\:|\%3a)</Pattern>
   </Header>
   <Variable name="request.message.path">
      <Pattern>(?i)(\$|\%24)(\{|\%7b).*j.*n.*d.*i.*(\:|\%3a)</Pattern>
   </Variable>
   <Variable name="request.message.querystring">
        <Pattern>(?i)(\$|\%24)(\{|\%7b).*j.*n.*d.*i.*(\:|\%3a)</Pattern>
    </Variable>
</RegularExpressionProtection>

 

Note: The exploit string is sent generally in the above-mentioned headers, querystring and/or path and we have covered them in our example RegularExpressionProtection. However, if you think that the regex can be sent as part of any other request header or input parameters, please ensure that they are also included in the RegularExpressionProtection policy as explained in the above example.

 


Should there be a match with the defined pattern, we want the proxy to raise fault and short-circuit the request with a 400-Bad request. RaiseFault definition would look like this:

 

<RaiseFault async="false" continueOnError="false" enabled="true" name="RaiseFaultOnExploit">
    <DisplayName>RaiseFaultOnExploit</DisplayName>
    <Properties/>
    <FaultResponse>
        <Set>
            <Headers/>
            <Payload contentType="text/plain"/>
            <StatusCode>400</StatusCode>
            <ReasonPhrase>Bad request</ReasonPhrase>
        </Set>
    </FaultResponse>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</RaiseFault>

 

 

 

Finally, in the proxy flow, we want to make sure RegexProtection is in PreFlow, and RaiseFaultOnExploit is in FaultRules.

 

<ProxyEndpoint name="default">
    <FaultRules>
        <FaultRule name="regex-threat">
            <Step>
                <Name>RaiseFaultOnExploit</Name>
            </Step>
            <Condition>(fault.name = "ThreatDetected")</Condition>
        </FaultRule>
    </FaultRules>
    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Name>RegexProtection</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>
..

 

 

 

2 4 2,699
4 REPLIES 4

Hi There,

Apigee being a WAF itself isn't there a rule that can be applied at Apigee Sense level ?

Thank you so much for this, but shouldn't the variables be the following instead?

  • request.header.user-agent
  • request.header.referer
  • request.querystring
  • request.path

Reference: https://docs.apigee.com/api-platform/reference/variables-reference#request

Hi @ahemanna you can change the variables as mentioned in the doc https://docs.apigee.com/api-platform/reference/variables-reference#request .Also you can add more checks on other request headers and payload data to protect against the potential Log4j threat, if there is any more request data being logged onto the target server. 
The above example is just a reference.

You can also add the Regex protection and the Raise fault in the shared flow and attach it to pre proxy flow hook to avoid manually adding the Policy in each of the deployed proxies in the prod.

https://www.googlecloudcommunity.com/gc/Apigee/How-To-Add-fault-Handling-in-the-shared-flow/m-p/3951...