Possible to use PKCE without client_secret? - authlib

I'm trying to use PKCE with the authorization code flow. It seems like the auth code flow requires you to use HTTP Basic auth to send along client_id and client_secret (so you must store client_secret client-side somewhere). Is this true, or is it possible to use the auth_code/PKCE flow without having store client_secret in the code? On this page from Okta, it says
Important: Unlike the regular Authorization Code Flow, this call does not require the Authorization header with the client ID and secret. This is why this version of the Authorization Code flow is appropriate for native apps.
So that makes it seem like it's possible to not need the client_secret in the auth_code flow.
However from my testing, it seems like the create_token_response method requires the client_secret to be sent along, otherwise it raises an Invalid Client error. I don't understand the need of that client secret as the client holds a code verifier.

I have implemented it on AWS Cognito, I imagine it should also work on Okta.
Maybe you haven't configured the client correctly. In Cognito I had to create a client without a client secret, so if you made one with a secret, maybe that's why it's breaking. Or just sent the wrong clientId.

Related

Github OAuth2 does not support Client Authentication?

Well, in OAuth2 specification is foreseen cases where you are authenticating in an application that runs fully on the client side (browsers, mobiles, etc.) and so they are incapable of protecting their code/data.
In the memo regarding Security Considerations they say you should not store credentials in our code (for obvious reasons, I think):
https://www.rfc-editor.org/rfc/rfc6819#section-5.3.1
Also, in the memo about native clients, they highly recommend that an authorization server do not require an application secret:
https://www.rfc-editor.org/rfc/rfc8252#section-8.5
So, it should be possible to obtain an access token without using the client secret using a "client" grant type, like this:
https://www.oauth.com/oauth2-servers/mobile-and-native-apps/authorization/
Anyway, in the Github documentation, it's stated that the client_secret is mandatory to retrieve the access token:
https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps/#2-users-are-redirected-back-to-your-site-by-github
By the official specification, you should be able to achieve this, but I couldn't find a way to achieve that using the Github OAuth, and here is my question:
Is there a way to use Github OAuth getting an access token without using the client_secret?
So, is there a way to use Github OAuth, get an access token without using the client_secret?
Not that I can see, when considering the authorization grant step
The application exchanges that code for the access token.
When the application makes the request for the access token, that request is authenticated with the client secret, which reduces the risk of an attacker intercepting the authorization code and using it themselves.
That means, if an application needs to automate that step on behalf of client, it needs to fetch that secret from a third-party referential, like a vault.
See for instance puppetlabs/vault-plugin-secrets-oauthapp, which is a plugin providing a secure wrapper around OAuth 2 authorization code grant flows, allowing a Vault client to request authorization on behalf of a user and perform actions using a negotiated OAuth 2 access token.
(here, Valut is hashicorp/vault)

Can the access token returned to an AngularJS app be used by an attacker?

We are looking into integrating keycloak to protect a front end AngularJS application which is served by a nodeJS application and also makes API requests to this server.
Having watched some tutorials, we see we need to use the javascript adapter for the AngularJS app to handle the user auth flow, and then protect our nodeJS application using the bearer only strategy, ensuring angularJS outgoing requests to our Node application contains an Auth header with the bearer token value present.
I have a question\concern about the way in which the token is being served back to the client as I can see it gets saved into a cookie which I assume is what the javascript adapter reads from in order for us to be able to write the Auth header into subsequent requests from the angular app.
My question is can this token value be easily read from the browser cookie and used maliciously by an attacker trying to make api requests?
Am I right in thinking it would be highly unlikely since the attacker would need to know the secret which is stored on the nodeJS side?
You don't need to know the client secret to use access token. That secret is used only to issue access token. If someone has your unexpired access token, then that someone will be able to use your identity until token expires. But you can minimise the possibility of the stolen access token by using https, httponly cookies. Also, you can use a short token lifetime (for example 5 minute). But then you will need to implement refresh tokens; otherwise, the user will need to re-login whenever access token expires.
I think the proper implementation is not trivial. I recommend using of some reverse auth-proxy, which will handle authorization and authentification in front of your app. Tip: https://github.com/gambol99/keycloak-proxy

Uber API credentials disclosure

I'd like to make an AngularJS app (no server side code at all) that uses Uber API history and requests-details endpoints.
As far as I understood the docs I'll need to use OAuth2 first and to get the access token the client_secret is required.
As it is a client-side application, client_secret can be seen by any user (easily or not).
I'm trying to understand the impact of exposing the client_secret but I cannot find anything bad about it from the docs.
There doesn't seem to be any client_secret endpoint that does anything harmful without the bearer token.
The client secret is the shared secret between the oauth server and the client application. Anyone who possesses the client secret for an application can represent as that application. So if it's leaked, a malicious application can:
Request permissions from users under the guise of your application
Request scopes that your application had been whitelisted for (e.g. the "request" scope)
Request an access token for your application using the client credentials grant flow (https://www.rfc-editor.org/rfc/rfc6749#section-1.3.4)
Perform other malicious activities as your application

Tracking consumers for RESTful API (no auth)

Folks,
What is a simplest way to track consumer applications accessing RESTful API services inside department.
We do not restrict access - no authentication/authorization - open for invocation, trusted environment.
No tools like OAuth AuthZ servers or API management yet... but might be heading there at some point.
For now we thought to request consumers just to include some custom HTTP Header like X-Client-Id and log it on the server side for stats etc..
But knowing that in the future we might want to switch to more standard ways of doing things ... what would be best alternative to have to change less code in the future ?
Have the "clientId" in the Authorization: OAuth token (like access token)
Have JWT token in the Authorization header (looks too much - signing,base 64 etc for simple client id tracking ...)
Any ideas would be appreciated
We recently implemented this for one of our REST platforms and we used a combination of BOTH the points you mentioned, meaning Authorization header & JWT token. Although, JWT is ONLY for authentication and GETTING an access_token (oauth token) which is later used with calling actual resource apis. I will discuss how we handled this situation and you can decide on how you want to implement it.
1) Authentication
Client sends a JWT to your authentication service (/api/oauth2/auth). (If you want more reading on JWT, you can read here and here of how JWT is implemented by google and how you can use spring-security-jwt libary to handle all the signing and encrypting/decrypting). You get the "clientId" out of JWT after decrypting and verifying the signature and after server does all the authentication, you respond back with a 'refresh_token' and an 'access_token'. Server will save the access_token as well and map it to the clientId so that when client makes requests using access_token, you can know which client is making the request. The access_token expires in some time (ideally in an hour) and when it expires, the client uses the 'refresh_token' to get a new access token by posting refresh_token to some refresh token url (/api/oauth2/auth/token)
2) Authorization
Client takes the 'access_token' and uses the access token to make all the subsequent requests on all other apis (/api/*). Ideally, the access_token is sent as a part of the "Authorization" header. Server uses request filters (if you are using JAX-RS, you can use something like ContainerFilterRequest to add filters to specific url patterns and intercept them) to filter EACH request and parse out the Authorization header value. You will get the access_token from the header and from the access_token you can get the clientId that you mapped in step 1). You can do other authorization logic in the security filter and if everything goes through, you can use this information to LOG that clientId and the request that the client made.
This way you can kill 2 birds with one stone : Implement a security layer & log the information about customers (what calls they are making, how many time etc. etc.). In case you don't want to implement security filter just yet (as you mentioned it might be in the future), for now, the clients can just pass on the "clientId" (base64encoded or not, upto you) as a part of "Authorization" header. If all the calls are from a "trusted" network, it should be ok, although not as secure. This way, when you ACTUALLY implement a JWT and Oauth based security layer, all you have to do is change your ContainerFilterRequest logic to parse out access_token instead of client id (as mentioned in step # 2).
I hope this helps ! For more information on security filters you can have a look at this answer: Basic Authentication of a resource in Dropwizard. It says dropwizard, but it mostly talks about JAX-RS.
To implement full AuthN/AuthZ layer for consumer tracking would be an overkill for now.
We thought to use either to Authorzation header to pass custom client_id token:
Authorization: Custom <Client_Id>
or to use some limited version of JWT (no signatures as there no intent to validate them)
as access token
Authorization: JWT <JWT>
Where JWT could be:
{"alg":"none","typ":"JWT"}
{
"iss":"Client_ID",
"aud": REST Service URI,
"iat":1328550785
}
I do not see description of access_token format in the specification https://datatracker.ietf.org/doc/html/rfc6749#section-1.4
Are there any contraints to use JWT as access token?

Basic Authentication with a Guid token for REST api instead of username/password

Overview
I am developing a mobile application using PhoneGap with REST API for the backend. The REST API won't be utilised by third-party developers, but will be application-specific, so there is no need for oAuth to be implemented. Hence, I am planning to use Basic Authentication where in the User enters their Username/password to access the API resources. All API communication will be on SSL.
Basic Authentication with Token
Instead of letting the application store the username/password and send it with every request to the API, I would rather authenticate username/password on the first login request and send a GUID token back. The client stores this GUID token and sends the token back to the API with each request through the Authorization header, like this:
Authorization: Basic e1d9753f-a508-46cc-a428-1787595d63e4
On the server side, the username/GUID combination will be stored on the server with a expiration date along with device settings. This will allow to keep track of the number of devices a user has logged in from as well as expire the session once the Guid has reached expiration.
Does this approach sound reasonable and secure?
There is no need for you to create custom headers or authentication schemes at all.
The Bearer authentication scheme is designed exactly for your use case:
Authorization: Bearer e1d9753f-a508-46cc-a428-1787595d63e4
Basic authentication must be as follows:
Authorization: Basic base64EncodedUsernameAndPassword
where base64EncodedUsernameAndPassword is equal to the output of:
base_64_encode(username + ':' + raw_password)
Do not use Basic if the trailing text value is not the above exact algorithm.
If you just want to put whatever value you want after the scheme name, use the Bearer scheme - that is what it was invented for.
Warning
While you can use a simple GUID/UUID as your token, this isn't really a secure token. Consider using a JWT instead. JWTs can be digitally signed and assigned a TTL so that only the server setting it can a) create it and validate its authenticity and b) ensure it is not used longer than is allowed. While this may be true of your data stored based on the GUID, the JWT approach does not require server state - so it scales far better - and accomplishes the same thing.
The general "Authentication with Token" approach is very good but you shouldn't try to make Basic Authentication work in different way than it is supposed to (after all it is a defined standard). You should rather use your own header for authentication purposes. You can find a very good description of such scenario here:
Making your ASP.NET Web API’s secure