restful Web Parameter Tampering - rest

I am trying to understand how I can implement security using a restful client for an authenticated user. The scenario I am having trouble is how to stop a user from updating a purchase that's not his own since the restful client passes a purchase id back. The product id can be easily tampered with for a skilled user. I am not really interested in being caught in the middle since using https prevents that or mitigates it. I am really interested in a user trying to update what's not theirs.
How do you prevent such attacks in the rest world? Web Parameter Tampering

The problem you are facing is called authorization. Once the user is authenticated it is authorization that grants him permissions to access particular resources. Authorization in a REST scenario should be implemented on the server side.
Let's say user Bob tries to modify a purchase resource by sending an authenticated (e.g. using Basic HTTP Auth, authorized session cookie, etc.) POST request to /purchases/1 endpoint (supplied with appropriate payload). It is the server's duty to validate if Bob is allowed to modify the entity (e.g. by checking if it was really Bob who made the purchase). If the permission is granted the server proceeds with the operation and responds with 2xx success HTTP status code. Otherwise 403 error code will be returned informing that the user is not authorized to modify the given purchase.
Once the authorization mechanisms are established another problem arises: users posting malicious input to try to trick and overcome the authorization mechanisms. This touches a very broad topic of web application security. There are a lot of known attacks on webapps (e.g. injection attacks) and even more ways of protecting against them. Testing applications for security vulnerabilities is called penetration testing. It's worth mentioning that there are automated tools that perform such tests (and also automated tools for performing such attacks).
In general you've touched a very broad topic and there's no way for an SO answer to explain a millionth of it. Treat this answer as a starting point for your own investigation in the area.
Reference
Nice post on SO about REST authentication
The Open Web Application Security Project worldwide not-for-profit charitable organization focused on improving the security of software
OWASP's Guide To Authorization
OWASP's REST Security Cheat-Sheet
List of HTTP status codes
[Edit] REST statelessness
API is stateless when no application state is stored on the server (as opposed to resource state). Click here for a nice explanation of the difference between these two. There's a lot of discussions out there about statelessness (particularly in context of authentication) - look up SO or Google.
In a nutshell stateless authentication in REST is very important given today's large distributed systems. The server-side application state in such environments might cause scalability problems when it comes to sharing it across many nodes in clustered environments. This is why it's advised to make the application state completely client side. I know it might be confusing for you at first, especially after what you've read in my answer that server should authorize user actions. Here is an example of a stateless authentication implementation (digitally signed self-contained session token).
But fear not - in practice most of the systems out there store at least some part of the application state on the server (AFAIK Google does this in their systems). So like stated in this answer:
"REST is not a religion (...), you should only follow the tenets of REST as far as they make sense for your application"

Related

Best practice for securing a client side call to an API endpoint

I'm building an application where I need to make a request in the client-side frontend app to an external API, and I'm at a bit of a loss for how to make this maximally secure so that only valid requests can be forwarded to this external API and not whatever anyone wants.
As a first step in security, I've made it so that the client-side app can't speak to the external API directly, but must instead hit our own server-side API, which then proxies the request to the external API, so that the credentials for hitting the external API are at least stored solely server side and not client side.
This, however, has led to the same fundamental issue - how do I secure whatever credential/authentication system I use to authenticate requests I make from the client-side app to our own server-side app?
The issue is this is an online restaurant ordering service, and so we don't expect users to authenticate themselves with say, usernames and passwords before being able to place orders necessarily, and so order placement, which triggers the external API call, isn't gated behind any username/password scheme, and must be available to all consumers of the frontend app.
What's the best practice for security here? I've enabled CORS whitelisting as a minimum practice, such that only requests from our own domain are theoretically allowed by our server side API endpoint, but CORS is trivially bypassed if someone chooses to just spoof the origin URL.
What other options are available? I'm sure I must just be missing something trivial, since this must be an extraordinarily common issue with an established best practice, but I'm just somehow failing to find it.
Thank you!
As a Developer Advocate for API and Mobile security, seeing a developer that really cares about their app security always makes me smile, especially when they already show some effort was made to secure it, therefore accept my congratulations for your efforts.
My Answer Context
I'm building an application where I need to make a request in the client-side frontend app to an external API, and I'm at a bit of a loss for how to make this maximally secure so that only valid requests can be forwarded to this external API and not whatever anyone wants.
So, you have not detailed if it's a web app or a mobile app, and once my expertise relies on mobile and API security I will be answering with the assumption that is a mobile app.
The Challenge
The issue is this is an online restaurant ordering service, and so we don't expect users to authenticate themselves with say, usernames and passwords before being able to place orders necessarily, and so order placement, which triggers the external API call, isn't gated behind any username/password scheme, and must be available to all consumers of the frontend app.
You have here a complicated challenge to solve, because you have an app that is open to the public, no user authentication/identification of any sort, but that requires rules of access to the underline resources as if it was behind user authentication and authorization, but even if it was, it would still be vulnerable to being abused.
To understand why I need to clear a misconception that usually I find among developers of any seniority, that is about the difference between who and what is accessing an API server.
The Difference Between WHO and WHAT is Accessing the API Server
I wrote a series of articles around API and Mobile security, and in the article Why Does Your Mobile App Need An Api Key? you can read in detail the difference between who and what is accessing your API server, but I will extract here the main takes from it:
The what is the thing making the request to the API server. Is it really a genuine instance of your mobile app, or is it a bot, an automated script or an attacker manually poking around your API server with a tool like Postman?
The who is the user of the mobile app that we can authenticate, authorize and identify in several ways, like using OpenID Connect or OAUTH2 flows.
Think about the who as the user your API server will be able to Authenticate and Authorize access to the data, and think about the what as the software making that request in behalf of the user.
So, in your case you cannot identify who is in the request, thus you need a solution that is able to give a very high degree of confidence to the API backend that the request is indeed from what it expects, a genuine and unmodified instance of your app.
Possible Solutions
I'm building an application where I need to make a request in the client-side frontend app to an external API, and I'm at a bit of a loss for how to make this maximally secure so that only valid requests can be forwarded to this external API and not whatever anyone wants.
This requires very advanced solutions to properly secure, thus isn't at all trivial to achieve as you may think:
I'm sure I must just be missing something trivial, since this must be an extraordinarily common issue with an established best practice, but I'm just somehow failing to find it.
And yes, it's a common issue that often is neglected or not addressed properly, and the first step to solve it is to have a clear picture about the difference between who vs what is in a request, otherwise the devised solutions will fail to address the issue properly.
For Mobile Apps
Here I recommend you to go through this answer I gave to the question How to secure an API REST for mobile app?, especially the sections Hardening and Shielding the Mobile App, Securing the API Server and A Possible Better Solution.
This answer will show you several solutions, like WAFs and UBAs, but ends with a recommendation to use a Mobile App Attestation concept.
In a nutshell the Mobile App Attestation will allow the API backend to have a very high degree of confidence that the request is indeed from what it expects, a genuine and modified instance of the mobile app.
For Web Apps
You can learn some useful techniques to help your API backend to try to respond only to requests coming from what you expect, your genuine web app, and to do so I invite you to read my answer to the question Secure api data from calls out of the app, especially the section dedicated to Defending the API Server.
Do You Want To Go The Extra Mile?
In any response to a security question I always like to reference the excellent work from the OWASP foundation.
For APIS
OWASP API Security Top 10
The OWASP API Security Project seeks to provide value to software developers and security assessors by underscoring the potential risks in insecure APIs, and illustrating how these risks may be mitigated. In order to facilitate this goal, the OWASP API Security Project will create and maintain a Top 10 API Security Risks document, as well as a documentation portal for best practices when creating or assessing APIs.
For Mobile Apps
OWASP Mobile Security Project - Top 10 risks
The OWASP Mobile Security Project is a centralized resource intended to give developers and security teams the resources they need to build and maintain secure mobile applications. Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.
OWASP - Mobile Security Testing Guide:
The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.
For Web Apps
The Web Security Testing Guide:
The OWASP Web Security Testing Guide includes a "best practice" penetration testing framework which users can implement in their own organizations and a "low level" penetration testing guide that describes techniques for testing most common web application and web service security issues.
Ultimately your client needs to perform some operation on 3rd party API.
So we know that some operations should be allowed, and based on your description we also know that not every operation should be allowed.
So your security should be based on this premise. Don't create a dumb proxy that forwards every single request, but your intermediate API should only specifically allow the operations that you want it to allow, based on the rules you set.
If you don't have a username & password, you probably still have some other kind of rule that identifies a person (email/phone number?), which means you can create an authentication system.
Or maybe your 3rd party service should only be called after a user completed an order with a credit card, that logic needs to exist on your API.

How to protect an API endpoint for reporting client-side JS errors against spam (if even necessary)?

I am developing a web application with Spring Boot and a React.js SPA, but my question is not specific to those libraries/frameworks, as i assume reporting client-side JS errors to the server (for logging and analyzing) must be a common operation for many modern web applications.
So, suppose we have a JS client application that catches an error and a REST endpoint /errors that takes a JSON object holding the relevant information about what happened. The client app sends the data to the server, it gets stored in a database (or whatever) and everyone's happy, right?
Now I am not, really. Because now I have an open (as in allowing unauthenticated create/write operations) API endpoint everyone with just a little knowledge could easily spam.
I might validate the structure of JSON data the endpoint accepts, but that doesn't really solve the problem.
In questions like "Open REST API attached to a database- what stops a bad actor spamming my db?" or "Secure Rest-Service before user authentification", there are suggestions such as:
access quotas (but I don't want to save IPs or anything to identify clients)
Captchas (useless for error reporting, obviously)
e-mail verification (same, just imagine that)
So my questions are:
Is there an elegant, commonly used strategy to secure such an endpoint?
Would a lightweight solution like validating the structure of the data be enough in practice?
Is all this even necessary? After all I won't advertise my error handling API endpoint with a banner in the app...
I’ve seen it done three different ways…
Assuming you are using OAuth 2 to secure your API. Stand up two
error endpoints.
For a logged in user, if an errors occurs you would
hit the /error endpoint, and would authenticate using the existing
user auth token.
For a visitor, you can expose a /clientError (or
named in a way that makes sense to you) endpoint that takes the
client_credentials token for the client app.
Secure the /error endpoint using an api key that would be scope for
access to the error endpoint only.
This key would be specific to the
client and would be pass in the header.
Use a 3rd party tool such as Raygun.io, or any APM tool, such as New Relic.

Protecting REST API behind SPA against data thiefs

I am writing a REST Api gateway for an Angular SPA and I am confronted with the problem of securing the data exposed by the API for the SPA against "data thiefs". I am aware that I can't do much against HTML scraping, but at least I don't want to offer such data thiefs the user experience and full power of our JSON sent to the SPA.
The difference between most "tutorials" and threads about this topic is that I am exposing this data to a public website (which means no user authentication required) which offers valuable statistics about a video game.
My initial idea on how to protect the Rest API for SPA:
Using JWTs everywhere. When a visitor opens the website the very first time the SPA requests a JWT from my REST Api and saves it in the HTTPS cookies. For all requests the SPA has to use the JWT to get a response.
Problems with that approach
The data thief could simply request the oauth token from our endpoint as well. I have no chance to verify that the token has actually been requested from my SPA or from the data thief?
Even if I solved that the attacker could read the saved JWT from the HTTPS cookies and use it in his own application. Sure I could add time expiration for the JWT
My question:
I am under the impression that this is a common problem and therefore I am wondering if there are any good solutions to protect against others than the SPA having direct access to my REST Api responses?
From the API's point of view, your SPA is in no way different than any other client. You obviously can't include a secret in the SPA as it is sent to anybody and cannot be protected. Also the requests it makes to the API can be easily sniffed and copied by another client.
So in short, as diacussed many times here, you can't authenticate the client application. Anybody can create a different client if they want.
One thing you can actually do is checking the referer/origin of requests. If a client is running in a browser, thr requests it can make are somewhat limited, and one such limitation is the referer and origin headers, which are always controlled by the browser, and not javascript. So you can actually make sure that if (and only if!) the client is running in an unmodified browser, it is downloaded from your domain. This is the default in browsers btw, so if you are not sending CORS headers, you already did this (browsers do, actually). However, this does not keep an attacker from building and running a non-browser client and fake any referer or origin he likes, or just disregard the same origin policy.
Another thing you could do is changing the API regularly just enough to stop rogue clients from working (and changing your client at the same time ofc). Obviously this is not secure at all, but can be annoying enough for an attacker. If downloading all your data once is a concern, this again doesn't help at all.
Some real things you should consider though are:
Does anybody actually want to download your data? How much is it worth? Most of the times nobody wants to create a different client, and nobody is that much interested in the data.
If it is that interesting, you should implement user authentication at the very least, and cover the remaining risk either via points below and/or in your contracts legally.
You could implement throttling to not allow bulk downloading. For example if the typical user accesses 1 record every 5 seconds, and 10 altogether, you can build rules based on the client IP for example to reasonably limit user access. Note though that rate limiting must be based on a parameter the client can't modify arbitrarily, and without authentication, that's pretty much the client IP only, and you will face issues with users behind a NAT (ie. corporate networks for example).
Similarly, you can implement monitoring to discover if somebody is downloading more data than it would be normal or necessary. However, without user authentication, your only option will be to ban the client IP. So again it comes down to knowing who the user is, ie. authentication.

How to secure Rest Based API?

We intend to develop rest based api. I explored the topic but it seems, you can secure api when your client is an app (So there are many ways, public key - private key etc). What about websites / mobile website, if we are accessing rest based api in website which do not use any login for accessing contents ( login would be optional ) then how could we restrict other people from accessing rest based api ?
Does it make sense using Oauth2.0 ? I don't have clear idea of that.
More clear question could be ,How can we secure get or post request exposed over web for the website which doesn't use any login ?
If it's simple get request or post request , which will return you json data on specific input, now i have mobile website , who will access those data using get request or post request to fetch data. Well, some else can also access it , problem is i am not using Login, user can access data directly. But how can we restrict other people from accessing that data.
What do you think is the difference between securing a website that is not using REST vs one that is using REST API?
OAuth provides authorisation capabilities for your site, in a REST architecture this means a user of the mobile application will have to provide their credentials before being allowed to access the resource. The application can then decide on if that user has access to the requested resource. However you've said your website doesn't need use authorisation.
You can use certificates however good luck managing the certificate for each client. My take on it is for your explanation you don't need to secure your website because you will never be able to manage a trust relationship between the client and the server. There are some options though:
You build your own client application that you ship out to people which can verify itself with the server using a packaged certificate with the client. E.g. iOS has this kind of feature if you build for that device.
You provide a capability to download a certificate that is 'installed' in the browser and used when communicating to your REST API
Use something like a handshaking protocol so when a client wants to make the first request it says; 'hi I'm a client can we chat?' And the server responds with 'yes for the next X minutes we can however make sure you send me this key everytime you tell me something YYYYYY' (you can use something like SecureUDID or equivalent for other devices than iOS).
There are probably others but you get the basic idea. Again in my opinion if your resource doesn't need authorisation then you don't need to secure that REST API. Can I ask what kind of data are you exposing via this REST API or functionality your providing? That might help provide a better answer.
You want authorization: only some agents (mobile clients) and/or users should be allowed to access those APIs.
To solve that problem, you need identification: a way for the server to tell who is who (or what), so the right decision can be made.
There are many different way to provide some form of identification, depending how much you care about security.
The simplest is a user agent string, specific to your mobile clients. But it can be faked easily. Slightly harder to fake are client based 'secrets' - embed some kind of secret or key in your mobile client code. You can make it really complicated and secret, but as ramsinb pointed out, you can't get security this way as it would require you to be able to guarantee that the secret you're shipping with the client (wether it's code, algorithm or any other fancy construct) can't be compromised or reverse engineered. Not happening when you don't control the client.
From there, 3 choices:
Security isn't really required, don't bother
Security isn't really required, but you still want to limit access to your API to either legit users/agents or people ready to invest some time hacking your protection - go with a specific user agent or a client embedded secret - don't invest much into it as it won't block people who really want access to get it anyway
Security IS required - and then I don't think there is a way around authentication, wether it's login/password, user specific (device specific?) keys, OpenID, etc... No matter what, you'll have to add to the user burden to some extent, although you can limit that burden by allowing authentication to persist (cookies, storage....)

Authorizing REST Requests

I'm working on a REST service that has a few requirements:
It has to be secure.
Users should not be able to forge requests.
My current proposed solution is to have a custom Authorization header that look like this (this is the same way that the amazon web services work):
Authorization: MYAPI username:signature
My question is how to form the signature. When the user logs into the service they are given a secret key which they should be able to use to sign requests. This will stop other users submitting requests on their behalf, but will not stop them forging requests.
The application that will be using this service is an iPhone application, so I was thinking we could have a public key embedded in the application which we can do an additional signature with, but does this mean we'll have to have two signatures, one for the user key and one for the app key?
Any advice would be greatly appreciated, I'd quite like to get this right the first time.
The answer is simple: It cannot be done. As soon as you ship any solution to the end user, he or she can allways attack the server it is communicating with. The most common version of this problem is cheating with hi-score lists in Flash games. You can make it harder by embedding some sort of encryption in the client and obfuscating the code... But all compiled and obfuscated code can allways be decompiled and unobfuscated. It is just a matter of how much time and money you are willing to spend and likewise for the potential attacker.
So your concern is not how to try to prevent the user from sending faulty data to your system. It is how to prevent the user from damaging your system. You have to design your interfaces so that all damage done by faulty data only affects the user sending it.
What's wrong with HTTP Digest Authentication?
I think the simplest way to do this right would be to use HTTPS client authentication. Apple's site has a thread on this very subject.
Edit: to handle authorization, I would create a separate resource (URI) on the server for each user, and only permit that (authenticated) user to manipulate this resource.
Edit (2014): Apple changed their forum software in the past six years; the thread is now at https://discussions.apple.com/thread/1643618
There is a better discussion of this here:
Best Practices for securing a REST API / web service