5

We are raising a SaaS product that allows businesses to setup and orchestrate selling of a certain class of goods/services. This product has an API in its core and an ecosystem of various apps around it. These include web apps (sites) facing the general public, a web-based CMS and an iOS app for sales staff. Our clients can either use these or build their own apps to talk to our API.

There has been a long debate between us as to how the API should be secured. It does have authentication (both API key/secret for apps and username/password for users) and role/permission based authorization. At the moment, no useful response can be obtained from the API (apart from its version) unless the requester authenticates itself. This includes endpoints returning data that is available to the general public such as the list of items for sale.

The moot point is whether the API should require authentication for what is essentially public data.

The arguments for authentication:

  • We can't just keep the API open to whoever wants to call it — even if they can obtain the info anyway by exploiting the public web apps. An open API can be abused or load attacked. Better to control who has access by issuing keys/secrets per client app which will be the first line of defence.

The arguments against authentication:

  • There is no point in restricting access to what is made available publicly anyway (via public facing web apps that have key/secret with the "public" role built in them);
  • Making authentication required does not add value and only creates unnecessary overhead by requiring the public apps implement auth clients, keep keys/secrets and refresh auth tokens. The apps should only authenticate against the API when a user needs to log in (which some clients simply do not need as they use guest checkout);
  • Any concerns of abuse (e.g. exceeding the requests rate limit, load attacks etc.) should be addressed by DDoS protection layer, or the API internally, or both. Authentication is not the right protection from this because a malicious client could obtain app credentials and create troubles to the API anyway, let alone that the rate of auth attempts needs to be limited as well.

Is any of the two positions above horribly wrong or would be laughed at if presented on the market of serious APIs? Is there a right approach here, or are the both approaches sensible in terms of security and could be chosen based on other considerations like convenience/ease to implement?

Greendrake
  • 669
  • 1
  • 8
  • 17

4 Answers4

3

Is any of the two positions above horribly wrong or would be laughed at if presented on the market of serious APIs?

Considering the data that is returned from the API is public information I do not really see why authentication is required, assuming your statement "The moot point is whether the API should require authentication for what is essentially public data." is correct. (The essentially part in that sentence makes me wonder though)

The statement:

'We can't just keep the API open to whoever wants to call it'

is incomplete as it does not describe why. Why can't it be open to anyone? What are you afraid of?

Rate limiting should be implemented obviously and the statement that it should be addressed by the DDoS protection layer in insufficient because you should use the defense in depth approach.

This means that you embed protection in every possible layer (within reason).

An open API can be abused or load attacked.

An example would be to configure the web server that is serving the API with rate limiting as well and not solely rely on the DDoS protection.

Is there a right approach here, or are the both approaches sensible in terms of security and could be chosen based on other considerations like convenience/ease to implement?

Yes, they both are sensible and a cost / benefit approach can be applied here. How much are you willing to invest in order to protect public data?

Jeroen
  • 5,783
  • 2
  • 18
  • 26
  • 1
    Thank you! The "_essentially_" part was referring to the fact that the bare API response is not seen by the general public (admittedly, there is nothing to hide there in terms of security). The apps decide what parts of the data to present in the UI. – Greendrake Mar 04 '19 at 19:53
3

TL;DR: Rate limiting is your only option.

As you are going to have mobile apps and websites as API clients, you will be sending the API key/secret to client devices - including ones potentially controlled by an attacker. You can never rely on the confidentiality of these keys for security decisions. They are just too easily compromised. Sure you can disable and re-issue a compromised key/secret, but given your architecture you will just have to send the new key/secret to the clients where they'll get compromised again. Basically, you're signing up for an endless game of whack-a-mole.

Even if a key/secret isn't compromised, being that you're going to allow 3rd-party clients, you must protect against non-malicious clients that request too much data, whether due to poor design or bugs. So you absolutely need rate-limiting in place - even for authenticated clients.

In short, the authentication that you are proposing provides little if any security, and even with that authentication, you need rate limiting in place. While your DoS protection has to be based on the rate limiting, I would still use the API key/secret to assist in monitoring and debugging.

Neil Smithline
  • 14,621
  • 4
  • 38
  • 55
2

You are missing one important point: It is way easier to exploit a public API. It's relatively easy for a sophisticated attacker to work around rate-limiting. If there is any kind of vulnerability, like SQLi or XXE, it will be detected and abused pretty fast by automated tools, and the abuse will not be traceable to a specific user, if there aren't any.

Martin Fürholz
  • 795
  • 9
  • 21
  • 1
    I hear you, though I don't see why a public API is different in this regard from a public website. Vulnerabilities should be found and killed, not guarded. – Greendrake Mar 06 '19 at 06:11
  • @Greendrake the reality is that breaches are not detected in months. If you have a completely open API it's obvious to me that the probability of breaches will be higher and it's easier for an anonymous attacker to detect vulnerabilities. Consider CVSS if you don't want to trust a random stranger: the Common Vulnerability Scoring System scores vulnerabilities without authentication-requirement much higher than ones with it. With authentication it will be possible to trace them back to a particular user. Also with a public API you could easily end up in a public search engine like shodan. – Martin Fürholz Mar 06 '19 at 10:34
0

Is any of the two positions above horribly wrong or would be laughed at if presented on the market of serious APIs? Is there a right approach here, or are the both approaches sensible in terms of security and could be chosen based on other considerations like convenience/ease to implement?

They are both reasonable positions, and the answer is yes, there is a right approach and you can support both positions: many authentication services have a guest or anonymous user, which is equivalent to unauthenticated access.

Best practices require the guest user is setup with appropriate authorization access rules. To ensure your APIs are convenient to use - if no authentication credentials are provided, then your APIs will assume guest user access. I strongly suggest picking an authentication service that supports the notion of a guest user, as its implementation by default should be reasonably secure, though you will want to follow its configuration recommendations.

Nevertheless, as you observed, introducing unauthenticated access of your APIs does open you up to abuse - rate limiting just the guest user (perhaps from the same IP address) could help mitigate against some situations. I would also suggest taking a look at third party solutions such as Redhat's apiman to see how they manage quotas/throttling. With this approach you can disable the guest user at any time.

HTLee
  • 1,772
  • 15
  • 30