Is this CORS handler safe? - java

I wrote this trivial method to handle CORS in a simple server proxy of mine.
private void handleCors(HttpServletRequest req, HttpServletResponse resp) {
final String origin = req.getHeader("Origin");
if (Strings.isNullOrEmpty(origin)) {
return;
}
if (!origin.startsWith("http://localhost:")) {
return;
}
resp.setHeader("Access-Control-Allow-Origin", origin);
resp.setHeader("Access-Control-Allow-Credentials", "true");
resp.setHeader("Access-Control-Expose-Headers", "Authorization");
resp.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type");
}
It's not needed for the real application, it's only used when testing manually (with ionic serve). I guess, it is safe because of doing nothing except when the origin is localhost, but better safe than sorry.
Moreover, findbugs complains about response splitting vulnerability. Should I simply use URLEncoder.html#encode or is there more to it?
Would in general removing spaces or adding no CORS headers in case of contained spaces do?

CORS is safer and more flexible than earlier techniques such as JSONP.
WebAPI works great straight out of the box for GET requests. However, once you start using it for POST, PUT or DELETE operations, then CORS kicks in and drops requests from hitting the server. CORS stops any cross domain requests so if your api is running at www.myapi.com and a request from www.mywebsite.com comes in, the request will be dropped. This is a security feature to ensure that requests from unknown domains cannot hit the server.
If you are using a web client to execute ajax calls, then there is one more thing you need to add to your ajax call to ensure that CORS words on all browsers.
$.support.cors = true
crossDomain: true
Resource Link:
How to Implement Cross Domain Requests (CORS) in WebAPI, old school?
But in a single line, if we want to say then CORS handler is not safe.
Already #zapl has given info about this.
Now I am trying to give you some attack type with some scenerios. Hope it will give you clear information.
CORS (In)security?
Several security issues arise from the improper implementation of
CORS, most commonly using a universal allow notation (*) in the
server headers.
Clients should not trust the received content completely and eval or
render content without sanitization which could result in misplaced
trust.
The application that allows CORS may become vulnerable to CSRF
attacks.
Prolonged caching of Preflight responses could lead to attacks
arising out of abuse of the Preflight Client Cache.
Access control decisions based on the Origin header could result in
vulnerabilities as this can be spoofed by an attacker.
CORS Security - Universal Allow
Setting the 'Access-Control-Allow-Origin' header to *
Effectively turns the content into a public resource, allowing
access from any domain.
Scenarios:
An attacker can steal data from an intranet site that has set this header to * by enticing a user to visit an attacker controlled site
on the Internet.
An attacker can perform attacks on other remote apps via a victim’s browser when the victim navigates to an attacker controlled site.
CORS Security – Misplaced Trust
Data exchange between two domains is based on trust
If one of the servers involved in the exchange of data is
compromised then the model of CORS is put at risk
Scenarios:
An attacker can compromise site A and host malicious content knowing site B trusts the data that site A sends to site B via CORS
request resulting in XSS and other attacks.
An attacker can compromise site B and use the exposed CORS functionality in site A to attack users in site A.
CSRF with CORS
Server may process client request to change server side data while
verifying that the Origin header was set
An attacker can use the .withCredentials = “true” property of XHR to
replay any cookies to the application on which the victim is logged
in
Scenarios:
An attacker sets the Origin header or uses a trusted site A to send a non idempotent request to site B.
The victim who is logged into site B when he is viewing the trusted site A causes site B to create a user account without his knowledge
via a CSRF attack.
CORS – Caching of Preflight responses
The Access-Control-Max-Age header is set to a high value, allowing
browsers to cache Preflight responses.
Caching the preflight response for longer duration can pose a
security risk.
If the COR access-control policy is changed on the server the
browser would still follow the old policy available in the Preflight
Result Cache.
CORS – Access Control based on Origin
The Origin header indicates that the request is from a particular
domain, but does not guarantee it.
Spoofing the Origin header allows access to the page if access is
based on this header
Scenarios:
An attacker sets the Origin header to view sensitive information that is restricted
Attacker uses cURL to set a custom origin header:
curl --header 'origin:http://someserver.com' http://myserver.com:90/demo/origin_spoof.php
Here is an example is given. You can go through this link :
https://www.owasp.org/index.php/Test_Cross_Origin_Resource_Sharing_(OTG-CLIENT-007)
Some Security Impacts of HTML5 CORS or How to use a Browser as a
Proxy

Related

How to make sure user is being authenticated from my app with POST request?

I am writing an android app that connects to my server with a POST request. So far, I am using SHA-256 to hash and salt epoch time and use that as a third parameter alongside the username and password to make sure that the authentication is done from the app. However, an attacker could decompile the apk and figure out the salt that I am adding to epoch time, allowing them to make a POST request from wherever.
I am wondering if there is a way to make sure the POST request is being made from my app. Note that I cannot change the authentication method of the server from POST.
Thanks in advance.
HTTP Client authentication is an open process to allow vendors to implement different authentication schemes.
Apart from SSL (when run under HTTP protocol) having is own authentication mechanism (for servers and/or clients) the authentication task on HTTP protocol is managed by the WWW-Authenticate header in the HTTP header protocol. That field reflects if the server demands some kind of authentication and how the peer is going to be authenticated.
This allows peer protocol authentication (not only for the client, but also the server can be authenticated) but it makes HTTP method agnostic, as the authentication procedure is orthogonal to the method used to request information. You can use authentication with any (or all) the http methods (GET, POST, CONNECT, HEAD, PUT, DELETE, etc)
You need to read the RFC's docs: 7230, 7231, 7232, 7233, 7234 and 7235.
The more interesting to you is 7234 (it describes protocol authentication), and the documentation of the web server you are requesting to, and how the service has been configured, to get an idea of the authentication methods it supports or the credentials you must provide to authenticate the client.
Normally, the process is as follows:
the client makes a unauthenticated request of info for the target url.
The server denies the request, signalling authentication must be used, and proposes an authentication method and challenge.
The client redoes the request, but providing the requested credentials from the server.
The server accepts the request or denies it again.
To note is that, depending on the authentication method to use (e.g. BASIC is a simple username/password scheme, while DIGEST forces the user to produce a digest, based on used credentials and some server provided info) you can need more than one roundtrip to the server (the server can force you, while not common, to use two of these in chain to grant you access to the resources)
In the case of Java, probably a good source of documentation is the Apache HttpClient class, and it has some tutorials from Apache that show you how to make authenticated requests. A good reference is this.

CSRF token protection with AJAX GET method

I'm a bit confused from the online information.
I'm using CSRF protection using Spring security on my back-end.
I wanted to ask is it safe to send CSRF token from my angular front-end, while I'm passing the token within HTTP header using Ajax GET method?
Because according to Spring docs I shouldn't use GET method, but on the other hand it doesn't say anything about if it's okay to use GET Ajax when I pass it in HTTP header.
Second,
If I shouldn't use GET, how do I use REST service & CSRF protection? should I give up GET method or CSRF protection?
Since GET requests should not modify any state on the server and should be "read-only" usually CSRF protection should not be needed for GET requests.
The problem about leakage is mostly related to browser usage because GET requests usually do not contain a body and thus the token is sent as request parameter. Thus the CSRF token could be visible through shoulder surfing, stored as a bookmark, appear in the browser history or logged on the server (altough logging also applies to AJAX requests).
Since you are talking about AJAX requests most of this leakage does not apply, although setting it in header may help in case of URLs appearing in the logs, but logs could also contain headers.
But actually using a custom header (with or without token) is often used to prevent CSRF attacks because AJAX requests cannot set custom headers cross-domain other than
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type
Thus using a custom header like X-Requested-With: XMLHttpRequest which is e.g. set by jQuery and verifying this header on the server can prevent CSRF attacks.
Last but not least there is one interesing article about having the same token for GET and POST requests and having same-origin access to the GET request via an XSS vulnerability of a separate web application in the same origin where the token can be leaked from the GET request and used for a POST. The solution there is to either not use CSRF tokens for GET or use different tokens for GET and POST.
Basically regarding your questions, if your GET does not have any side-effects, a CSRF token is not really needed but would not hurt. On the other hand, if your GET request changes something on the server, you should think about using another verb (e.g. POST) depending on what you want to do and then protect your POST requests with a CSRF token or a custom header.

Is it a good practice to check referer in the server-side form submission handler?

I am doing a Java web site. I hope to make the web site safer.
In my web site, all the forms are supposed (by design) to be opened in a page through a GET link from my website. I hope to check whether the referer is my web site in my server-side form submission handler. The idea is to avoid taking data from attacker-locally-generated form submission.
I feel that the key to this approach is whether the referer the server detects is reliable.
I understand that there are other ways to improve security. Let's just focus on the approach in my post.
Thanks for any input!
UPDATE
Specifically, I am doing a Spring MVC web site. I am using an interceptor to examine all traffic, especially the form submission.
No, it is not reliable. Some browsers may allow removing the referrer, or might not send it at all. And a naughty person can easily just add the referrer to the requests, so by itself it will not give any extra security except from random people trying random things.
Not the best way, but referer checking can help prevent Cross Site Request Forgery attacks:
Although it is trivial to spoof the referer header on your own
browser, it is impossible to do so in a CSRF attack. Checking the
referer is a commonly used method of preventing CSRF on embedded
network devices because it does not require a per-user state.
[snip]
...checking the referer is considered to be a weaker from of CSRF
protection. For example, open redirect vulnerabilities can be used to
exploit GET-based requests that are protected with a referer check and
some organizations or browser tools remove referrer headers as a form
of data protection.
Remember here that the attacker is not the one sitting at the keyboard - it is harder for them to spoof the referer from the victim's machine.
The strongest way of preventing CSRF though is the Synchronizer Token Pattern.

Is Access-Control-Allow-Origin sufficient in preventing XSRF attacks?

We're building an app with a Java Spring/Hibernate backend running in JBoss. The frontend is AngularJS.
We haven't yet done anything to setup XSRF tokens on the server end. We also don't (not yet anyway) have a requirement to allow other domains access to our web resources.
I figured I'd try to see if our site was vulnerable to an XSRF attack so I set up a malicious webapp to post to one of our real app's urls using Angular's $http.post(). I logged in to the real app, then I tried posting from the malicious app.
In the browser I got a 401 response and saw the error:
XMLHttpRequest cannot load http://localhost:8080/user/delete. No
'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:6543' is therefore not allowed access. The response
had HTTP status code 401.
The server side isn't setup to set Access-Control-Allow-Origin on the response thus the above error.
So my question is, is simply omitting Access-Control-Allow-Origin from the response header adequate to prevent XSRF attacks?
Is there a way I could still do an XSRF attack on my site even though Access-Control-Allow-Origin is not set? If so how? I'd like to demo this attack.
Thanks.
No, this is not sufficient. Even though the browser gives the 'Access-Control-Allow-Origin' error, the request has still been made by the browser. If withCredentials is specified by the attacking page:
$http.post(url, {withCredentials: true, ...})
then this request will be sent to your domain with the victim's authentication cookies, meaning that the request to http://www.example.com:8080/user/delete will succeed.
Also, this request could also be made without XHR using a standard HTML form:
<form method="post" action="http://www.example.com:8080/user/delete">
and JavaScript would just be used to submit the form rather than making the request itself.
An easy way to protect your system against CSRF is to check for a custom header such as X-Requested-With or the Origin header. X-Requested-With cannot be sent cross domain without enabling CORS server-side. However, the Synchronizer Token Pattern is still the strongest method of CSRF prevention as this is not subject to flaws in browser plug-ins such as a previous flaw in Flash that allowed headers to be sent that weren't normally possible from a browser.

Is it possible to add headers for CORS at the calling side server?

I have a GWT appilcation in which the client makes a request to another domain.
I wrote the request using RequestBuilder in GWT.
On executing the code, I get an error in my browser :
No 'Access-Control-Allow-Origin' header is present on the requested resource.
So I google and I found that the domain to which I am making the request should add this header in the response that it sends. Now I dont't have control over the other domain's server, so I can't do any modification there.
My question is, can I intercept the response and the Access-Control-Allow-Origin header to the response that is being sent by the other domain's server at my server, before I send it to my client?
I tried using Filters but the Filter doesn't get called for responses coming from another domain.
Is this possible to do, am I missing something or is it just not possible?
Vivek's answer that cross domain requests aren't allowed by the browser is true, except for the CORS mechanism, whereby newer browsers that support it can try in a cross origin way to servers that also support it.
However, unless that remote server support it itself, there is nothing you can do. If I server my app from A, and want to connect to B, only B can authorize that. If A were allowed to permit my app to connect to B via some filter or servlet, then I could write an app that makes calls to gmail or facebook or twitter and read/write your settings and personal data at those other urls.
So instead, it is the cross origin server that you are contacting that must approve the connection with the header you mentioned. In lieu of that, you can still use your own server as a proxy for the cross origin server.
Cross-domain requests are forbidden by web browsers as per the same origin security policy. These restrictions are limited to browser based applications and hence you can definitely use your own server application as a filter between the GWT based client side application and the external server.

Categories