I have a website which consumes the rest APIs exposed on the webserver.
This is content website and free to public. Thus, anybody can read the content by navigating on it (which call different REST APIs in the background). At the same time, I am worried that somebody could figure out my endponits from developer tools in the browser and call those (millions of times) to bring my server down. I need to secure my REST apis except from browsers. How do I go about this ?
I like to see the problem separated from your REST api.
Your api is a service on top of wich you'll want to build some security. Therefore, security is not actually affecting the design of your api.
One trivial thing to do is controlling the input flows. There are patterns associated with DOS or DDOS attacks that can be recognised to undertake counteractions. This is what Intrusion Prevention Systems (IPS) do.
Please, take a look here and, if you are more interested in something deeper, here.
If your requests are not authenticated (i.e. your apis are public) I think there's nothing more you can do.
You can secure your HTTP endpoints by using SHA-256 cryptographic algorithms. SHA-256 is more secure and fast enough to be used to secure HTTP calls. Here is a good example of how can you secure your API endpoints by signing the request and response using SHA-256.
Related
We are developing a desktop application in C++ which is distributed to our customers. It will communicate with the server using REST API over HTTPS. We are concerned about network sniffing software, such as Wireshark. By using such tools, malicious users could record the HTTPS traffic, extract request URL, headers and body and perform requests to our backend REST API server on their own using automated scripts or Postman.
I read an article which suggests that API keys should be used to identify that requests are really sent from C++ application. However, I don't understand how API keys prevent users from sniffing traffic? If API keys are included in HTTP header, they are still easily extracted by Wireshark.
Are there any other ways for ensuring that requests to our REST API server are actually sent from genuine and unmodified C++ application that we developed? How can we ensure that even if attackers use Wireshark, they won't be able to call REST API on their own using Postman (outside of our C++ application)?
Sending the API key inside a TLS encrypted session (HTTPS) is perfectly safe as the headers are encrypted as well. The only thing that you may find in cleartext is the hostname/SNI of the server.
No, there is absolutely no way to make sure, that the requests are sent from the 'genuine and unmodified C++ application'. But if you want to raise the bar and make it way harder for an attacker to e.g. perform a Man in the Middle (MitM) attack and analyze the traffic, you can do following:
API keys are a good thing. Do it.
Pin the certificates to make MitM attack way harder to perform. Wireshark will see the traffic still, but it will be encrypted.
Obfuscate the code, so even a binary analysis becomes harder.
This will not hold back a motivated attacker, but it will raise the bar significantly and unless you are doing banking apps (which I believe you don't, as banks buy themselves security solutions out of the box from some companies specializing in security design), then it may be simply not worth it to go through all the trouble of attacking apps with such protection.
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.
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.
I am currently implementing a Facebook Chat Extension which basically is just a web page displayed in a browser provided by the Facebook Messenger app. This web page communicates with a corporate backend over a REST API (implemented with Python/Flask). Communication is done via HTTPS.
My question: How to secure the communication the Web page and the backend in the sense that the backend cannot be accessed by any clients that we do not control?
I am new to the topic, and would like to avoid making beginners' mistakes or add too complicated protocols to our tech stack.
Short answer: You cant. Everything can be faked by i.e. curl and some scripting.
Slightly longer:
You can make it harder. Non browser clients have to implement everything you do to authenticate your app (like client side certificates and Signet requests) forcing them to reverse engineer every obfuscation you do.
The low hanging fruit is to use CORS and set the Access Allow Origin Header to your domain. Browsers will respect your setting and wont allow requests to your api (they do an options request to determine that.)
But then again a non official client could just use a proxy.
You can't be 100% sure that the given header data from the client is true. It's more about honesty and less about security. ("It's a feature - not a bug.")
Rather think about what could happen if someone uses your API in a malicious way (DDoS or data leak)? And how would he use it? There are probably patterns to recognize an attacker (like an unusual amount of requests).
After you analyzed this situation, you can find more information here about the right approach to secure your API: https://www.incapsula.com/blog/best-practices-for-securing-your-api.html
I've seen many questions about restful-authentication but I'm wondering what strategies are being used to keep browser user agents stateless while authenticating to a RESTful web-service.
Doing it with a custom REST Client is "easy": We can use Basic Auth, Digest, OAuth or roll your own (custom headers, tokens, signatures etc). Thus, for machine to machine we are pretty much covered but I'm only interested in authentication with everyday browser user agents (IE, Firefox etc). For example JSON is out since the browser can not render / use it ;)
Here are some of my thoughts in terms of browser limitations:
AFAICS there is no way for a browser to send custom headers such as those used by OAuth? (Right?)
I have a feeling that one should be able to have a login page (html+ssl for example) where the user does a login. (No Basic auth) The browser then captures a token(s) and passes it back the server with each request. The problem I have with Basic Auth is that I do not have a “nice custom login page”. Is the current authentication mechanism to extensible that we can keep it restful?
I'm careful in breaking / relaxing REST constraints because of the risk of loosing the benefits of scalability.
A similar answer here but I have a special case against cookies : (without going to much detail): The way browsers currently work in using cookies is out of the question since the server is in control of the cookies. ("Set-Cookie" header from server side state). The client does not understand or interpret the contents of cookies it's fed and just returns it. The problems is that the client is not in control of the cookie. Thus, yes we can use cookies in a restful way in "custom/machine to machine clients" but it's not the way browsers implements it.
What strategies and best practices are there that you have been using and what are your experiences? Any extra comments?
I think the browser limitations you mention are essentially insurmountable for most use cases. Our personal solution is to have a lightweight non-RESTful layer presented to the user which contains a custom REST client; for example, for JavaScript apps we expose a server-side REST client via JSON-RPC.
If you are using an apache web server, you might want to take a look at this document.