response.setHeader("Access-Control-Allow-Origin", "https://example.com");
I only wanted to allow 'https://example.com' to access my Java servlet with POST request. How do I can enable CORS in IBM WebSphere 7.0.0.27
Thanks
I cannot provide specific informations about Websphere 7, but it is not complicated to write a servlet filter, which handles the CORS preflight requests. Here are two resources that explain the protocol:
http://www.html5rocks.com/en/tutorials/cors/
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
The filter needs to do 2 tasks:
Recognize if the http request is a CORS preflight request.
If it is a CORS preflight request:
set Access-Control-Allow-Origin: https://example.com
set other Access-Control-* header
Hope it helps a bit.
Please have a look at https://www.owasp.org/index.php/CSRFProtector_Project or the CSRF information in General. There is a J2EE filter as well on their page.
You have to build a filter which checks the origin header (if you do it on your own) it is no rocket science, but some browsers do implement the spec differently. Chrome does always set the origin header.
Even with CORS you would still need to protect against the old CSRF attack like auto form submit as this would not set origin header as far as I know.
Related
I have created a web service using dropwizard.
Through this, I am able to create resources, wherein I have created an entity for indexing the document, search request, getting doc by id.
By hitting the API in postman I get the desired result.
For developing the web application I built the front end using ember.js.
But when I send a request to my application I am getting CORS policy exception.
When I am sending request through postman to http://localhost:9090 (9090 is the port number of my ApplicationConnector) then it is responding to the request.
Now when I send request from origin http://localhost:4200 (4200is the default port number for ember.js) to http://localhost:9090 it is giving error :
Access to XMLHttpRequest at http://localhost:9090/{indexName}/{id} >from origin http://localhost:4200 has been blocked by CORS policy: Response to preflight request doesn't pass access control check:
No 'Access->Control-Allow-Origin' header is present on the requested resource.
So can someone please explain how to resolve this issue and if there is any other way apart from enabling CORS in Dropwizard ?
You need to enable CORS in Dropwizard or serve both the frontend and the API from the same host (hostname and port). Otherwise it's forbidden by CORS security feature, which is enabled by default in all major browsers. Postman does not care about CORS.
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.
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
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.
We are using IBM Websphere Application Server 6.1 and browser is Internet Explorer 8.
We have a java servlet which dynamically generates PDF and MS Word documents. On the first attempt some users are saying they are getting
"Internet Explorer was unable to open this site. The requested site is either unavailable or cannot be found. Please try again later."
As per Microsoft Support article id 323308
When you try to open a Microsoft Office document or a PDF document over HTTPS (SSL) IE fails with above error message.
This issue occurs if the server sends a "Cache-control:no-store" header or sends a "Cache-control:no-cache" header.
For IE8 Microsoft suggests to add registry entry on users Windows XP desktop. This is not very practical for us to do as we don't control our users desktops. This does not happen for IE9, Firefox, Chrome, etc.
As per PK20531 WAS 6.1 is adding Cache-Control: no-cache="set-cookie, set-cookie2" and Expires
HTTP headers when there is cookie being set in the response.
Note - We are not setting the cookie in the servlet. The cookie is set by single sign-on software.
On the first attempt when the single sign-on (LTPA) cookie is being set and WAS is adding HTTP headers which IE browser does not like.
Does Java servlet api provide a way to remove http headers? Is there a technique to use Filter api to remove http headers?
If you remove the Cache-Control header from the response, then you're not sending any instructions about caching and therefore the caching behavior would be unpredictable.
It would be better to set the header to something else, rather than remove it. Presumably you want to enable caching on the browser for your pages. So you could add these lines to your servlet to enable caching in the browser:
response.setHeader("Pragma", "cache");
response.setHeader("Cache-Control", "private, must-revalidate");
You could do this in a Filter too, because filters have access to the HTTP response object. But if you've written your own servlet then it's probably more efficient — and clearer — to do it in the servlet.
It's all controllable by you. If you don't put it there, there will be nothing to remove.