Showing posts with label Security. Show all posts
Showing posts with label Security. Show all posts

Friday, November 16, 2018

Beware: SAP Gateway services can default not be Cross-Domain / CORS accessed

In our business context we have non-SAP web applications that invoke SAP Gateway services to retrieve business data. This week I was involved in a rewrite of such application (the need for rewrite being that another consumed data source, namely a SharePoint List, was moved to a new destination, from on-premise SharePoint 2010 to Office 365 SharePoint Online). While testing the updated application codebase, I noticed that I unexpected run into data retrieval issues with getting the SAP data; on code that I did not even touch. After some investigation, the cause appeared to be a Cross Domain issue: the consumed SAP Gateway services are deployed on another domain as the application (whether run local via Node.js, or on the target webserver). The problem was known to application owner, and pragmatic solution to use the application only from Internet Explorer (IE); as that includes an option to disable the Cross Domain check. Mind you, I initially did my testing via Chrome and Edge; both browsers do not support to skip the Cross Domain check in their default usage behavior.
Having a developer and solution-aware mindset, I then thought to fix the application itself to enable Cross Domain data access. All browser support this via CORS. Change in the JavaScript codebase should be simple, call the service requests with Cross-Domain awareness: see Using CORS. However, even with this code change the application (or rather the browser) failed to retrieve the data from the SAP Gateway services. With developers tools I inspected the network traffic, and identified the problem. The PreFlight request issued by the browser for non-simple CORS data requests, are responded by the SAP Gateway application with HTTP 401.
This is not compliant with the CORS specification: Preflight requests must not include the user credentials. See the W3C Cross-Origin Resource Sharing specification, preflight request
All modern browsers obey to the CORS specification, and do intentionally not include Authorization in the Preflight OPTIONS request. SAP NetWeaver should respond with sending the CORS response, and next the succeeding actual http request (with GET, POST, PUT, or DELETE method) will include Authorization information: this is the call that actually goes into the SAP backend to access the stored business data.
The SAP Gateway specific cause is written in post How to Enable CORS on SAP NetWeaver Platform:
...why is the Preflight Request failing? The issue lies in how a Preflight Request is constructed. According to the CORS specification, the Preflight Request must NOT carry any user credential. As most applications on NetWeaver require user authentication, the Preflight Request will get an “HTTP 401 Unauthorized” error message, thus failing the request.
The post also describes an approach to resolve it directly on SAP Netweaver level, via combination of SICF configuration and ICM rewrite rules. Another approach can be to utilize a reverse proxy in the network infrastructure, and let that handle the CORS handling in front of the SAP NetWeaver destination.

Tuesday, September 2, 2014

HowTo diagnose root cause of Gateway authentication issues

Gateway supports multiple authentication methods to enable Single Sign-On: Basic Authentication, SAML 2.0, X.509 Certificates, SAP Logon Tickets, OAuth. Correct operation of SSO between a Gateway services consumer (e.g. SAP Fiori, SharePoint App, …) and Gateway requires that the consumer and the Gateway system have established an identity trust relationship. This typically (except for basic authentication, but I do not consider that as a viable enterprise-ready SSO option) requires configuration on consumer and Gateway side.
What to do in case the service consumer does not succeed in successfully sign-in on Gateway? How to find out what is the root cause, when you have configuration settings on both the consumer and on the Gateway side? Well, it appears that the NetWeaver stack provides a convenient diagnose tool for this:
https://<hostname>:<port>/sap/bc/webdynpro/sap/sec_diag_tool.
.
Make sure to activate this service in SICF, open the service in a browser, start a recording session, and repeat from consumer side the attempt to single sign-on. Next stop the recording, and inspect the trace file. In case of security related exception, you're likely to find useful information logged in that trace file.

Friday, August 15, 2014

Gateway protection against Cross-Site Request Forgery attacks

Gateway REST services open up the SAP landscape for consumption and operation from clients outside that trusted SAP landscape, including those evil browsers. Evil as we all know, the web cannot be trusted. A critical aspect in the Gateway architecture is therefore to mitigate the impact of web-based security attacks.

Cross-Site Request Forgery (CSRF)

One of the most exploited security vulnerabilities on the web is cross-site request forgery. The essence of a CSRF attack is that a malicious site misleads a trusting site in believing that a transactional request comes with approval of the user. The working of a CSRF attack is as follows: 1) after the user has set up an authenticated session with an application site, 2) the user while still within this authenticated browser session visits a malicious site, and 3) the malicious site tricks the user in sending requests to the application site that are actually constructed by the malicious site. Misleading the trusting site that the request comes with approval from the authenticated and authorized user, while in fact it originates from a malicious site. Hence the name cross-site request forgery.
The success of CSRF attacks depends on 3 factors:
  1. The ability to load malicious javascript code within the authenticated browser session.
  2. The ability to misuse the user authentication to the application site. In most browser/webapplications scenarios the user’s authentication state is maintained in cookies after successful authentication – required to preserve the authenticated state. If the malicious site can lure the user into sending a malicious request from the authenticated browser session, that request will automatically include all cookies including the authentication state. And thus be authorized to the trusting site without the user being aware nor approved the request.
  3. The predictability of the transaction request, so that the malicious site is able to automatically construct a request that will be serviced by the trusting site.
The first factor is common exploited by social engineering. The user is somehow seduced to load javascript code from the malicious site into the current browser session, without the user even be aware. Typical example is to send an email to user with hidden javascript code, and when the user opens it a request is send to malicious site. The protection against this risk are a combination of tooling – mail filters; and educating the users – do not just open any received mail. Although the quality of both security measures increases (yes, users are also more and more aware of the risks on the web), this protection is certainly yet not 100% foolproof.
Note that this factor is only present if the consumption of the webservices is via a browser. In case of a native application, and also in case of an embedded browser in native App (e.g. Fiori Client, Cordova), the user cannot visit others sites and have its client context become infected / compromised.
The second factor is inherent present in all browsers. Without it, each request send from browser would first need to go through the authentication protocol with the remote webapplication, involving browser redirects, identity stores. And in case of username/password browser logon, the user would have to reenter his/her credentials over and over again. Thus: preserving the authentication state after initial authentication is needed to avoid the processing and elapse time for the authentication protocol handling, and to prevent unhappy users. User-friendliness and security are often in contradiction.

Protection against CSRF attacks: CSRF Token

CSRF protection focusses on the 3rd factor: make sure the request cannot be (automically) predicted and thus constructed. Introduce CSRF Token protection.
The essence of CSRF Token protection is that the token is a secret key that is only known to the authenticated browser session and the trusting site, and that the authenticated browser session must include in each modifying request to the trusting site in order to convince the trusting site that the request is coming with consent from the user.
CSRF token protection is utilized on modern webapplication platforms, including SAP ICF, Microsoft IIS, …

CSRF protection applied in Gateway

SAP Gateway applies the following protocol to protect against CSRF:
  1. The user opens in browser a session with the Gateway based webapplication, and must first authenticate. This can be via any of the authentication methods: username/password, integrated Windows Authentication, X.509, SAML2, OAuth. After successful authentication, the browser has established an authenticated user-session with this trusting web application.
  2. The webapplication code loaded in the browser (HTML5, JavaScript) invokes HTTP GET requests to the Gateway REST services to retrieve data. The GET request can only be used to retrieve data, not to request a modifying transaction on a Gateway service.
  3. In case the client application wants to execute a transaction via Gateway REST service, it must invoke this via a POST, PUT or DELETE request. To ensure to the trusting Gateway REST service that the transaction request indeed originates from the user through the client application, the request must be signed with a CSRF-Token as secret key only known by the client application context and the Gateway webapplication.
  4. The CSRF-Token must be requested by the client application from the Gateway webservice. This can only be done via a non-modifying HTTP GET request. If the client application needs the CSRF Token for subsequent transactional request(s), it must include header variable X-CSRF-Token with value ‘FETCH’ in a non-modifying HTTP Get request send to the Gateway service. As all browsers enforce same-origin policy, the browser will only send HTTP GET requests issued from resource/code loaded in the browser that has the same origin/domain as the Gateway REST service. When code loaded via another (cross) site tries to send the HTTP GET request, the browser will refuse to send it.
  5. Gateway webservice only serves request to return X-CSRF-Token for non-modifying HTTP GET Request. It is not possible to retrieve the X-CSRF-Token via a modifying HTTP PUT/POST/DELETE action. Reason is that these requests are not subject to same-origin policy, and thus can be issued from code loaded from another domain (note: the essence of JSONP crossdomain handling).
  6. When Gateway receives a non-modifing GET Request with header variable ‘X-CSRF-Token’ equal to ‘FETCH’, it random generates a new token and returns the generated value to the requesting client in the response: via header variable and cookie. As result of same-origin browser policy, cookies can only be read by javascript code originating from the same domain. Malicious code loaded from another domain cannot read the cookie nor header variable. Also the random generated value cannot reasonable be guessed by the malicious code.
  7. The client application reads the CSRF Token from the HTTP GET Response, and includes the value as header parameter X-CSRF-Token in modifying HTTP requests to Gateway webservice. As the token value is also returned in GET ‘FETCH’ response via cookie, the value will also be included as cookie variable in each subsequent request from the client application in the current browser session.
  8. When Gateway receives a modifying request, SAP ICF runtime inspects the request on presence of X-CSRF-Token in both request header as in cookie. If present in both, it next compares the 2 values. Only if present and equal, the modifying request is guaranteed to come from the client application context, and is granted for execution by the Gateway REST service.

Proofing of Gateway CSRF protection

As stated above, a CSRF attack depends on the ability for malicious site to automatically construct a malicious request, that next the user is somehow lured into sending to the trusting site, and that is well-crafted to mislead the trusting site that the request is with the approval of the authenticated user.
The URL, including REST action is typically static; and could reasonable be ‘guessed’. And as same-origin only applies to HTTP GET request, it is also possible to send PUT/POST/DELETE requests that originate from the malicious site. But in order to have SAP ICF and thus Gateway trust and next execute such a transactional request, the request must be signed with the CSRF-Token as secret key in request header + cookie. The browser automatically includes all the cookies in the request. But the request header is not automatically reused/added by the browser, and the malicious code must therefore explicly set it in the XmlHttpRequest. However the CSRF Token value can only be retrieved and read by JavaScript code that originates from the same domain as the Gateway webservice. Not from JavaScript code that originates from another, external domain. Therefore the malicious code cannot reasonable construct a complete transaction request that includes the proper value of CSRF Token in both request header and client cookie. And Gateway is enabled to detect the malicious request as not being legitimate.

Wednesday, October 24, 2012

Preserve X-CSRF-Token requires SUP 2.1.3

At customer we are conducting an innovation project to experience and validate the applicability of SAP NetWeaver Gateway and Sybase Unwired Platform (SUP) for exposing SAP workflow tasks management to mobile devices. The App has 2 integration dataflows with SAP backend:
  1. Retrieve the list of open tasks for logged-on user
  2. And per task, propagate task decision to complete the SAP workflow
The integration App - SAP Backend is achieved via REST and OData; which is stateless. To protect against Cross-Site Request Forgery attacks, SAP Gateway requires that data modifying requests include a valid X-CSRF-Token in the header. The token value must first be retrieved through HTTP Fetch via a non-modifying request, and can then in this session be used for subsequent modifying requests.
This approach worked correct when initially SUP excluded, and with requests direct invoked against SAP NetWeaver Gateway. Upon including SUP in the system landscape, we received error '403:Forbidden/Location'. Through HTTP sniffing I detected that the SAP session was not maintained over multiple http requests originating from SUP context. SAP Support analysis on the submitted OSS Ticket identified the inability to preserve the complete session cookie as a problem in the SUP 2.1.1 OData layer, and advised us to upgrade to SUP 2.1.3. This indeed resolved the issue.