Page MenuHomePhabricator

Fix an anchor redirect issue with OAuth server, plus modernize the application a bit
ClosedPublic

Authored by epriestley on Mar 13 2014, 4:38 PM.
Tags
None
Referenced Files
F14062328: D8517.diff
Mon, Nov 18, 11:32 AM
F14046532: D8517.diff
Wed, Nov 13, 9:43 PM
F14041200: D8517.id.diff
Mon, Nov 11, 4:37 PM
F14034577: D8517.diff
Sun, Nov 10, 1:04 AM
F14004002: D8517.diff
Sat, Oct 26, 2:03 PM
F13989746: D8517.id20211.diff
Mon, Oct 21, 10:47 PM
F13974915: D8517.diff
Oct 18 2024, 7:56 AM
F13967671: D8517.id20211.diff
Oct 16 2024, 3:08 PM
Subscribers

Details

Summary

Ref T4593. Via HackerOne. An attacker can use the anchor reattachment, combined with the Facebook token workflow, combined with redirection on OAuth errors to capture access tokens. The attack works roughly like this:

  • Create an OAuth application on Phabricator.
  • Set the domain to evil.com.
  • Grab the OAuth URI for it (something like https://phabricator.com/oauthserver/auth/?redirect_uri=http://evil.com&...).
  • Add an invalid scope parameter (scope=xyz).
  • Use that URI to build a Facebook OAuth URI (something like https://facebook.com/oauth/?redirect_uri=http://phabricator.com/...&response_type=token).
  • After the user authorizes the application on Facebook (or instantly if they've already authorized it), they're redirected to the OAuth server, which processes the request. Since this is the 'token' workflow, it has auth information in the URL anchor/fragment.
  • The OAuth server notices the scope error and 302's to the attacker's domain, preserving the anchor in most browsers through anchor reattachment.
  • The attacker reads the anchor in JS and can do client workflow stuff.

To fix this, I've made several general changes/modernizations:

  • Add a new application and make it beta. This is mostly cleanup, but also turns the server off for typical installs (it's not generally useful quite yet).
  • Add a "Console" page to make it easier to navigate.
  • Modernize some of the UI, since I was touching most of it anyways.

Then I've made specific security-focused changes:

  • In the web-based OAuth workflow, send back a human-readable page when errors occur. I think this is universally correct. Previously, humans would get a blob of JSON if they entered an invalid URI, etc. This type of response is correct for the companion endpoint ("ServerTokenController") since it's called by programs, but I believe not correct for this endpoint ("AuthController") since it's used by humans. Most of this is general cleanup (give humans human-readable errors instead of JSON blobs).
  • Never 302 off this endpoint automatically. Previously, a small set of errors (notably, bad scope) would cause a 302 with 'error'. This exposes us to anchor reattachment, and isn't generally helpful to anyone, since the requesting application did something wrong and even if it's prepared to handle the error, it can't really do anything better than we can.
  • The only time we'll 'error' back now from this workflow is if a user explicitly cancels the workflow. This isn't a 302, but a normal link (the cancel button), so the anchor is lost.
  • Even if the application is already approved, don't blindly 302. Instead, show the user a confirmation dialog with a 'continue' link. This is perhaps slightly less user-friendly than the straight redirect, but I think it's pretty reasonable in general, and it gives us a lot of protection against these classes of attack. This redirect is then through a link, not a 302, so the anchor is again detached. -
Test Plan

I attempted to hit everything I touched. See screenshots.

Diff Detail

Repository
rP Phabricator
Branch
oauth1
Lint
Lint Passed
Unit
Tests Passed

Event Timeline

epriestley retitled this revision from to Fix an anchor redirect issue with OAuth server, plus modernize the application a bit.
epriestley updated this object.
epriestley edited the test plan for this revision. (Show Details)
epriestley added a reviewer: btrahan.
btrahan edited edge metadata.

Nice. Thanks for the cleanup / update-up while you were in there!

This revision is now accepted and ready to land.Mar 13 2014, 6:13 PM
epriestley updated this revision to Diff 20211.

Closed by commit rPae7324fd5b8a (authored by @epriestley).