Open Falci opened 3 years ago
This has been inspired by these security considerations: https://tools.ietf.org/id/draft-ietf-oauth-browser-based-apps-02.html#cors
Additionally the routing via URL fragments is handled with this custom components: https://github.com/namebasehq/handshake-id-manager/tree/master/src/packages/Hashbrown This has been implemented so the id manager as a static website can be hosted on servers with limited routing options. The current id.manager.io is hosted directly from github: https://github.com/namebasehq/handshake-id-manager/tree/master/docs
There's nothing preventing a SPA hosted on GitHub to access the search part of the URL (aka query string)
I am not sure to fully understand the limitation you are referring to. I can't think of any use cases where this would block its implementation.
Please correct me if I am mistaking but it seems that sensitive information should not be carried over GET: https://cwe.mitre.org/data/definitions/598.html https://owasp.org/www-community/vulnerabilities/Information_exposure_through_query_strings_in_url
For more info: https://stackoverflow.com/a/14718532/1724828
OAuth 2.0 supports both, depending on the use case: Implicit Grant (fragment) for when only the client should have access to the response and Authorization Code Grant (query param) for when it should be passed to the server for more verification.
Verifying if someone is legitimate (analogous to checking username and password) and using an access_token with another authorization server (sending the user/pass to get some sensitive data) are completely different. One SHOULD be validated server-side, the other MAY be done server-side.
https://developer.okta.com/blog/2018/05/24/what-is-the-oauth2-implicit-grant-type
Implicit Grants are used when the browser requires the access_token
to make additional queries. Passing as a fragment ensures that it isn't sent to any server (static file storage, etc.) as it is not needed (think JAMStack apps). This option was specifically made with server-less JavaScript web-apps in mind.
https://developer.okta.com/blog/2018/04/10/oauth-authorization-code-grant-type Authorization Code Grants are used when a code needs to be sent to the client's (oauth term, not browser) server which will then use the code for whatever purpose. There is no additional benefit security-wise by not providing this option.
Please correct me if I am mistaking but it seems that sensitive information should not be carried over GET: https://cwe.mitre.org/data/definitions/598.html https://owasp.org/www-community/vulnerabilities/Information_exposure_through_query_strings_in_url
The handshake login flow (the id manager part) does not pass the same kind of "sensitive" data as OAuth's access_token
.
The access_token is reusable, and can be used to retrieve more information from the resource server whereas data in our case cannot.
The response data in our case is a one-time use signed message that only authenticates which the client's server must verify again. The access_token
on the other hand, attempts to fetch resources from the resource server and simply fails if it is incorrect.
I think this resolves the concern about the CWE?
I agree the domain and the public key are not as sensitive as the access_token but these fingerprints might also need to be kept private. Ideally the communication between these components could be configured like the oauth response mode: https://openid.net/specs/oauth-v2-multiple-response-types-1_0.html#ResponseModes
What do you think should be the ideal mechanic? Would you be willing to submit a PR to implement these changes?
That's perfect, to add a new query param to the request to id-manager. Then it's up to the clients (apps) to choose what's best for their apps.
We can default to fragment since that's what the oidc server uses and that won't need any changes.
I can do the PR next week, doesn't seem like a lot of work. Unless @Falci finds time to do it first.
TL;DR: why not querystring instead of hash for params from the OIDC?
When the OIDC sends the request to
_idmanager
the params are in the format of URL fragment (aka hash).That seems a misuse of URL fragments. I understand this is a common practice among some popular javascript frameworks, but since the browser won't send the fragment to the server, it forces the flow to have a client javascript that will read, parse and process it. Even if we want to process the login request on the backend, we are forced to have a js client.