OAuth device code grant – JWT

I am looking at implementing an API Gateway for a system using WS02 as the IdP. Users will be signing in using OAuth via federated SSO with social providers (initially Google). The users will also need to pass access to a device with limited input, so I was looking to implement the OAuth device_code grant (WS02 is the only open source IdP that supports this grant, as far as I can see, please correct me if you know I am wrong). This will pass a JWT to the device which it should be able to use to access the API Gateway.

  1. Is it acceptable for a JWT to be used by a device in this way? I have been reading that using ‘opaque tokens’ is preferable but I don’t know how these could be assigned to a device using open standards. What are the risks of this approach and how can they be mitigated?
  2. The JWT would pass from ‘client device’ -> ‘API Gateway’ -> ‘service’. Is this delegation accpetable – is the Gateway impersonating the client?
  3. There will also be some JavaScript (React) web apps to use in browser, could these use the JWT also? Again what are the risks and how could they be mitigated?

How to exclude rule 930120 for google oauth

I’ve this error:

ModSecurity: Warning. Matched "Operator `PmFromFile' with parameter `lfi-os-files.data' against variable `ARGS:scope' (Value: `email profile https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/useri (16 characters omitted)' ) [file "/usr/local/owasp-modsecurity-crs-3.0.2/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf"] [line "84"] [id "930120"] [rev "4"] [msg "OS File Access Attempt"] [data "Matched Data: .profile found within ARGS:scope: email profile https:/www.googleapis.com/auth/userinfo.profile https:/www.googleapis.com/auth/userinfo.email openid"] [severity "2"] [ver "OWASP_CRS/3.0.0"] [maturity "9"] [accuracy "9"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-lfi"] [tag "OWASP_CRS/WEB_ATTACK/FILE_INJECTION"] [tag "WASCTC/WASC-33"] [tag "OWASP_TOP_10/A4"] [tag "PCI/6.5.4"] [hostname "a.a.a.a"] [uri "/***/create_account_oauth.php"] [unique_id "159608684932.394214"] [ref "o53,8v144,116t:utf8toUnicode,t:urlDecodeUni,t:normalizePathWin,t:lowercase" 

and I’ve created this exclusion rule for that:

SecRule REQUEST_URI "@beginsWith /***/create_account_oauth.php" \         "phase:2,log,pass,id:19023,ctl:ruleRemoveById=930120" 

what I’d like to do is to refine the exclusion for googleapis only. I’m think chaining the rule with another one to match googleapis in the data field. Is that what you’d recommend? It seems difficult to find resource on chaining. Can someone please help? Thank you.

OAuth authorization code grant with exposed client secret

Let’s assume that a client has the client secret exposed somewhere. What are the risks that the client and its users are exposed to? Are those the same as having implemented the implicit flow from the begin with?

I would say that, the risk here is for an attacker stealing a code, and since the client secret is available, assuming no other form of client authentication is performed, then the attacker would be able to exchange the code to token. So it looks like it’s similar with the risks of implicit flow, but a bit more secure since by default the tokens are not exposed in the user-agent (implicit flow could use for example response_mode=form_post and avoid that scenario)

Exploitation of client_id in OAuth

We have a web app where its back end are composed of APIs. We use OAuth to authorize the webb app’s call to the APIs. We all know that in OAuth, there is always the Authorization endpoint used to get the Authorization code, which in turn is used to get the Authorization token. In the Authorization endpoint, part of its input parameters is the client_id. Its the identifier for the components that wants to access the resources (e.g. mobile app, web app).

Now, we have a web app where its back end are composed of APIs. We use OAuth to authorize the app’s call to the APIs. I

  1. In this case, is the client_id stored in the browser? How would we know where it is stored?

  2. What if a user of the web app was able to successfully authenticate then using OAuth, was given authorization to access the APIs via the web app, but after he uses his machine, the next user was able to get hold of the client_id in the browser. Would he/she be able to access the APIs?

I am asking both since we recently subjected our app to penetration testing and the testers had a lot of issues on the client_id. They said this can be guessed via enumeration and when guessed, can be used to access your resources. Also, if stored in the browser (if your app is a web app), and you’re using a public computer, other people can get this and use this to access and use the APIs that your web app uses (if they know what their urls are). I’m confused if this are really valid issues.

OAuth native app without localhost redirect

Section 4.1 of RFC 8252 describes the OAuth authorization flow for native apps using the browser (i.e., external user-agent). In this flow, the native app receives the authorization code in step 4 by setting the redirect URI to the loopback IP. This, of course, requires the native app to open a port on the loopback interface and subjects us to attacks where other apps could get the authorization code (unless we use something like PKCE).

Our system is a client-server model where the clients are various custom command line tools with no real user interface. In our deployments, we can’t always guarantee that we will be able to open a port on the loopback (and we’d like to avoid the added security concerns that PKCE addresses). We would like to tweak the flow for our use case but want to make sure we aren’t leaving the door open for security issues. Here is the flow we’d like to use:

  1. Command line tool initiates intent to perform OAuth flow to Application Server.
  2. Application Server generates a random in progress session token and a separate random OAuth flow state value
  3. Application Server stores both values in the database together
  4. Application Server returns both values to the Command line tool
  5. Command line tool launches the external user-agent (e.g., browser) and starts the authentication process against the Authorization Server using the OAuth state value provided by the Application Server
  6. User authenticates
  7. Authorization Server redirects to the Application Server along with the state value
  8. Application Server retrieves authorization code and stores it in the database along with the in progress session token and OAuth state value
  9. Command line tool submits the in progress session token to the application server
  10. Application server retrieves the authorization code from the database and treats it as if the command line tool provided it

Outside of the potential for DoS abuse on submitting lots of OAuth initiations and the potential for the command line tool to initiate step 9 before the application server has completed step 8, are there other security issues to be concerned with?

Can Chrome Extensions steal OAuth tokens from redirect-uri?

This is a duplicate of a stack overflow question, since it might apply more to security and authentication best practices.

I’m working on auth between a Chrome Extension, Google Cloud Platform, and trying to send the id_token JWT to an AWS server to retrieve user data (and/or establish a session?).

My question is this — how can I prevent chrome extensions with tabs permissions from reading the GET request or the redirected URI which has the fully-validated user JWT?

The JWT confirms that a user is who they are, but how do I know my Chrome Extension is the one making the request to my backend?

I have a few ideas:

  1. Maybe I can make a private window that only my extension can control

  2. Maybe I can somehow use the nonce or get the nonce from my server first

  3. Maybe my chrome extension has a private key or some way to verify itself with my backend, which has the public key

Any help would be appreciated, it’s difficult to research this specific scenario.

var url = 'https://accounts.google.com/o/oauth2/v2/auth' +           '?client_id=' + encodeURIComponent(chrome.runtime.getManifest().oauth2.client_id) +           '&response_type=id_token' +           '&redirect_uri=' + encodeURIComponent(chrome.identity.getRedirectURL()) +           '&scope=' + encodeURIComponent(chrome.runtime.getManifest().oauth2.scopes.join(' ')) +           '&nonce=' + Math.floor(Math.random() * 10000000);  chrome.windows.create({ url: 'about:blank' }, function ({ tabs }) {     chrome.tabs.onUpdated.addListener(         function googleAuthorizationHook(tabId, changeInfo, tab) {             if (tab.id === tabs[0].id) {                 if (tab.title !== 'about:blank') {                     console.log(url);                     if (tab.title.startsWith(chrome.identity.getRedirectURL())) {                         const id_token = tab.title.split('#')[1];                         console.log(id_token);                     } else {                         console.error(tab.title)                     }                      chrome.tabs.onUpdated.removeListener(googleAuthorizationHook);                     chrome.tabs.remove(tab.id);                 }             }         }     );      chrome.tabs.update(tabs[0].id, { 'url': url }); }); 

Securing API access. oAuth Client Credentials vs client ID and secret

I have a REST API that will be called by other external 3rd party servers over the internet and be used only for machine to machine communication. I am looking for mechanisms to secure this API such that only servers that I designate will be allowed to use this API. I do not control the servers and cannot guarantee the IP addresses that these servers use.

I thought of using the OAuth client credentials flow to secure the API by giving each external server a client id and a client secret. But that made me realize why use OAuth at all and not directly deal with client id and secret i.e. when the external servers call my API they will pass the client id and client secret and if a compromise happens I will revoke the client secret and the communication will no longer be allowed. For the communication to start again, I will issue them a new client ID and secret.

Is this approach correct? If not, what is the advantage of using the client credentials flow in OAuth if the external server has to store and pass the client id and secret to get a token anyway.

Apps removing their permissions in OAuth

We are designing a web application for a customer and the main use case is that users will be using the system for anywhere between a few days and a few months.

The customer would like to offer users to make use of existing identity service providers (Google, LinkedIn etc.), but wish, at the end of the process, to offer them the option to revoke the permission granted.

Is there a simple way to do that from the application’s side or will it have to be a reference to the vendor’s documentation with how to revoke the access?

OAuth access token/API key patterns for large web sites

First off, let me preface this post by saying I’m not a security expert.

I’m trying to build regular expresssions to find OAuth 2.0 access tokens and API Keys for common web sites such as Google, Twitter, Facebook, Slack etc. that may have been embedded in source code.

I couldn’t find the token formats of the large sites documented in one place anywhere so I carried out my own research:

OAuth 2.0

| Site      | Regex                                         | Reference                                                                     |  | --------- | --------------------------------------------- | ----------------------------------------------------------------------------- | | Slack     | xox.-[0-9]{11}-[0-9]{13}                      | https://api.slack.com/docs/oauth                                              | | Google    | random opaque string upto 256 bytes           | https://developers.google.com/identity/protocols/OAuth2                       | | Twilio    | JWT [1]                                       | https://www.twilio.com/docs/iam/access-tokens                                 | | Instagram | [0-9a-fA-F]{7}\.[0-9a-fA-F]{32}               | https://www.instagram.com/developer/authentication/                           | | Facebook  | [A-Za-z0-9]{125} (counting letters [2])       | https://developers.facebook.com/docs/facebook-login/access-tokens/            | | Linkedin  | undocumented/random opaque string             | https://developer.linkedin.com/docs/v2/oauth2-client-credentials-flow#        | | Heroku    | [0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12} | https://devcenter.heroku.com/articles/oauth                                   | | Github    | [0-9a-fA-F]{40}                               | https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps/ | 

API Keys

| Site   | Regex                                                                       | Reference                                                     |  | ------ | --------------------------------------------------------------------------- | ------------------------------------------------------------- | | GCP    | [A-Za-z0-9_]{21}--[A-Za-z0-9_]{8}                                           | undocumented (obtained by generating token)                   | | Heroku | [0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12} | https://devcenter.heroku.com/articles/platform-api-quickstart | | Slack  | xox.-[0-9]{12}-[0-9]{12}-[0-9]{12}-[a-z0-9]{32}                             | https://api.slack.com/custom-integrations/legacy-tokens       | 

Based on this research:

  • We can map credentials to web-sites with some level of accuracy based on position of hypens, periods, etc.
  • A more robust way to detect credentials might be to skip the regex altogether and use shannon entropy to find “unusually random” strings, as illustrated in this blog: http://blog.dkbza.org/2007/05/scanning-data-for-entropy-anomalies.html

I also stumbled on truffleHog which has its own completely different regexs which really confused me at first:

    ...     "Facebook Oauth": "[f|F][a|A][c|C][e|E][b|B][o|O][o|O][k|K].{0,30}['\"\s][0-9a-f]{32}['\"\s]",     "Twitter Oauth": "[t|T][w|W][i|I][t|T][t|T][e|E][r|R].{0,30}['\"\s][0-9a-zA-Z]{35,44}['\"\s]",     "GitHub": "[g|G][i|I][t|T][h|H][u|U][b|B].{0,30}['\"\s][0-9a-zA-Z]{35,40}['\"\s]",     "Google Oauth": "(\"client_secret\":\"[a-zA-Z0-9-_]{24}\")",     "Heroku API Key": "[h|H][e|E][r|R][o|O][k|K][u|U].{0,30}[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}",     ... 

Applying these rules to find a GitHub token, would not match the token in GitHub’s documentation: e72e16c7e42f292c6912e7710c838347ae178b4a but it would match assignment of this value to a suspiciously named variable, eg:

$  github_key = "e72e16c7e42f292c6912e7710c838347ae178b4a"   # ... but would _not_ match  $  key = "e72e16c7e42f292c6912e7710c838347ae178b4a"  

My question is:

  1. Does anyone have a more comprehensive list of credential formats
  2. Does anyone have additional/better detection patterns?

[1] I implemented JWT detection as its own rule which matches a 3 section block of text delimited by . with two sections starting { (base64 encoded):


[2] https://www.youtube.com/watch?v=_hF099c0A9M (skip to 1:35)