OAuth2 Bearer token used like API_KEY - oauth-2.0

We want to make simple authorization for server-server HTTPS communication (we control both servers) like classic API_KEY: client has hardcoded (in a config) a key which use in every request. Server check if the key is valid.
Our colleague has implemented it like OAuth2 Bearer token (RFC6750)
Authorization: Bearer client_key
So the client has the client_key in the config, it's never refreshed. It works well, we have just a philosophical dispute in the company, if such "hardcoded" Bearer token is along with OAuth2 or not. (Disclaimer: I am not with any side of the dispute.)

The OAuth 2.0 protocol basically defines an access_token - which is a token that is bound in time and permissions - and two protocol "legs":
how to obtain and access token
how to use/present an access token
You do not use access tokens (since your tokens are not bound in any way) and you've only "syntactically" implemented part 2. In fact you don't actually implement OAuth 2.0 in that case. You may present the client_key just as well in an HTTP Basic header or in a query parameter, it has nothing to do with OAuth 2.0 except that you're borrowing (arguably: abusing...) its header name and format.

Related

OAuth authorization code flow security question (authorization code intercepted by a hacker)

Something I can't wrap my head around.
As I understand the authorization code flow is supposed to be more secured than the implicit flow, because the tokens are not directly sent to the client from the authorization server, but rather retrieved by your backend.
So the flow is basically:
Browser gets the authorization code (as a URL parameter of sort).
Sends it to a public backend endpoint.
The backend sends the code + client secret to the authorization server, retrieves the tokens and stores them in the client's cookie/local storage for further use.
In this flow all the tutorials describe the authorization code as useless to the hacker, why is that? Can't a hacker use Postman or some other client and access your (public) API directly, make it go through step 3 and thus retrieve the tokens just the same?
What am I missing here?
The code is used exactly once. In many scenarios that an attacker might get access to the code, it's already been exchanged for an access token and therefore useless.
The authorization_code is a one-time token.
Authorization Code aka auth code is used publicly so that the client can establish a secure back channel between him and the authorization server so that he can exchange it with the access token without the use of a browser.
The auth code is public and can be intercepted via a proxy since it appears in the query of the redirect_uri and is used via the browser (which is considered insecure). The access token depends on the auth_code (public) and the client_secret (private) for the exchange. Without the client_secret an attacker can get the access token with brute-forcing this way through.
Summary: even if the attacker knows the authcode he can do anything without the client_secret given to the client at registration (or dynamically) and assumed to be secured.

Can we use same OAuth bearer token from different machine for API call

Suppose i am calling webapi from my machine in angular and get token from server, can i call api from other machine using same token will server be able to authenticate it.
Bearer token allows any party in possession of the token to use it. Using a bearer token does not require the bearer to prove the possession of token. However API implementation may add another layer checking, like one time use only, or bind token to first calling client.

OAuth2 authorization code PKCE without client_secret (wso2 5.3.0 IAM)

I'm currently trying to implement the OAuth 2.0 authorization code grant on a public client/native client (Android App).
Since it is impossible to store the client_secret on the device, I wanted to use this grant type with rfc7636 / Proof Key for Code Exchange by OAuth Public Clients (PKCE).
I'm using wso2 5.3.0 IAM in the backend.
The Authorization step works perfectly fine, but I'm not able to get the Access Token without a client_secret: invalid_request, Missing parameters: client_secret
Did I misunderstand the authorization code grant with PKCE wrong or did I miss some configuration in the IAM?
In comparison: It is possible with auth0.
Best Regards,
Robert
Even if you use the authorization code flow, client_secret is required at the token endpoint if the client type of your application is confidential. "4.1.3. Access Token Request" in RFC 6749 says as follows:
If the client type is confidential or the client was issued client credentials (or assigned other authentication requirements), the client MUST authenticate with the authorization server as described in Section 3.2.1.
So, change the client type of your application to public. I don't know WSO2, but I guess that it provides settings menu to switch the client type like below.
(screenshot of Authlete's web console)
The definitions of confidential clients and public clients are described in "2.1. Client Types" in RFC 6749.
Yes, the client_secret is mandatory in WSO2 IS implementation due to the Apache OLTU library that has been used internally to implement the OAuth2 feature.
Currently there is no way to register an application as a public client as explained.
However that doesn't mean there are necessarily any security pitfalls. Basically what the recommendation says is, not to embed the client_secret in a mobile app, because it makes it vulnerable. It doesn't provide any additional security for protected backend resources, because the client request is anyway not authenticated using client_secret. If you just treat the "Base64(client_id:client_secret)" as one single string it doesn't make any difference in the protocol or security of the protocol.
So when using WSO2 IS with mobile applications, following recommendations need to be followed.
Use authorization code grant type, which requires the client_secret.
Use PKCE (after WSO2 IS 5.2.0)
If you have other type of clients or channels for the same applications, e.g. like web, then register them as a separate service provider in IS and generate a separate pair of client_id, client_secret for them.
Disable "client_credentials" grant type for the particular OAuth2 mobile client you register in WSO2 IS, so that those apps can't get an access token without user authentication.
Going one step further, if you need to have unique client credentials for each instance of the mobile applications then use OAuth2 Dynamic Client Registration (DCR) to generate client credentials on the fly.
By following above 5 recommendations, it gives you the same level of security as recommended in the specification.
For Authorization grant flow you can send the request with empty client_secret. Try putting empty string like this client_secret='' and it should work as expected. You cannot request TOKEN_URI without client_secret parameter.
PKCE is used to protect theft of authorization code, Authorization code is valid for 10 minutes, when auth code is redeemed for access_token we also send code_verifier to make sure the auth code is not stoled by someone. code_verifier and code_challenge are generated together and code_challenge is used while requesting for auth code & code_verifier is used while requesting for access_token

Usage of response_type="code token" in OAuth 2?

The OpenID Connect Spec OAuth 2.0 Multiple Response Type Encoding Practices states that multiple response_type can be combined, e.g. response_type="code token". Now I'm wondering what it's good for to request an authorization code and the token. Isn't the auth code superfluous if you have the token already?
OAuth 2.0 is a protocol framework on top of which other protocols can be built and OpenID Connect is an example of such a protocol.
Especially for OpenID Connect it makes sense to use combined response types because there are 2 tokens in play: the access_token and the id_token. Using "response_type" the client can request how each of the tokens should be delivered.
In the example that that you give, the access_token will be delivered through the front channel as part of the authentication response but the id_token will be delivered when exchanging the "code" for an id_token at the token endpoint in a backchannel call.
A reason for doing this may be that the id_token, which is a signed JWT, does not have to be verified locally when obtained from a proper TLS protected token endpoint, so the client code can be simple. The access_token is opaque to the client anyhow and does not benefit from that.
I've never seen this used in practice. Yes, having the token already kind of diminishes the value of using the code flow.

What are Bearer Tokens and token_type in OAuth 2?

I'm trying to implement the Resource Owner & Password Credentials flow from the OAuth 2 spec. I'm having trouble understanding the token_type value that gets sent back with a valid response. In the spec all the examples show "token_type":"example" but says it should be
token_type
REQUIRED. The type of the token issued as described in
Section 7.1. Value is case insensitive.
Can someone please explain this to me?
token_type is a parameter in Access Token generate call to Authorization server, which essentially represents how an access_token will be generated and presented for resource access calls.
You provide token_type in the access token generation call to an authorization server.
If you choose Bearer (default on most implementation), an access_token is generated and sent back to you. Bearer can be simply understood as "give access to the bearer of this token." One valid token and no question asked. On the other hand, if you choose Mac and sign_type (default hmac-sha-1 on most implementation), the access token is generated and kept as secret in Key Manager as an attribute, and an encrypted secret is sent back as access_token.
Yes, you can use your own implementation of token_type, but that might not make much sense as developers will need to follow your process rather than standard implementations of OAuth.
Anyone can define "token_type" as an OAuth 2.0 extension, but currently "bearer" token type is the most common one.
https://www.rfc-editor.org/rfc/rfc6750
Basically that's what Facebook is using. Their implementation is a bit behind from the latest spec though.
If you want to be more secure than Facebook (or as secure as OAuth 1.0 which has "signature"), you can use "mac" token type.
However, it will be hard way since the mac spec is still changing rapidly.
https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-http-mac-05
From RFC 6750, Section 1.2:
Bearer Token
A security token with the property that any party in possession of the token (a "bearer") can use the token in any way that any other party in possession of it can. Using a bearer token does not require a bearer to prove possession of cryptographic key material (proof-of-possession).
The Bearer Token or Refresh token is created for you by the Authentication server. When a user authenticates your application (client) the authentication server then goes and generates for your a Bearer Token (refresh token) which you can then use to get an access token.
The Bearer Token is normally some kind of cryptic value created by the authentication server, it isn't random it is created based upon the user giving you access and the client your application getting access.
See also: Mozilla MDN Header Information.

Resources