How to prevent sending custom value to CORS disabled API? - javascript

I get a photo(image file) from my user. I can access to their camera and they will take a photo and send that photo for me. Codes are written in JavaScript.
In my API, CORS is disabled and only requests from my site are valid.
I want to be sure that photo which i will get it, is a photo that is taken via camera(codes are written in JS).
I want to get a image from API endpoint. That value is get from user camera and will be send via ajax request.
Can user send custom value to API if CORS is disabled?
I know that client side user can access JS codes via browser inspector, but can user change JS codes and send custom value to CORS disabled API?

A user can send whatever they want to your HTTP endpoint.
HTTP endpoints are public. You have no control over what is sent to them.
A user could manually construct an HTTP request (e.g. with a tool like Postman or any programming language) and send whatever data they like without involving a browser at all.

Any client (it doesn't even need to be a browser) can send arbitrary values to your API. It does not need to be a photo taken from the camera, it does not even need to be a photo at all. And you cannot prevent that, or force a browser to do anything. That includes preventing savy users from messing with your JS code.
CORS is a client-side security measure implemented in many clients that prevents js code on other domains from accessing your API with the user's credentials. It does not help you here.

Related

How to securely cross domain submit a form from a static html site to a server side backend?

I'm wanting to create a series of static HTML sites which will be hosted at on Amazon S3.
The static sites will have forms. My plan is to post/ajax submit the form data to a server side application hosted on a different domain. The server side application will store the data in a database for future reference as well as email the submitted data to the relevant person.
At face value this is simple, the HTML form just needs to POST the data to the server side script, similar to google forms/wufoo/formspree etc.
My concern is with the security implications of this. The post will be cross domain from the static site, which seems to make CSRF difficult to implement in popular web frameworks. I've read many blog posts on CSRF/CORS/Authentication but am no clearer.
From studying formspree.io's source code, it seems they check the referer and origin headers to verify the form submission is coming from the website it should be and a website that is registered. However I understand these can be spoofed?
As any javascript code on the static site can be read and reverse engineered, API style authentication seems difficult...
Or am I overthinking this, and if I post the form via SSL, validate the form data server side, check the referer/origin headers as per formspree it should be secure enough?
TLDR; For a static HTML site posting form data to a server side backend for storing in a DB and emailing, what security steps do I need to take?
Thanks in advance!
Optimal Solution
It appears that the optimal solution in your case is doing the following:
Implementing a Recaptcha.
Sending the request to a script of your own first, that validates the captcha and then forwards the request.
Adding Access-Control-Allow-Origin only your HTMLs' origins only. useful question
CSRF Protection
As a matter of fact, It's pretty difficult to build a secure application if you only have access to the client side. If the services you're posting to doesn't have a built-in CSRF system, It'd be a good solution if you add a recaptcha to your HTML page and create a simple php script that will receive the form fields, validate the recpatcha and submit the form fields to whatever destination you want.
A CSRF protection through a token would also do the trick and actually it's the clean-coding solution if you eventually submit to your own script first, still, it would be somehow difficult to implement it into static HTML pages. (You'll need to generate it through Javascript or a php script, store it in your session, then validate it in your backend script) but I'd recommend it if you are able to code it.
In both cases, you'll need to submit to your own script first and then forward the request through CURL.
Validating Headers
In your backend script, you can validate the referer and origin to make sure the requests aren't coming from a different source other than your HTML forms.
Summary
The recaptcha will prevent anyone from doing a CSRF attack against your users.
In case the attacker was trying to find a workaround the origin and referer checking, they might use something like CURL, the recaptcha will also prevent them from doing that.
The Access-Control-Allow-Origin Implementation will prevent attackers from submitting data to your page through javascript.
Submitting to your own script first will also prevent anyone from knowing where exactly you're submitting these data, which will make it harder for them to perform an attack.
Although the captcha isn't a very user-friendly solution, if you have the ability to code a CSRF protection system it needs to be done through either javascript, or sending an ajax request that generates a token unique to user's session then you can validate that token inside your other PHP page, but you'll need to implement the captcha to prevent spamming anyways.
On your server, you need some middleware to make sure that the request origin is one that is trusted. So if your static html site is www.mysite.com, make sure that on the server www.mysite.com is allowed access to your apis. As far as authentication goes, if you don't want just anyone accessing your apis, you need some type of authentication. Basic flow kind of looks like this:
User posts login data, server authenticates, server generates token and sends back to client in response, token gets stored on the client and set in the header with any requests being made. Then on your routes, you will need some middleware to check if a token is present in the request header, if so, allow access, if not, deny it.
Hope that clears some stuff up.

How to safeguard credentials when doing authenication for a javascript/jQuery API client?

I need to call a web service from my client side JavaScript code (which will run as a web page is loading). I understand there are libraries for doing this like this one, or I can just use straightup jQuery as described here.
But one concern I had was authentication. I need to send the webservice a username/password or a authorization header as described here. Now if this will not come from the user, it seems that it needs to be stored somewhere on the browser side code in order for it to be sent when that code runs (client side).
Won't this then be in the clear for all to see just by doing a view source on my page? If so, how can I prevent this?
Well you can encode the user name and password so if someone sees the view source of the web page it will show the encoded credentials.
To encode/decode the credentials you can use the atob and btoa Javascript functions. They are present in the JavaScript implementation of most browsers. See this link: https://developer.mozilla.org/en/docs/Web/API/WindowBase64/Base64_encoding_and_decoding
When sending the credentials to the server you can decode the data before sending the credentials.
To ensure that the credentials are not read during transmission, they should not be sent in plain text. HTTPS can be used to secure the web service requests.

Hide headers on client side request

We will be using react to consume endpoints that request a header to be attached for authorization. The endpoint will be called client-side.
This header key should be secret. However, if the user opens up a terminal she will be able to inspect the request and see the header. Is there a way to hide this header?
One way could be to encrypt this and decrypt on the other side. Is there another way to hide the header via javascript?
Is there a way to hide this header?
No. It is not possible to give something to the browser without giving it to the user. The user has complete control over the browser.
If you do not trust the user to access the endpoint, then you can't trust their browser to either.
One way could be to encrypt this and decrypt on the other side.
Not really. That just changes the string that the user has to send to the endpoint in order to access it. You are still giving them that string.

Differenciate Between User Requests and AJAX/Resource Requests

I'm attempting to create an app with Node.js (using http.createServer()) which will be a single page application with requests for data via XMLHttpRequest. To do this I need to be able to differentiate between a user navigating to my domain, and AJAX requests and requests generated by the browser for linked resources.
If the request is from the user I always want to return the index.html page which will handle requesting content but if the request is browser generated or AJAX and is for CSS, Javascript or other linked files I want to serve those files. Is there any way to detect this?
Looking at the request headers for the different file types I saw the referer header appeared when the request for content was generated by the page. I figured that was the solution I was looking for but that header is also set when a user clicks on a link to the page making it useless.
The only other thing which seems to change is the accept header which could sort of work but might not be a catch all solution. Any user requests always seem to have text/html as the preferred return type regardless of which url was entered. I could detect that but I'm pretty sure AJAX requests for html files would also have that accept header which would cause problems.
Is there anything I'm missing here (any headers or properties I can look for)?
Edit: I do not need the solution to protect files and I don't care about users bypassing it with their own requests. My intention is not to hide files or make them secure, but rather to keep any data that is requested within the scope of the app.
For example, if a user navigates to http://example.com/images/someimage.jpg they are instead shown the index.html file which can then show the image in a richer context and include all of the links and functionality to go with it.
TL/DR: I need to detect when someone is trying to access the app to then serve them the index page and have that send them the content they want. I also need to detect when the browser has requested resources (JS, CSS, HTML, images, etc) needed by the app to be able to actually return the resource not the index file.
In terms of HTTP protocol there are NO difference between a user-generated-query and a browser-generated-query.
Every query is just... a query.
You can make a query with a command line, with a browser, you can click a link, send some ascii text via telnet, request a proxy which will make the query for you, the server goal is never to identify how the query was requested by the user.
See for example a request made by a user on a reverse proxy cache, this query will never reach your server (response comes from the cache), the first query made to build this response could have been made by a real user or by a browser.
In terms of security trying to control that the user is never requesting data by-himself cannot be done by detecting that the query is a real human click (and search google for clickjacking if you want to be afraid). Every query that a browser can make can also be played by the user, every one, you have no way to prevent that.
Some browsers plugins are even doing pre-fetching, detecting links on the page and making the request before you do it yourself (if it's a GET query).
For ajax, some libraries like JQuery will add an X-Requested-With: XMLHttpRequest header, and this is used on most framework to detect ajax mode.
But it is more robust to depend on a location policy for that (like making your ajax queries with a /format/ajax, which could also be used on other ways (like /format/json, /format/html, or /format/csv).
Spending time on a location policy based routing is certainly more usefull.
But one thing can make a difference, POST queries are not indempotent, it means the browser cannot make a POST query without a real user interaction, because a POST query may alter the state of the session or the state of the server data (but js can make POST queries, this is just a default behavior of browsers). The browser will never automatically retrieve a POST query, so you could make a website where all users interactions are POST queries (via forms or via some js altering link clicks to send POST ajax queries instead). But I'm not that's your real goal.
Not technically an answer to the question but I found a simple solution which does what I want: prefix all app based requests with a subdomain eg. http://data.example.com/. It's then really simple to check the host header for that subdomain: if present send the resource else send the index page.

Avoiding cross-domain Check and Other Browser Security Checks

We're developing a Dynamics CRM 2011 product that has a button in the ribbon that calls an external API. Currently, for this button to work, the following settings need to be changed in the browser (IE):                
We would like to avoid this, because many of the target customers for this product are very security conscious. Is there a way to write the code so that it will not require these permissions to be changed, but still be able to communicate with the external API? The code running when the button is pressed in CRM is HTML and Javascript.
Thanks!
Are you in control of the API? If so, look into CORS. With CORS, all you do is basically add a few extra headers to your request response. If you use an AJAX library (like jQuerys $.ajax), you should be able to continue writing code as is. If not, a good article on how to implement cors in Javascript can be found here: http://eriwen.com/javascript/how-to-cors/
To enable cors, read up on http://enable-cors.org/
I don't know anything about this CRM, but other than JSONP, your best bet is to have a server side script act as a proxy.
So, you would create a script within the same domain as the user interface code. That script will then use a server side language (such as PHP) to perform the request to the cross domain script on your behalf. The server side connection has no restriction on which domain it can access, and all the browser knows is that it is sending a request to a page within the calling domain, which is presumably safe.
How you will do this depends on the exact language of choice, but in general you would just need to send the remote API URL as well as any arguments needed to your server side script, which then rebuilds the request to that URL and passes the result back to the client.

Categories

Resources