@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Generate a 403 page with a nice dialog when a file token is invalid

Summary:
Ref T5685. Currently we just 403 on an invalid token, but we can be a little more helpful.

The issues here are:

- If we **do** redirect you on this page and something goes wrong, you might get stuck in a redirect loop.
- If we **don't** redirect you, copy/pasting the link to someone (or reloading the page) gives them a pretty confusing result, since the link doesn't work any more. Prior to this diff, they get a 403.

To mitigate this, do a little better than a bare 403: give them a link to auth and generate a new URI for the file.

If this is still confusing, the next best thing I can come up with is something like this:

- Put some modulous of the timestamp in the URI.
- If the current time is within 2 seconds of the generation time, show this dialog.
- Otherwise, redirect.

That seems like it would be okay, but I worry that "2" has to be small (so links you copy/paste -> chat -> click still work) and a small value means that a small amount of clock skew breaks things. We could use the database clock, but ehhh.

Other ideas:

- Put a hash of the remote IP in the URI, redirect if it doesn't match. Fails for companies behind a NAT gateway but should work in a lot of other cases.
- Just redirect always, there's no reason it should ever loop and browsers don't really do anything bad when there's a loop (they'll show an error after too many redirects).

I'm leaning toward letting this stabilize in the wild for a bit, then trying "always redirect".

Test Plan: {F188914}

Reviewers: btrahan, 20after4

Reviewed By: 20after4

Subscribers: epriestley

Maniphest Tasks: T5685

Differential Revision: https://secure.phabricator.com/D10215

+38 -15
-11
src/applications/files/controller/PhabricatorFileController.php
··· 2 2 3 3 abstract class PhabricatorFileController extends PhabricatorController { 4 4 5 - public function buildApplicationCrumbs() { 6 - $crumbs = parent::buildApplicationCrumbs(); 7 - $crumbs->addAction( 8 - id(new PHUIListItemView()) 9 - ->setName(pht('Upload File')) 10 - ->setIcon('fa-upload') 11 - ->setHref($this->getApplicationURI('/upload/'))); 12 - 13 - return $crumbs; 14 - } 15 - 16 5 protected function buildSideNavView() { 17 6 $menu = $this->buildMenu($for_devices = false); 18 7 return AphrontSideNavFilterView::newFromMenu($menu);
+27 -4
src/applications/files/controller/PhabricatorFileDataController.php
··· 90 90 return $error_response; 91 91 } 92 92 93 + $acquire_token_uri = id(new PhutilURI($file->getViewURI())) 94 + ->setDomain($main_domain); 95 + 96 + 93 97 if ($this->token) { 94 98 // validate the token, if it is valid, continue 95 99 $validated_token = $file->validateOneTimeToken($this->token); 96 100 97 101 if (!$validated_token) { 98 - return new Aphront403Response(); 102 + $dialog = $this->newDialog() 103 + ->setShortTitle(pht('Expired File')) 104 + ->setTitle(pht('File Link Has Expired')) 105 + ->appendParagraph( 106 + pht( 107 + 'The link you followed to view this file is invalid or '. 108 + 'expired.')) 109 + ->appendParagraph( 110 + pht( 111 + 'Continue to generate a new link to the file. You may be '. 112 + 'required to log in.')) 113 + ->addCancelButton( 114 + $acquire_token_uri, 115 + pht('Continue')); 116 + 117 + // Build an explicit response so we can respond with HTTP/403 instead 118 + // of HTTP/200. 119 + $response = id(new AphrontDialogResponse()) 120 + ->setDialog($dialog) 121 + ->setHTTPResponseCode(403); 122 + 123 + return $response; 99 124 } 100 125 // return the file data without cache headers 101 126 $cache_response = false; 102 127 } else if (!$file->getCanCDN()) { 103 128 // file cannot be served via cdn, and no token given 104 129 // redirect to the main domain to aquire a token 105 - $file_uri = id(new PhutilURI($file->getViewURI())) 106 - ->setDomain($main_domain); 107 130 108 131 return id(new AphrontRedirectResponse()) 109 - ->setURI($file_uri); 132 + ->setURI($acquire_token_uri); 110 133 } 111 134 } 112 135
+11
src/applications/files/controller/PhabricatorFileListController.php
··· 22 22 return $this->delegateToController($controller); 23 23 } 24 24 25 + public function buildApplicationCrumbs() { 26 + $crumbs = parent::buildApplicationCrumbs(); 27 + $crumbs->addAction( 28 + id(new PHUIListItemView()) 29 + ->setName(pht('Upload File')) 30 + ->setIcon('fa-upload') 31 + ->setHref($this->getApplicationURI('/upload/'))); 32 + 33 + return $crumbs; 34 + } 35 + 25 36 }