Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

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,851
4 REPLIES 4