Comments (19)
Sorry I didn't mean to imply that PKCE flow was a alternative to using refresh tokens. I was suggesting that Bungie look into adding a PKCE enabled OAuth flow so we can avoid embedding the Client Secret in our native apps (aka SPA).
I haven't yet come across any OAuth flows that use such an aggressive refresh token rotation strategy as listed in that documentation. Thanks for that info.
from api.
from api.
Turns out there is a spec for dynamic registration: RFC7591.
Something else that seemed interesting was the Assertion Framework (An abstract framework for OAuth client credentials/grants)
Two examples would be:
And again concerning the question about native app there is this spec draft that mentions in section 8.4:
Native apps, except when using a mechanism like Dynamic Client
Registration [RFC7591] to provision per-instance secrets, are
classified as public clients. . .
from api.
Jose, you are interpreting the documentation correctly. OAuth requires that authentication providers distinguish between public and confidential clients and configuration time. However, Bungie.net has no mechanism to determine that the client really is confidential at run time.
from api.
It's too bad that there isn't some refresh token setup for public clients because it drives folks who should be using a public client type to configure a confidential client type and putting their credentials at risk.
from api.
from api.
What actions will be taken if a mobile application registers as confidential and transmits their client_secret through the user's device? To force a user to open a new browser tab every 60 minutes is a bit strange.
from api.
So, yeah, any native application could be subject to decompiling, or some inspection of app resources, so it's assumed that anything included in the application binary could be extracted. For public clients, that would be your API Key.
On the other hand, the OAuth spec believes that native apps can provide adequate security for tokens.
...dynamically issued credentials such as access tokens or refresh tokens can receive an acceptable level of protection. At a minimum, these credentials are protected from hostile servers with which the application may interact. On some platforms, these credentials might be protected from other applications residing on the same device.
Of course, anything that goes over the wire could be intercepted using a proxy. The same is true for the official Destiny app, which seems to use a cookie based authentication mechanism.
From a user experience perspective, forcing a user to sign in every hour is awful. iOS or Android users might sign in twice, but by the third time you pop a web browser they'll give you a one star review and uninstall your app. It would be difficult to develop anything useful with such a restriction in place.
Could you consider providing refresh tokens to public clients?
from api.
from api.
@floatingatoll Their iOS application still uses a web-view, as @jose-ibanez pointed out.
from api.
Good conversation, thank you all for the input! When we get time, I'll loop back around and investigate further, and discuss options and opinions mentioned here with the rest of the team. We're pressed for time at the moment, but I just want to make sure you guys know that we're not dropping the issue and will loop back.
from api.
Agreed. Any observations from the industry in general. How do other apps/oauth servers deal with this problem?
from api.
Those are just profiles to help base a decision on what OAuth flows to use I think. They define a confidential client as one that can maintain a secret regardless of how it is implemented. So if you're able accomplish that then you should safely be able to run as a confidential client. If you cannot accomplish that then you should not be issued a refresh token. As mentioned refresh tokens are equivalent to credentials.
The supplemental info on the security considerations of the OAuth spec mention in section 4.1.1 different threat models - including accessing secrets.
Attack: Obtain Secret From Source Code or Binary:
This applies for all client types. For open source projects, secrets
can be extracted directly from source code in their public
repositories. Secrets can be extracted from application binaries
just as easily when the published source is not available to the
attacker. Even if an application takes significant measures to
obfuscate secrets in their application distribution, one should
consider that the secret can still be reverse-engineered by anyone
with access to a complete functioning application bundle or binary.
Countermeasures:
o Don't issue secrets to public clients or clients with
inappropriate security policy (Section 5.2.3.1).
o Require user consent for public clients (Section 5.2.3.2).
o Use deployment-specific client secrets (Section 5.2.3.4).
o Revoke client secrets (Section 5.2.3.6).
Attack: Obtain a Deployment-Specific Secret:
An attacker may try to obtain the secret from a client installation,
either from a web site (web server) or a particular device (native
application).
Countermeasures:
o Web server: Apply standard web server protection measures (for
config files and databases) (see Section 5.3.2).
o Native applications: Store secrets in secure local storage
(Section 5.3.3).
o Revoke client secrets (Section 5.2.3.6).
In section 3.7 it mentions:
Deployment-independent "client_id" with pre-registered "redirect_uri"
and with "client_secret" This is an option for native
applications only, since web applications would require different
redirect URIs. This category is not advisable because the client
secret cannot be protected appropriately (see Section 4.1.1). Due
to its security weaknesses, such client identities have the same
trust level as deployment-independent clients
Now for section 5.2.3.4:
An authorization server may issue separate client identifiers and
corresponding secrets to the different installations of a particular
client (i.e., software package). The effect of such an approach
would be to turn otherwise "public" clients back into "confidential"
clients.
For web applications, this could mean creating one "client_id" and
"client_secret" for each web site on which a software package is
installed. So, the provider of that particular site could request a
client id and secret from the authorization server during the setup
of the web site. This would also allow the validation of some of the
properties of that web site, such as redirect URI, web site URL, and
whatever else proves useful. The web site provider has to ensure the
security of the client secret on the site.
For native applications, things are more complicated because every
copy of a particular application on any device is a different
installation. Installation-specific secrets in this scenario will
require obtaining a "client_id" and "client_secret" either
1. during the download process from the application market, or
2. during installation on the device.
Either approach will require an automated mechanism for issuing
client ids and secrets, which is currently not defined by OAuth.
The first approach would allow the achievement of a certain level of
trust in the authenticity of the application, whereas the second
option only allows the authentication of the installation but not the
validation of properties of the client. But this would at least help
to prevent several replay attacks. Moreover, installation-specific
"client_ids" and secrets allow the selective revocation of all
refresh tokens of a specific installation at once.
Basically if Bungie came up with a way to automate issuing of client ids and secrets we could "turn otherwise 'public' clients back into 'confidential' clients." ~~~Unfortunately such a thing isn't defined in the spec. I have no idea how feasible it would be for them to implement if it's even a good idea to do so.~~~
I haven't read all of this damned thing so there are probably other solutions for what we have currently. In my case I'm trying to build a web app so the web crypto api seemed like something that could help. Possibly the user-agent would retrieving the id and secret from a server at runtime and store them encrypting/decrypting on use. You would of course have to ensure only the proper clients can get the id and secret.
If secure storage is possible then it seems the only problem is handling the id and secret. As mentioned you can't hardcode them as they would basically be public. Some sort of secure delivery mechanism would need to be put in place. ~~~But I'm still not sure how necessary it is to protect those two elements... It could be possible that exposing them would not be a big problem. In which case running as confidential would only require having some place to secure the tokens.~~~
from api.
Wanted to implement a litte app and i can't realy decide which client model i should use.
Public or Confidential.
Public seems like the right aproach because. i'm building a webapp/spa where i don't want to include any secret api keys.
I still can't quite understand the difference between public and confidential Clients. (is it only the 3600s lifetime of the access token vs the 90days refresh token?)
To my understanding there is not such a think like a confidential client (every client could expose there secrect keys though debbuging), like DIM exposes there client_id and client_secret upon every token refresh in there http request. Likewise Braytech for example exposes it via the Authorization header as there client_sec and client_id in a base64 encoded string.
Why?
Should'nt they use some kind of proxy, where the proxy only knows the secrets api keys and only pass the access or refresh token back to the client?
What should i choose? The burden of relogging every hour in my app is kind of cumbersome and proxying could drastically increase traffic on my side? (If and only when the app find its users...)
from api.
It's an age old question.
The confidential client gets a refresh token which means the user won't need to sign in again for a year as long as they use your app every 90 days.
The public client requires the user sign in once an hour. It is the most secure option for your scenario and really the only option if you are following the rules carefully (not everyone does). The user experience may not be as bad as you are imagining. Most of the time, the re-signin will happen without the user having to enter a user ID or password.
I advise against creating a proxy; it becomes a point on the open internet someone can attack and leverage to attack Bungie.net. You would also need to have it authenticate each of your users which is a complex task and hard to get right. You may be tempted to have a secret your proxy can verify that only your app knows, but that is the same as keeping the client secret in your app. You may as well just put the client secret in that app and not have the headache of a proxy.
My advice, try it as a public client first. It is easy to upgrade to a confidential client later if you must. You may find your scenario works well as a public client.
from api.
thank you for quick answer.
I will try as you say and go with the public client settings. Will see what the login, (which is maybe somehow cookied by the browser?) looks like.
from api.
The access token, which you need to add to each request header per the OAuth spec, will not be cookied by the browser. Depending on your platform, you can probably find a pre-rolled OAuth client. For example, I think npm has a few to choose from.
from api.
A potential solution to this would be to implement PKCE on the server side. This adds a significant layer of security for the code exchange process and is already baked into some OAuth client libraries.
I was just running into the missing refresh_token
issue with a test app using a public client type. The every one hour re-authentication flow is a deal breaker for an app with what's really only read-only privileges. Adding PKCE support should allow clients to safely obtain refresh tokens without exposing client secrets and be done with this issue for good.
from api.
PKCE is not a replacement for refresh tokens. The OAuth.net featured post for implementing PKCE indicates that PKCE is a safer way to retrieve an access token — but also shows that it's still retrieving a one-hour access token:
{
"token_type": "Bearer",
"expires_in": 3600,
"access_token": "eyJraWQiOiI3bFV0aGJyR2hWVmx...",
Auth0 also reversed their prior recommendation of PKCE alone and now indicates refresh token rotation alongside PKCE as their current guidance:
Auth0’s former guidance was to use the Authorization Code Flow with Proof Key for Code Exchange (PKCE) in conjuntion with Silent Authentication in SPAs. This is more secure solution than the Implicit Flow but not as secure as the Authorization Code Flow with Proof Key for Code Exchange (PKCE) with Refresh Token Rotation.
... long-lived Refresh Tokens are not suitable for SPAs because there is no persistent storage mechanism in a browser that can assure access by the intended application only. As there are vulnerabilities that can be exploited to obtain these high-value artifacts and grant malicious actors access to protected resources ...
If you expect users of your app to use your app for longer than 1 hour, or more than 1 time per 7 days, then the 'public' scope is inappropriate for your app; you'll need 'confidential' scope, and you'll need to handle refresh tokens.
from api.
Related Issues (20)
- Contest Instances Missing HOT 3
- Prismatic subclasses `screenshot` fields missing HOT 2
- Text conversation is not active
- Text conversation does not change from disabled to enabled HOT 1
- Weapon property is wrong? HOT 1
- A means of seeing the total number of kills of each weapon used for a given character. HOT 1
- Question: Pathfinder quests via API HOT 2
- Missing Item after Transfer HOT 7
- typos in DestinyActivityDefinition manifest
- Inconsistent Paging Parameters HOT 2
- Adjust Hawthorne's reputation name - currently set to "Reputation Max Rank" 🙈
- Add engram balances for Hawthorne, Xur (Tower) and Rahool to CurrencyLookups [component 600]
- Competitive matches are mistagged.
- Iron Banner Milestone is missing HOT 1
- nothing manacles and ursa furiosa plugsets differ between implementation and manifest
- DestinyActivityInteractableDefinition is missing from sqlite definitions HOT 1
- Add all resettable-reputation vendors to currentRankProgressionHashes
- API does not report red border weapons in the season pass reward track
- Test interface status 302
- itemTypeDisplayName for Salvation's Edge raid mods is drastically different from every other mod
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from api.