Be more strict about "Location:" redirects

Summary:
Via HackerOne. Chrome (at least) interprets backslashes like forward slashes, so a redirect to "/\evil.com" is the same as a redirect to "//evil.com".

  - Reject local URIs with backslashes (we never generate these).
  - Fully-qualify all "Location:" redirects.
  - Require external redirects to be marked explicitly.

Test Plan:
  - Expanded existing test coverage.
  - Verified that neither Diffusion nor Phriction can generate URIs with backslashes (they are escaped in Diffusion, and removed by slugging in Phriction).
  - Logged in with Facebook (OAuth2 submits a form to the external site, and isn't affected) and Twitter (OAuth1 redirects, and is affected).
  - Went through some local redirects (login, save-an-object).
  - Verified file still work.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Differential Revision: https://secure.phabricator.com/D10291
This commit is contained in:
epriestley
2014-08-18 14:11:06 -07:00
parent fe042def42
commit df361470c1
10 changed files with 183 additions and 6 deletions

View File

@@ -74,6 +74,7 @@ final class PhabricatorFileDataController extends PhabricatorFileController {
// if the user can see the file, generate a token;
// redirect to the alt domain with the token;
return id(new AphrontRedirectResponse())
->setIsExternal(true)
->setURI($file->getCDNURIWithToken());
} else {
@@ -128,7 +129,9 @@ final class PhabricatorFileDataController extends PhabricatorFileController {
// file cannot be served via cdn, and no token given
// redirect to the main domain to aquire a token
// This is marked as an "external" URI because it is fully qualified.
return id(new AphrontRedirectResponse())
->setIsExternal(true)
->setURI($acquire_token_uri);
}
}
@@ -171,7 +174,10 @@ final class PhabricatorFileDataController extends PhabricatorFileController {
// authenticate users on the file domain. This should blunt any
// attacks based on iframes, script tags, applet tags, etc., at least.
// Send the user to the "info" page if they're using some other method.
// This is marked as "external" because it is fully qualified.
return id(new AphrontRedirectResponse())
->setIsExternal(true)
->setURI(PhabricatorEnv::getProductionURI($file->getBestURI()));
}
$response->setMimeType($file->getMimeType());