Create AphrontWriteGuard, a backup mechanism for CSRF validation

Summary:
Provide a catchall mechanism to find unprotected writes.

  - Depends on D758.
  - Similar to WriteOnHTTPGet stuff from Facebook's stack.
  - Since we have a small number of storage mechanisms and highly structured
read/write pathways, we can explicitly answer the question "is this page
performing a write?".
  - Never allow writes without CSRF checks.
  - This will probably break some things. That's fine: they're CSRF
vulnerabilities or weird edge cases that we can fix. But don't push to Facebook
for a few days unless you're prepared to deal with this.
  - **>>> MEGADERP: All Conduit write APIs are currently vulnerable to CSRF!
<<<**

Test Plan:
  - Ran some scripts that perform writes (scripts/search indexers), no issues.
  - Performed normal CSRF submits.
  - Added writes to an un-CSRF'd page, got an exception.
  - Executed conduit methods.
  - Did login/logout (this works because the logged-out user validates the
logged-out csrf "token").
  - Did OAuth login.
  - Did OAuth registration.

Reviewers: pedram, andrewjcg, erling, jungejason, tuomaspelkonen, aran,
codeblock
Commenters: pedram
CC: aran, epriestley, pedram
Differential Revision: 777
This commit is contained in:
epriestley
2011-08-03 11:49:27 -07:00
parent 68c30e1a71
commit 39b4d20ce5
29 changed files with 397 additions and 2 deletions

View File

@@ -129,7 +129,8 @@ class PhabricatorOAuthLoginController extends PhabricatorAuthController {
}
$oauth_info->setUserID($current_user->getID());
$oauth_info->save();
$this->saveOAuthInfo($oauth_info);
return id(new AphrontRedirectResponse())
->setURI('/settings/page/'.$provider_key.'/');
@@ -149,7 +150,7 @@ class PhabricatorOAuthLoginController extends PhabricatorAuthController {
$session_key = $known_user->establishSession('web');
$oauth_info->save();
$this->saveOAuthInfo($oauth_info);
$request->setCookie('phusr', $known_user->getUsername());
$request->setCookie('phsid', $session_key);
@@ -317,4 +318,12 @@ class PhabricatorOAuthLoginController extends PhabricatorAuthController {
return $oauth_info;
}
private function saveOAuthInfo(PhabricatorUserOAuthInfo $info) {
// UNGUARDED WRITES: Logging-in users don't have their CSRF set up yet.
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
$info->save();
}
}