Kong response for unauthenticated user

My current Kong test deployment is using Basic Authentication. What I observed with that was that when creating API requests towards endpoints without any/incorrect credentials was that I got the following responses.
An existing API endpoint:
{“message”:“Unauthorized”}
A non-existing endpoint:
{“message”:“no API found with those values”}

Now I was planning to onboard a whole lot of APIs to my deployment most of which I am not in control of nor even have good knowledge about. The thing that worries me is that at the moment basically anybody can from the internet basically map out my APIs without any authentication. To make matters worse I don’t currently have any brute force protection which leads to that somebody could brute force information about which user subscribes to which services in case a weak password is used. In my opinion it is not really responsible to leave it up to the users to select strong passwords as that is often disregarded.

My question is twofold. Firstly, is it possible to configure Kong to always send e.g. unauthorized in case the credentials are invalid ? I have not found such configuration option other than specifying a global error message but that would make troubleshooting cumbersome for legitimate users. I know usually APIs are public and so on but to me this is still essentially not in accordance with one of the basic rules of security: Information should be disclosed on a minimal need-to-know principle. I think violating this principle is in many cases the root cause of vulnerabilties because somebody expects security from the first perimeter and disregards all security on any perimeters behind it. That being said I think non-legitimate users should not get any information out from the system other than unauthorized.

Secondly, how would you recommend to in practice implement brute force protection in Basic Authentication ? I am thinking of switching to Oauth2 but in the meanwhile and out of general interest this would be nice to know. AFAIK Kong utilizes rate limitation but that is a global setting so in practice using that I would just introduce a bottleneck to legitimate users. As all messages are authenticated I can really separate login messages either and introduce a delay there. I could of course use fail2ban but that is ineffiecnt for source IP spoofing. I don’t really like banning users because in my opinion that basically enables malicious entities to ban legitimate users. Any good ideas are warmly welcome here :slight_smile:

Hello,

Community member here just wanted to throw out my opinions.

Be sure to use TLS 1.2 or greater, I believe TLS 1.3 is here as well(kong will not support it just yet, until openssl 1.1.1 is out of beta). Encrypted traffic is a must online.

Do not use basic auth in the wild unless you absolutely have to. OAuth2.0 and JWT (my personal favorite, does not require remote call and uses local client crypto)are vastly superior from a security standpoint and are extremely easy to implement from client side in 2-3 lines of code or less. Then you have a ttl based token that does not reveal the “secrets” used to generate them if an attacker were to somehow sniff out that token.

Lastly it is certainly possible to re-code Kong to make the errors generic across the board(can even just overwrite the source code lua files prior to starting Kong where the errors are mentioned otherwise a plugin can handle the transformations for you on the response to clients), but I am not one for security through obscurity, any attacker worth their salt will not be fooled. I like the fact Kong is transparent in proxy and in error codes. Many gateway products out there will throw say HTTP 500 and some cryptic json body response code like 1.1 or 1.2 etc and require you to then refer back to some internal user guide manual about what the heck just happened, which is a very poor user experience for genuine users, so to put them through that is not worth the minimal upside IMO. Non-legitimate users will not get into your API’s simply by practicing proper TLS + secure authentication patterns. Don’t forget to implement some form of security between the gateway and the API provider as well so the API provider application knows the payload came from gateway and was not tampered with, we do this: (https://github.com/Optum/kong-upstream-jwt) :slight_smile: .

-Jeremy

A good start would be to use the request termination plugin on a fallback Route (catching all non-matched traffic). This way you could reply with HTTP 401 to all orphan requests if you wanted to.

Now, it seems that your ask is also to send HTTP 401 in lieu of 403 that Kong sends in case of invalid credentials? If so, then indeed you would have no choice but to make changes to the code yourself, as @jeremyjpj0916 suggested. i18n/customization of error codes is still something we have plans for, but low on the priorities list. @jeremyjpj0916 is also hitting the nail on that this feels like security through obscurity, so make sure your legitimate endpoints are properly secured.

Secondly, how would you recommend to in practice implement brute force protection in Basic Authentication ?

This is something you would have to implement yourself. Kong’s rate-limiting runs after the bundled authentication plugins and as such, limits authenticated requests only. You can inspire yourself heavily from the rate-limiting plugin if you ever go down that road.

Hi,

Thanks a lot for the prompt responses. I totally agree that Basic Auth shouldn’t be used and I am very much planning to remove that as soon as I have some basic function testing done. I think we can also forget the brute force protection as that is not such a major issue in practice once basic auth is gone. Thanks for reminding about the security between gateway and API. That is also partially being done but I have to make sure its done across the board.

Now for the error message part I was looking at the fallback route as an option but the problem there is that with that option I would give that particular error message (unauthorized) to e.g. in case an authorized user would try to access a non-existent API endpoint etc. This is not something I want as I want an authorized user to get the best possible error message to describe the issue so that he can take the exact corrective action to fix the issue. At the same time I don’t want a non-authorized user to get any information in an error message other than unauthorized.

I very much agree that security through obscurity is not security and I definitely don’t want that. I would even state that nobody hates security through obscurity more than me (hehe). However here I have to say that I disagree with the statement that giving an unauthorized error message to a user without correct creds would be security through obscurity. I think that is actually very much according to basic security principles. The workaround of fallback route in this scenario might be somehow security through obscurity but in my opinion not the case of always returning unauthorized when no correct creds are provided. I honestly think that would be best also from usability point of view. In that way the user is notified of incorrect creds and that is really all he needs to know. The problem he needs to solve is creds and not anything other than that related to APIs and whatnot.

Now I would really want to avoid modifying the lua files for maintainability reasons. @jeremyjpj0916 you mentioned “a plugin can handle the transformations for you on the response to clients”. Is this an existing plugin or are you suggesting that I should write such a plugin =) I am thinking that maybe to accomplish what I want I would need to add a plugin at the end of the chain that would modify the response to the client accordingly as it might be difficult to do that at the first step of processing the request. Please comment on if you think this would be feasible in my case?

BRs, Joona

Such a plugin can certainly be created. You can have a look at the Plugin Development Guide, and specifically, at the request contexts section, which introduces you to the header_filer and body_filter phases. Those are a little tricky to use, so read about them and inspire yourself from existing plugins. They would respectively allow you to change the status/headers of the response, and then its body, even if an authentication plugin previously short-circuited the request.

You could monitor the ngx.ctx.authenticated_consumer variable (see other existing plugins or documentation about authentication) in those phases, and modify the response on-the-fly if it is not set.

Of course to accomplish this, your plugin would need to run last, so set its priority accordingly based on the plugins execution order table (and any other custom plugin you may have).

Thanks a lot for this information. This looks to be a prominent solution for my case. I will look in to this and try to see if I can implement the plugin by looking at some inspiration from existing plugins.