Github OAuth2 does not support Client Authentication? - github

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)

Related

Protocol for password-less authentication in clis

I have a cli (which use a rest api) which needs authentication for use.
As of right now, it supports a token auth. This token is generated at the server on a request with username and password and given as the response.This is not ideal (due to man in the middle attacks) and I am looking for a better protocol to use to generate the tokens.
Users will use such a protocol from a cli, and may or may not have access to a browser on the same device (Though a protocol that requires opening a website is not a problem)
The OAuth device flow seems to be a very simple to use flow, but it is meant
for authorization and not authentication. I also do want to support OAuth as that will require a lot of work, and frankly not what I need.
What is the standard or recommended protocol to use in such a situation?
MITM should not be an issue if your server and app are properly securing the connection. There is nothing really wrong in using a username+password to connect to your backend services. After all, when you're logging into the site you're sending an HTTP request with your username and password to a backend the same way your cli app would do it.
But OAuth indeed can a better fit for cli app:
it's easier to revoke the stolen OAuth token than to force user to change a password,
an app doesn't have to deal with user credentials (although OAuth credentials flow is also exists),
it gives you flexibility when creating new tokens. For example, you may want to issue short lived tokens only to force the user to re-login each time the app is used or you may want to use long-lived refresh tokens.
As you already mentioned, OAuth doesn't handle authentication but you can use your current login flow to verify user credentials and issue an OAuth token (how exactly do that is a separate topic).
I don't think there is a special protocol targeting authentication in cli apps. In any case the app would need to send some secret to a backend. One of the possible solutions is to use OTP (e.g. SMS or email code). In this case you send the code the same way as you would send a password but it is better protected against MITM attacks because a code cannot be used more than once.

REST API for internal consumption and authentication

When I use public APIs from web applications, I am provided with an API key that I use inside my client, as a string.
Now suppose I design a REST API for internal consumption. Let's say for a mobile app eshop. The user of the eshop logs in with a username and a password.
Does that mean that my client won't use API key authentication but username and password? I also see OAuth2 a lot in REST APIs, which also seems like a key-oriented authentication. Are they just different types, all valid ones? The API keys are usually issued for developers though, could that work with customers?
It could work and it's also what you will be seeing in many cases. You login with username and password (POST request) and the server returns you an authentication token which you store in a Cookie through response headers. When user specific information is being required you would be using that token to authenticate, similar to how OAuth2 and dev keys work.
Based on my understanding on your question -
There are methods or way on how you can authenticate your api. Some of the common ones are through Oauth, Token authentication and Basic auth (username and password).
You can read some of the concepts here - http://www.django-rest-framework.org/api-guide/authentication/
Hope this helps

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

Accessing REST APIs secured using OAUTH

I have a set of REST APIs that are secured by oauth 2. I need to access them from an Android app and a webapp.
Accessing the APIs from android app seems pretty straight forward for me to implement. What I am unable to understand here is - what is the correct and secure way to access the same APIs from a webapp?
I am thinking, I shouldn't be making any direct calls to the APIs from the browser, using some JS library, for it seems to me that it would be pretty insecure. Instead, I should keep it all traditional, by submitting requests to the web server and then letting it make the REST API call. This would be similar to the method of making REST calls from Android.
Am I correct in my thinking/approach?
Accessing your API should be the same no matter where the request is coming from. You just use an Authorization header with bearer scheme and stick the JWT token in there.
The way you get the JWT token is different though, as I explain in this answer. It all depends on how much you trust the client application.
If your client is a web application that queries your API from the server side, you can use the code authorization grant and get an access and refresh token for your API.
If you want to access your API from a JavaScript application, you have no way to hide app-keys or refresh tokens, so you should use the implicit grant.
If you know how to store secrets securely on your Android client, you could use the resource owner password grant.
The code authorization grant is definitively the most secure as it's much harder to compromise a server application than an application that runs on your machine.

Rest application and authorization

I would like to build my own REST app.
I'm planning to use oAuth as a main auth approach.
The question is: Can I use login and password as client_id and client_secret (in terms oAuth spec) ?
I don't have any third side applications, companies, sites etc... which will authenteficate my users.
I have my own REST server and JS-application.
Whole site will be made in usual(RPC) approach, but some private part will be done as RESTfull service, with enough stand-alone JS application.
UPDATED: I'm not sure that I even need full oAuth support. It seems to me that I can ask login and password on https page and then generate some token. Later i could use it to check is this user authenticated already or not. But in this case this oAuth become almost the same what we have in web aplications. I do not need oAuth to athorize users ?
I'm not consider HTTP(s) authotization because i don't want to send evrytime user and password to server.
No.
One if the main reasons OAuth exists is to allow integrations without users compromising their usernames and passwords.
If you plan on using username and password, look into xAuth as an option if you still want to sign your requests. More info: https://dev.twitter.com/docs/oauth/xauth.
But you could likely just as well go for HTTP Basic Authentication. At least if you publish your API over SSL. More info: http://en.wikipedia.org/w/index.php?title=Basic_access_authentication
I think you might get a better answer on the security site. See, for example, this question.
In any case, you need to start with a detailed assessment of what attacks you are trying to prevent and what attacks are "acceptable.". For example, if you are using HTTPS then you can probably accept the remaining danger of a man-in-the-middle attack, because it would require forging an SSL certificate. It is harder to say in general if a replay attack is acceptable.
One reasonable solution would be to create a time-limited temporary token by having the user authenticate over HTTPS with the username and password, generating a secure token with an expiration date, and then sending that token and expiration date back to the client. For example, you can create a (reasonably) secure token by taking the SHA1 hash of a secret plus the user name plus the expiration timestamp. Then the client can include the token, the user name, and the authentication timestamp in future requests and you can validate it using your secret and your clock. These need not be sent as 3 parameters; they can be concatenated into one string user|timestamp|token.
Register your application with SLI. SLI grants a unique client ID and a client secret that enables your application to authenticate to the SLI API. You must also register the redirect URI of your application for use in authentication and authorization flows.
Enable your application with specific education organizations so that the application can be approved for use in those districts.
Configure and implement the appropriate OAuth 2.0 authentication and authorization flow in your application, which includes managing sessions and authorization timeouts.