Uploading files on web from client without revealing API key - javascript

I'm trying to upload a file from a web application to an external source (such as scribd) for example. to upload the file I need to send the API key as well. however if i send the API key from the client it will be revealed to users who search for it on the client side.
How could I upload from client using an API key that I don't want to reveal to users? It seems redundant to upload it to my server and then to the external source.

As redundant as it may be to pass through your server, it's the only way. You can't use the key client-side and hide it from the client, and if you don't use HTTPS it can easily be intercepted too. As a side note, I don't know about Scribd but usually stealing API keys is not very useful, so you may just live with the "risk".
Edit:
apparently Scribd offers a way to provide encrypted requests so that your API key can't be deduced by them (you have to generate these remotely and send them to the client of course). See http://www.scribd.com/developers/api?method_name=Signing

Related

How to secure when make a call to DialogFlow from Client side (browser)?

Where to save security information when I want to send a Web API call to DialogFlow from Browser? I use Angular.
I have a backend of the application, but I don't want to send the request through my backend (don't want to pay for the additional traffic).
Is it even possible to make a secure call from a browser?
Are there any techniques I could apply to achieve this? As I know DialogFlow uses Google Cloud (GCP) behind the scene, are there any recommendations from GCP (so far can't find any)?
Anything sensitive you need to store client side is out of your control, and therefore you need to assume it will be compromised.
If the API can be called from your server instead of the browser then you can store the token on the server to protect it, but this depends on what the API is used for.
It appears their documentation on accessing the API can be found here: https://dialogflow.com/docs/reference/v2-auth-setup#getting_the_service_account_key

How to prevent sending custom value to CORS disabled API?

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.

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.

Write PDF files from Web-App to USB-Stick

I am concerned with the feasibility of this:
On a pre-configured machine I will have a Web-Application pre-installed, next to an Apache-Suite. So client and server are the same!
In this Web-Application Users can drag and drop PDF-Files to an USB-Icon.
Then the Web-App should write the dropped PDF to an attached USB-Stick.
I have never done something like this (writing to USB), so I am fairly insecure.
And I am well aware of the browser-restrictions concerning JavaScript and Filesystem-Access, but...
after researching a bit I found out, that there might be some possible and
relevant (I'm a Web-Platform-Guy) solutions to this:
Make a "Chrome App" with USB-Permission (does this really work?)
Use PHP to find the USB and then write to it (how would that work under Windows?)
Use some Flash as middle man (not preferred)
Now I'd like to know:
Has anyone some good experience with before mentioned possibilities?
Has anybody ever done something similar? Did it work? Which path did you choose?
How would I know which drive the USB is mounted, and how would I get sure?
What other possible solutions to this problem are there?
You have a website ('client-side' user interface) and a back-end server ('server-side') running on the same machine. This gives you 2 options:
Client-side: Download a file through the browser via HTTP GET and let the user choose where they save it.
Server-side: Build your USB interactions into the back-end (Node.js) code, as #mcgraphix suggests.
Interacting with the USB on the server-side provides the most flexibility. Furthermore, there are a number of libraries that you can leverage. Head to npmjs.org and consider, among others, the following Node.js server-side packages:
usb-detection
usb
With the server-side approach, initiate a Webservice request when the user completes the drag & drop action on the client, and implement the USB interaction within the server (Express.js or similar) method which services the request.
If the letter of the stick is known then writing a file from PHP will be simple
file_put_contents( 'E:\\folder\\file.pdf', $data );
Update
You can read a list of drives into a dropdown and allow a user to select a default drive to write to
https://stackoverflow.com/a/8210132/696535
Your question is more an architecture question than a code specific question.
Your web app (if you insist on a web app) should have two major components, a server side component that can be given arbitrary commands, and a client side component (javascript using XMLHttpRequest) that can make requests to the server side component to execute said arbitrary commands.
So your server side component, the component that serves your web page should have some server side code that can write your pdf to the file system, it should probably generate the pdf file as well rather than doing that on the web browser.
Which technology you use is up to you, whether that's PHP, .Net, Node.js etc...
The general gist is you want a server side framework that deals with HTTP requests, in your case probably a post request from the client side containing the encoded pdf, and responds accordingly. Bind a particular http route to trigger your save logic.
Your http post request to the server will contain your payload which is the pdf file to a particular path, e.g. http://localhost/savepdf that whichever technology stack http listens to (you'll need to configure that)
Your server side component should read the incoming data, decode it as appropriate then make a file system request to write the received payload to disk.

Web services API Keys and Ajax - Securing the Key

This is probably a generic security question, but I thought I'd ask in the realm of what I'm developing.
The scenario is: A web service (WCF Web Api) that uses an API Key to validate and tell me who the user is, and a mix of jQuery and application on the front ends.
On the one hand, the traffic can be https so it cannot be inspected, but if I use the same key per user (say a guid), and I am using it in both then there's the chance it could be taken and someone could impersonate the user.
If I implement something akin to OAuth, then a user and a per-app key is generated, and that could work - but still for the jQuery side I would need the app API key in the javascript.
This would only be a problem if someone was on the actual computer and did a view-source.
What should I do?
md5 or encrypt the key somehow?
Put the key in a session variable, then when using ajax retrieve it?
Get over it, it's not that big a deal/problem.
I'm sure it's probably a common problem - so any pointers would be welcome.
To make this clearer - this is my API I have written that I am querying against, not a google, etc. So I can do per session tokens, etc, I'm just trying to work out the best way to secure the client side tokens/keys that I would use.
I'm being a bit overly cautious here, but just using this to learn.
(I suggest tagging this post "security".)
First, you should be clear about what you're protecting against. Can you trust the client at all? A crafty user could stick a Greasemonkey script on your page and call exactly the code that your UI calls to send requests. Hiding everything in a Javascript closure only means you need a debugger; it doesn't make an attack impossible. Firebug can trace HTTPS requests. Also consider a compromised client: is there a keylogger installed? Is the entire system secretly running virtualized so that an attacker can inspect any part of memory at any time at their leisure? Security when you're as exposed as a webapp is is really tricky.
Nonetheless, here are a few things for you to consider:
Consider not actually using keys but rather HMAC hashes of, e.g., a token you give immediately upon authentication.
DOM storage can be a bit harder to poke at than cookies.
Have a look at Google's implementation of OAuth 2 for an example security model. Basically you use tokens that are only valid for a limited time (and perhaps for a single IP address). That way even if the token is intercepted or cloned, it's only valid for a short length of time. Of course you need to be careful about what you do when the token runs out; could an attacker just do the same thing your code does and get a new valid token?
Don't neglect server-side security: even if your client should have checked before submitting the request, check again on the server if the user actually has permission to do what they're asking. In fact, this advice may obviate most of the above.
It depends on how the API key is used. API keys like that provided by Google are tied to the URL of the site originating the request; if you try and use the key on a site with an alternate URL then the service throws and error thus removing the need to protect the key on the client side.
Some basic API's however are tied to a client and can be used across multiple domains, so in this instance I have previously gone with the practice of wrapping this API in server side code and placing some restrictions on how the client can communicate with the local service and protecting the service.
My overall recommendation however would be to apply restrictions on the Web API around how keys can be used and thus removes the complications and necessity of trying to protect them on the client.
How about using jQuery to call server side code that handles communication with the API. If you are using MVC you can call a controller action that can contain the code and API key to hit your service and return a partial view (or even JSON) to your UX. If you are using web forms you could create an aspx page that will do the API communication in the code behind and then write content to the response stream for your UX to consume. Then your UX code can just contain some $.post() or $.load() calls to your server side code and both your API key and endpoint would be protected.
Generally in cases like this though you proxy requests through the server using 'AJAX' which verifies the browser making requests is authorized to do so. If you want to call the service directly from JavaScript, then you need some kind of token system like JSON Web Tokens (JWT) and you'll have to work out cross-domain issues if the service is located somewhere other than the current domain.
see http://blogs.msdn.com/b/rjacobs/archive/2010/06/14/how-to-do-api-key-verification-for-rest-services-in-net-4.aspx for more information
(How to do API Key Verification for REST Services in .NET 4)

Categories

Resources