3 ms·
They are adding a second redirect on top and sticking it into the state parameter, presumably so they can redirect to anywhere. so the flow wanted was Go the
by scurvy_steve 3y ago
They are adding a second redirect on top and sticking it into the state parameter, presumably so they can redirect to anywhere.
so the flow wanted was
Go the some harvest authorize url,
That redirects to the Microsoft authorize url with redirect_uri=registered_uri and state=some_encoded_final_uri,
user enters credentials,
redirect to a registered uri
read state parameter and redirect to uri encoded in state.
This exploit still redirect to an authorized uri, but that endpoint then reads the the state parameter and happily forwards the response/token.
3 mistakes in this, abusing state, not encypting and validing state if you are going to abuse it. Enabling implicit grant(even if they needed it, should have made a second registration with limited uses).
- michaelt 3y agoIt's kinda normal that you'd want to let a user log in and return them to the page they were at. For example, if you're making a shopping website and a user asks to put something in their basket and you send them to log in, you'd want to return them to the item they were about to buy, not dump them back at the homepage. What's the proper way of doing this, without "abusing state" ?
- Operyl 3y agoStore the basket in a temporary cookie, not the oauth state parameter.
- lstamour 3y agoAlso only allow redirects to your domain or website, not literally anywhere on the internet. And the token should stay in your website’s cookies - it’s unclear why the second redirect would ever need to pass a token if it can read it from site cookies in the first place.
- johncolanduoni 3y agoDon't attach the sensitive URL parameters to the second redirect. The first redirect logs you in via cookie, and then if the second redirect is on the right origin it will have access to your cart.
- madeofpalk 3y agoAt the least you're supposed to validate the at the returning "state" parameter is the same value as what you sent (using cookies or local storage). Ideally you would 'consume' the token before redirecting, and not send it to the second redirecting url.
- pravus 3y agoThere's no reason to have a URL (or any data) encoded in the state parameter. The purpose of the parameter is to provide an opaque lookup key which you can utilize to provide correct, validated responses. This is usually done in some sort of database or Redis-like cache. My workflows have always used a random UUID for the state key and I just encode the necessary (validated) data items needed for the next step as a JSON blob. It's essentially a very short-lived web session. If for some reason you really do need to transmit this data in-band (ultra rare use case) you should at least be using something like HMAC to verify that all carriers have transported the data unmodified. It is your responsibility to ensure the integrity of the data end-to-end.
- matja 3y agoBut in the POC link, they have state=1 as a parameter for the authorization server, there is another state parameter encoded into the value for the redirect_uri, which makes me wonder why that even matches the registered redirect_uri.
- 0xcrypto 3y agoYou are right that redirect_uri must match the exact registered redirect_uri. But some providers allow query parameters. For Microsoft, it was possible in 2020 when I reported the vulnerability. In 2022, they restricted query parameter support to only applications that is built for Work and School accounts and in August 2022, they added a section for this in the documentation. See: - Commit: https://github.com/MicrosoftDocs/azure-docs/commit/c249a0548d0a6d230f57bb132e1cf3e1d51ba977 https://github.com/MicrosoftDocs/azure-docs/commit/c249a0548... - Current Documentation: https://learn.microsoft.com/en-us/azure/active-directory/develop/reply-url#query-parameter-support-in-redirect-uris https://learn.microsoft.com/en-us/azure/active-directory/dev...