Skip to content

Commit 9a61375

Browse files
authored
Bug 2022058
1 parent 2b920e1 commit 9a61375

File tree

1 file changed

+20
-26
lines changed

1 file changed

+20
-26
lines changed

src/applications/files/controller/PhabricatorFileImageProxyController.php

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,12 @@ public function handleRequest(AphrontRequest $request) {
1111
$viewer = $request->getViewer();
1212
$img_uri = $request->getStr('uri');
1313

14-
// Validate the URI before doing anything
15-
PhabricatorEnv::requireValidRemoteURIForLink($img_uri);
14+
// Validate the URI before doing anything, including DNS resolution and
15+
// outbound blacklist check, to fail fast before consuming rate limit tokens.
16+
PhabricatorEnv::requireValidRemoteURIForFetch(
17+
$img_uri,
18+
array('http', 'https'));
1619
$uri = new PhutilURI($img_uri);
17-
$proto = $uri->getProtocol();
18-
19-
$allowed_protocols = array(
20-
'http',
21-
'https',
22-
);
23-
if (!in_array($proto, $allowed_protocols)) {
24-
throw new Exception(
25-
pht(
26-
'The provided image URI must use one of these protocols: %s.',
27-
implode(', ', $allowed_protocols)));
28-
}
2920

3021
// Check if we already have the specified image URI downloaded
3122
$cached_request = id(new PhabricatorFileExternalRequest())->loadOneWhere(
@@ -45,10 +36,11 @@ public function handleRequest(AphrontRequest $request) {
4536
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
4637
$save_request = false;
4738
try {
48-
// Rate limit outbound fetches to make this mechanism less useful for
49-
// scanning networks and ports.
39+
// Rate limit outbound fetches by remote IP to make this mechanism less
40+
// useful for scanning networks and ports. Using IP (not PHID) ensures
41+
// anonymous users are not all collapsed into a single actor.
5042
PhabricatorSystemActionEngine::willTakeAction(
51-
array($viewer->getPHID()),
43+
array(PhabricatorSystemActionEngine::newActorFromRequest($request)),
5244
new PhabricatorFilesOutboundRequestAction(),
5345
1);
5446

@@ -64,13 +56,14 @@ public function handleRequest(AphrontRequest $request) {
6456
$engine = new PhabricatorDestructionEngine();
6557
$engine->destroyObject($file);
6658
$file = null;
59+
phlog(pht(
60+
'Image proxy rejected "%s": not a valid image (MIME type: "%s").',
61+
$uri,
62+
$mime_type));
6763
throw new Exception(
6864
pht(
69-
'The URI "%s" does not correspond to a valid image file (got '.
70-
'a file with MIME type "%s"). You must specify the URI of a '.
71-
'valid image file.',
72-
$uri,
73-
$mime_type));
65+
'The URI does not correspond to a valid image file. '.
66+
'You must specify the URI of a valid image file.'));
7467
}
7568

7669
$file->save();
@@ -119,11 +112,12 @@ public function handleRequest(AphrontRequest $request) {
119112
private function getExternalResponse(
120113
PhabricatorFileExternalRequest $request) {
121114
if (!$request->getIsSuccessful()) {
115+
phlog(pht(
116+
'Image proxy failed for "%s": %s',
117+
$request->getURI(),
118+
$request->getResponseMessage()));
122119
throw new Exception(
123-
pht(
124-
'Request to "%s" failed: %s',
125-
$request->getURI(),
126-
$request->getResponseMessage()));
120+
pht('Unable to load the requested image.'));
127121
}
128122

129123
$file = id(new PhabricatorFileQuery())

0 commit comments

Comments
 (0)