Hacker News new | past | comments | ask | show | jobs | submit login

The vulnerability came from the outlook-integration.harvestapp.com. It used a JSON object as `state` containing instructions once the OAuth2 Callback succeeded.

The property `subdomain` was used to redirect the browser to a subdomain of harvestapp.com, passing the `#id-token`. The problem came from the fact that the value of `subdomain` was injected directly to:

https://${subdomain}.harvestapp.com/...#id-token=...

By setting the `subdomain` in JSON payload to `attacker-controlled.com/` (note the trailing slash), the URL become:

  https://attacker-controlled.com/.harvestapp.com/...#id-token=..
..thus redirects the browser to another domain, leaking the token.



So it was the combination of:

* the additional redirect using the JSON object in state * the `subdomain` not being properly verified * the implicit grant being supported

Which allowed an attacker to get an access token for a user's Microsoft account.

From my reading, this seems to be entirely an issue due to an improper implementation on Harvest's side, nothing to do with Microsoft's implementation of OAuth. Am I correct?


Clearly not, or I doubt we would be reading this blog post.

I assume that for several years though, that was exactly what Microsoft thought too.


What am I missing then?

It seems pretty clear to me from reading the blog post that the issue was what I outlined (sorry for the lack of list formatting, I always forget I need an extra line after each bullet point).


Not sure what parent was talking about. You are correct. This is Harvest’s responsibility, not Microsoft’s.


I didn't understand the article correctly. I was wrong.


Good explanation. Quick follow up, so to resolve this issue, what I have in mind are :

1. Make sure the redirect url is a valid harvestapp.com (more checks on state)

2. Encrypt the state since the start of the request, so then they can double check the state hasn't been forged by decrypt and compare

Is there any option beside those?


All they had to do was sanitize the subdomain var to only allow values valid in host part of a URL. But also, one of the state parameter's primary uses is exactly to prevent XSRF attacks like this by using a random nonce value so that you can validate from the redirect that your system was the initiator of the auth request. The data in this state was not sensitive, so encryption is not really necessary.


Why not just use a random ID and pull from DB instead of shuffling around a json payload? Really trying to avoid that DB hit? Just pay the price imo




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: