Skip to Content

SAP Cloud Platform, API Management offers many out of the box API Security best practices which can be customized based on your enterprise requirements.  These API Security Best Practices includes security policies for Authentication and Authorization,  Traffic Management and many more.

OWASP Top 10 that represents a broad consensus about the most critical security risks to web applications lists Injection attacks as one of the Top 10 web application security attack. As per OWASP, XML External Entity or XXE is a type of attack against an application that parses XML input. This attack occurs when XML input containing a reference to an external entity is processed by a weakly configured XML parser. This attack may lead to the disclosure of confidential data, denial of service, server side request forgery, port scanning from the perspective of the machine where the parser is located, and other system impacts.

In this blog we will extend the previous blog on Threat Protection against SQL Injection attacks, to detect the XML External Entity attacks.

More best practices covered in API Security Best Practices blog series.

Prerequisites

Launch API Portal

 

  • Click on the link Access API Portal to open API Portal.

 

XML External Threat Protection

In this section we would describe the usage of the Regular Expression Protection Policy to detect the XXE reference or (!Entity) reference in OData queries and request body.

In this blog, we would be extending the Regular Expression Protection Policy used in SQL Threat Protection blog to detect and mitigate the XXE attacks.
  • Navigate to the Define from the hamburger icon, then select the tab APIs. Select the API Proxy to which API Rate limiting was applied.

 

  • Click on the Policies button of  the selected API Proxy.

 

  • Select PreFlow from the ProxyEndPoint and select checkForCodeInjection policy, then update policy content the following policy snippet
<RegularExpressionProtection async="false" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt">
	<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
	<URIPath>
		<Pattern>[\s]*(?i)((delete)|(exec)|(drop\s*table)|(insert)|(shutdown)|(update)|(\bor\b))</Pattern>
	</URIPath>
	<QueryParam name="$format">
		<Pattern>[\s]*(?i)((delete)|(exec)|(drop\s*table)|(insert)|(shutdown)|(update)|(\bor\b))</Pattern>
	</QueryParam>
	<QueryParam name="$top">
		<Pattern>[\s]*(?i)((delete)|(exec)|(drop\s*table)|(insert)|(shutdown)|(update)|(\bor\b))</Pattern>
	</QueryParam>
	<QueryParam name="$skip">
		<Pattern>[\s]*(?i)((delete)|(exec)|(drop\s*table)|(insert)|(shutdown)|(update)|(\bor\b))</Pattern>
	</QueryParam>
	<QueryParam name="$filter">
		<Pattern>[\s]*(?i)((delete)|(exec)|(drop\s*table)|(insert)|(shutdown)|(update)|(\bor\b))</Pattern>
	</QueryParam>
	<QueryParam name="$count">
		<Pattern>[\s]*(?i)((delete)|(exec)|(drop\s*table)|(insert)|(shutdown)|(update)|(\bor\b))</Pattern>
	</QueryParam>
	<Variable name="request.content">
		<Pattern>[\s]*((delete)|(exec)|(drop\s*table)|(insert)|(shutdown)|(update)|(\bor\b))</Pattern>
		<Pattern>[\s]*(?i)(!ENTITY)</Pattern>
	</Variable>
	<Source>request</Source>
</RegularExpressionProtection>

 

Note that the values of Regular expression pattern used in this blog is just a sample and would have to be extended to handles all the edge case.

 

 

In the above screenshot, pattern added to detect the XXE usage is highlighted.

 

  • Click on the Update button to save the Policy changes

 

  • Click on the Save button to save the changes to API Proxy.

 

 

With this we have successfully updated a Regular expression protection to detect XML External entity attacks in request body.

Finally testing the flow

 

  • Navigate to the Test tab from the hamburger icon

 

 

  • From the APIs list search for the API Proxy that you would like to test say GatewayServiceRestrictedAccess and then click the API to test.

 

 

  • Click on the Authentication: None link and select Basic Authentication to set the user credential to connect to the SAP Gateway ES4 system

 

 

  • select POST method and in the request body, paste the following request payload and then click on the Send button
<!DOCTYPE foo [  
   <!ELEMENT foo ANY >
   <!ENTITY xxe SYSTEM "file:///etc/passwd" >]><foo>&xxe;</foo>

 

The above snippet is a sample copied from the OWASP XXE cheat sheet, which is used to access the password information from a local file system.

  • This would result in Regular expression protection policy error as the usage of !entity has been blacklisted in the policy

  • Next we would using a POST call to pass a valid the JSON payload, and for this x-csrf-token handling would be required. Click on the Headers button. Enter x-csrf-token as header name and fetch as the header value and then click on the Send button

 

    • Click on the response headers tab, then copy the x-csrf-token value received from the server in the OData batch request call

     

     

  • Append /SalesOrderSet to the API Proxy URL and then select POST method. In the x-csrf-token header value paste the x-csrf-token header response received from the server in previous call. Click on the + button next to the Headers and then add a new header named Content-Type with value set to application/json. Click on the + button next to the Headers again and then add another header named Accept with value set to application/json. In the request body, paste the following request payload and then click on the Send button
{
        "Note": "EPM DG: SO ID 0500000000 Deliver as fast as possible",
        "NoteLanguage": "EN",
        "CustomerID": "0100000000",
        "CustomerName": "SAP",
        "CurrencyCode": "EUR",
        "GrossAmount": "28142.31",
        "NetAmount": "23649.00",
        "TaxAmount": "4493.31",
        "LifecycleStatus": "N",
        "LifecycleStatusDescription": "New",
        "BillingStatus": "",
        "BillingStatusDescription": "Initial",
        "DeliveryStatus": "",
        "DeliveryStatusDescription": "Initial",
        "ToLineItems":  [
                {
                    "ProductID": "HT-1000",
                    "ItemPosition" : "0000000010",
                    "Note": "EPM DG: SO ID 0500000000 Item 0000000010",
                    "NoteLanguage": "EN",
                    "CurrencyCode": "EUR",
                    "GrossAmount": "3412.92",
                    "NetAmount": "2868.00",
                    "TaxAmount": "544.92",
                    "DeliveryDate": "/Date(1503532800000)/",
                    "Quantity": "3",
                    "QuantityUnit": "EA"
                },
                {
                    "ProductID": "HT-1001",
                    "ItemPosition" : "0000000020",
                    "Note": "EPM DG: SO ID 0500000000 Item 0000000020",
                    "NoteLanguage": "EN",
                    "CurrencyCode": "EUR",
                    "GrossAmount": "2972.62",
                    "NetAmount": "2498.00",
                    "TaxAmount": "474.62",
                    "DeliveryDate": "/Date(1503547200000)/",
                    "Quantity": "2",
                    "QuantityUnit": "EA"
                }
            ]
      
}

 

  • Since the JSON request is within the given limit defined in the various Threat Protection policies, the call would be successfully passed by the SAP API Management to the SAP Gateway system and a Sales order would be get created.

 

Further Reads

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply