XSRF token validation - javascript

Since XSRF validation involves matching of cookie/token sent in the UI request with the request header as part of that same request, what are the options for testing locally?
So assuming I run my UI locally and I am pointed to server hosted in a different place, the cookie would never be able to read on localhost (since it is a different host). What is the best-practice in this case - is it adding logic on server to identify the Origin and bypassing the check if Origin is localhost ?

What I usually do in such a case is to use /etc/hosts and use a subdomain for my code running locally. E.g. the UI is run on www.example.com and the server is on api.example.com, then in my hosts file I point www.example.com to localhost.
If the cookies are not samesite cookies and the server has proper CORS settings, then in fact it shouldn't be a problem using them from localhost. Your UI won't have access to them, but the browser should send them together with any request to the server. (CORS should allow credentials and the http client of your UI should use something like a withCredentials: true flag)

Related

How to make a request to a server that doesn't support CORS?

I'm working on an Angular web application. I need to make a POST request with a XML body to a server I don't have control over. The request needs an Authorization header. I tried the following:
Send the request directly: It only works when the application is served on http://localhost. Otherwise, the browser shows the following error: Access to XMLHttpRequest at 'server.com' from origin 'my-server.com' 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..
Use a browser extension that adds the missing header to responses: Unsafe, because the extension adds Access-Control-Allow-Origin: * to responses from all domains and that header allows requests from any domain.
Disable browser security: I ran Chrome using this command: chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security. Works when the application is running on a HTTPS server. However, it's unsafe, for the same reasons stated for the previous approach.
Use a third-party proxy: Works for a few requests, but the server blocks the proxy IP because the requests of all clients pass through the same proxy.
My project requires to bypass browser security without compromising security for non-related domains. My project also requires a different IP to be sent to the server by each client. That's required so that if a client overuses the feature, it won't affect other clients.
Is there a way I can add Access-Control-Allow-Origin: my-server.com to all responses or add the header only for a specific server? Is there a way I can redirect each request to a different IP so that the server won't block all my clients? Are there any other workarounds?
For protection of end users browsers block requests to other servers. Yes, you can have a cors browser extension but that is a temporary solution.
You need to set up an endpoint on your server 'my-server.com' to consume your web application post requests. From there you can communicate with the server you don't own and set up your proper auth headers ect.

How to prevent sending Origin HTTP header in Chrome?

Situation:
I have a production web server, let's say https://example.com, configured with CORS with limited set of allowed origins. The set does NOT include localhost origins.
On localhost, developers develop a page/module/whatever that needs to call the production web server via AJAX (even during development). To do that, they run Chrome with CLI arguments --disable-web-security --user-data-dir=chromeNoCors so that Chrome would send AJAX without Origin header.
The problem is that only GET requests are sent without the header. POST requests still contain the header, therefore the production server compares the header value (http://localhost:5678) with allowed set of origins and forbids access to requested resource.
Question:
Is it possible to somehow prevent sending of Origin HTTP header altogether?
I'm aware that there's a workaround to solve this situation by allowing "localhost" (or some specific host that developers will have to add to their /etc/hosts) to the set of allowed origins on production server but I'd like not to do this if possible.
if you guys use chrome try this extension
https://chrome.google.com/webstore/detail/requestly-redirect-url-mo/mdnleldcmiljblolnjhpnblkcekpdkpa
you can modify requests on the fly,even headers
I recommend that you setup a simple "proxy server" (short node.js or python script would suffice). Have this server forward all requests to your remote API server but delete the information about the origin in headers. This is a matter of simple regular expression.
This is simple solution that will be portable to different servers. On AJAX side, all you need is to change the hostname to localhost or IP of your testing proxy server.

How to share cookie between front-end app and backend server?

In a javascript single page application, on first request of the user to the front-end, a cookie is set with Node JS Express.
Credentials are included to requests by adding the "credentials: include" option to Fetch API.
The first render is server-side with React server side rendering.
I can see the cookie in developer tools. It is sent on every request to the front-end, but not to the backend.
Front-end and backend are both node servers. In development they are on differents ports of localhost, (also tried setting a domain in hosts file but no difference). In staging the api server is on a subdomain of the front-server domain. Neither works.
Can they share the same cookie or should I create one cookie for each? I can't seem to set the cookie for the requests to the backend, either because different port in dev or different subdomain in staging.
Ok so I think I figured it out.
Cookies were sent on some requests but not on others. Checking the request method, turns out cookies are not sent when method type is "OPTIONS", which is preflight, and apparently this is normal.
The workaround is to avoid checking cookies if request method is OPTIONS and just send a 200 empty response in this case, so that the real request can proceed, during which cookies will be sent.

CORS error for NODEJS server running on the same machine as domain

I have a NodeJS server running on my machine, and I am trying to access it with ajax from a website running on the same machine. I have getting a cross domain error though:
XMLHttpRequest cannot load http://localhost:3000/games. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.
I have access a different api on this machine, running with php, which the address is
http://localhost/games.
My thinking is that because the nodejs server is running on a different port to apache that is causing the cross domain issue?
Any insight would be great, im new to api development and not sure where to go from here.
It has been suggested to me that I should try use JSONP, but im not sure if this is technically needed, since the api is running on the same machine?
An origin is defined as a combination of URI scheme, hostname, and port number so you're indeed breaking the same origin policy performing a XMLHttpRequest from http://localhost to http://localhost:3000
I'm not very familiar with nodejs but I see five options:
Obviously the easiest thing would be run everything on the same port, not sure if this is possible or not on your scenario.
Use JSONP (only valid for GET requests)
Implement CORS headers (it has some compatibilities issues with IE <= 9 + other corner case anomalies)
Implement a proxy to always communicate to http://localhost from client. Let the proxy deal with http://localhost:3000 and return response to client.
Use an alternative to perform cross domain request as XDomain
Since you need to be able to send POST requests, your only options are:
Implement CORS
Reverse Proxy
php proxy (or whatever language you are using for serving html pages)
The easiest would be to implement CORS if you are using express. Most of the work is done for you, all you would need to do is include the cors module and attach it as middleware.
Reverse proxy is the next solution to look at. What it does is it takes all requests to a given domain or domain/folder and reroutes them to the specified domain, in this case your node server running on a different port. For example, you would route all requests to http://localhost/api to http://localhost:3000. Research Reverse Proxy for the webserver you are using.
The third solution would be to have the webserver serving html also send requests to the node server. I consider this to be a bit too hacky for my tastes because the above two solutions are easy to implement and don't add additional code to the html webserver. However, if you didn't own the target webserver, this would be the only option if the target webserver didn't support CORS.

Jquery: $.getJSON with different url port

I am trying to use $.getJSON with a local app calling another local app on a different port.
For example my app is running on localhost:3000, but I want to make a $.getJSON call to another app running on localhost:3001, in firebug it returns red with a 200 response, but with no data in the response. Is there a way to do this? I tried this....
$.getJSON('http://localhost:3001/dashboard/widgets/marketing_efficiency_gauge.json',
{ key: 'value' }, function(data){
alert(data)
});
Edit: for clarity there are two rails apps involved one on localhost:3000 another on localhost:3001
Second edit: here is the json response for localhost:3001 when I hit it with a browser (say firefox) https://gist.github.com/willfults/7665299
The Same Origin Policy prevents JavaScript scripts from making HTTP requests to different domains. For the purposes of SOP, a URL with the same hostname but different ports (as is the case here) is still considered to be a different domain, and hence requests are not permitted.
What typically happens in such cases is that the browser actually does make the request over the network, but drops the response and sends an error result to the JavaScript.
To fix this, you'll need to implement Cross-Origin Resource Sharing on the localhost:3001 service. In a nutshell, this entails adding a Access-Control-Allow-Origin header to responses listing the domains which are permitted to make cross-domain requests to the service. That is, in this case adding a Access-Control-Allow-Origin: localhost:3000 header to the response from the localhost:3001 service should allow things to work as you expect.
Incidentally, this is why the browser makes the request but drops the result: it needs to request the headers from the server in order to determine whether the JavaScript is allowed to make the request or not (i.e. it needs to check if there's a Access-Control-Allow-Origin header in the response). Why a HEAD request isn't sufficient, I don't know.
The other alternative is to use JSONP. This is potentially simpler to implement on the server side, but has the disadvantages of only working for GET requests, and requiring slightly trickier coding on the client side.

Categories