2011-05-22 11:55:10 -07:00
|
|
|
<?php
|
|
|
|
|
|
2012-03-09 15:46:25 -08:00
|
|
|
final class PhabricatorFileDropUploadController
|
|
|
|
|
extends PhabricatorFileController {
|
2011-05-22 11:55:10 -07:00
|
|
|
|
2013-06-24 08:21:42 -07:00
|
|
|
/**
|
|
|
|
|
* @phutil-external-symbol class PhabricatorStartup
|
|
|
|
|
*/
|
2011-05-22 11:55:10 -07:00
|
|
|
public function processRequest() {
|
|
|
|
|
$request = $this->getRequest();
|
Give files uploaded to objects a very restrictive view policy
Summary:
Fixes T4589. This implements much better policy behavior for files that aligns with user expectations.
Currently, all files have permissive visibility.
The new behavior is:
- Files uploaded via drag-and-drop to the home page or file upload page get permissive visibility, for ease of quickly sharing things like screenshots.
- Files uploaded via the manual file upload control get permissive visibility by default, but the user can select the policy they want at upload time in an explicit/obvious way.
- Files uploaded via drag-and-drop anywhere else (e.g., comments or Pholio) get restricted visibility (only the uploader).
- When the user applies a transaction to the object which uses the file, we attach the file to the object and punch a hole through the policies: if you can see the object, you can see the file.
- This rule requires things to use ApplicationTransactions, which is why this took so long to fix.
- The "attach stuff to the object" code has been in place for a long time and works correctly.
I'll land D8498 after this lands, too.
Test Plan:
- Uploaded via global homepage upload and file drag-and-drop upload, saw permissive visibility.
- Uploaded via comment area, saw restricted visibility.
- After commenting, verified links were established and the file became visible to users who could see the attached object.
- Verified Pholio (which is a bit of a special case) correctly attaches images.
Reviewers: btrahan
Reviewed By: btrahan
Subscribers: epriestley
Maniphest Tasks: T4589
Differential Revision: https://secure.phabricator.com/D10131
2014-08-02 14:46:13 -07:00
|
|
|
$viewer = $request->getUser();
|
2011-05-22 11:55:10 -07:00
|
|
|
|
Prevent CSRF uploads via /file/dropupload/
Summary:
We don't currently validate CSRF tokens on this workflow. This allows an
attacker to upload arbitrary files on the user's behalf. Although I believe the
tight list of servable mime-types means that's more or less the end of the
attack, this is still a vulnerability.
In the long term, the right solution is probably to pass CSRF tokens on all Ajax
requests in an HTTP header (or just a GET param) or something like that.
However, this endpoint is unique and this is the quickest and most direct way to
close the hole.
Test Plan:
- Drop-uploaded files to Files, Maniphest, Phriction and Differential.
- Modified CSRF vaidator to use __csrf__.'x' and verified uploads and form
submissions don't work.
Reviewers: andrewjcg, aran, jungejason, tuomaspelkonen, erling
Commenters: andrewjcg, pedram
CC: aran, epriestley, andrewjcg, pedram
Differential Revision: 758
2011-08-01 20:23:01 -07:00
|
|
|
// NOTE: Throws if valid CSRF token is not present in the request.
|
|
|
|
|
$request->validateCSRF();
|
|
|
|
|
|
2011-05-22 11:55:10 -07:00
|
|
|
$name = $request->getStr('name');
|
2015-03-13 11:30:36 -07:00
|
|
|
$file_phid = $request->getStr('phid');
|
Give files uploaded to objects a very restrictive view policy
Summary:
Fixes T4589. This implements much better policy behavior for files that aligns with user expectations.
Currently, all files have permissive visibility.
The new behavior is:
- Files uploaded via drag-and-drop to the home page or file upload page get permissive visibility, for ease of quickly sharing things like screenshots.
- Files uploaded via the manual file upload control get permissive visibility by default, but the user can select the policy they want at upload time in an explicit/obvious way.
- Files uploaded via drag-and-drop anywhere else (e.g., comments or Pholio) get restricted visibility (only the uploader).
- When the user applies a transaction to the object which uses the file, we attach the file to the object and punch a hole through the policies: if you can see the object, you can see the file.
- This rule requires things to use ApplicationTransactions, which is why this took so long to fix.
- The "attach stuff to the object" code has been in place for a long time and works correctly.
I'll land D8498 after this lands, too.
Test Plan:
- Uploaded via global homepage upload and file drag-and-drop upload, saw permissive visibility.
- Uploaded via comment area, saw restricted visibility.
- After commenting, verified links were established and the file became visible to users who could see the attached object.
- Verified Pholio (which is a bit of a special case) correctly attaches images.
Reviewers: btrahan
Reviewed By: btrahan
Subscribers: epriestley
Maniphest Tasks: T4589
Differential Revision: https://secure.phabricator.com/D10131
2014-08-02 14:46:13 -07:00
|
|
|
// If there's no explicit view policy, make it very restrictive by default.
|
|
|
|
|
// This is the correct policy for files dropped onto objects during
|
|
|
|
|
// creation, comment and edit flows.
|
|
|
|
|
$view_policy = $request->getStr('viewPolicy');
|
|
|
|
|
if (!$view_policy) {
|
|
|
|
|
$view_policy = $viewer->getPHID();
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-13 11:30:36 -07:00
|
|
|
$is_chunks = $request->getBool('querychunks');
|
|
|
|
|
if ($is_chunks) {
|
|
|
|
|
$params = array(
|
|
|
|
|
'filePHID' => $file_phid,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$result = id(new ConduitCall('file.querychunks', $params))
|
|
|
|
|
->setUser($viewer)
|
|
|
|
|
->execute();
|
|
|
|
|
|
|
|
|
|
return id(new AphrontAjaxResponse())->setContent($result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$is_allocate = $request->getBool('allocate');
|
|
|
|
|
if ($is_allocate) {
|
|
|
|
|
$params = array(
|
|
|
|
|
'name' => $name,
|
|
|
|
|
'contentLength' => $request->getInt('length'),
|
|
|
|
|
'viewPolicy' => $view_policy,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$result = id(new ConduitCall('file.allocate', $params))
|
|
|
|
|
->setUser($viewer)
|
|
|
|
|
->execute();
|
|
|
|
|
|
|
|
|
|
$file_phid = $result['filePHID'];
|
|
|
|
|
if ($file_phid) {
|
|
|
|
|
$file = $this->loadFile($file_phid);
|
|
|
|
|
$result += $this->getFileDictionary($file);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return id(new AphrontAjaxResponse())->setContent($result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Read the raw request data. We're either doing a chunk upload or a
|
|
|
|
|
// vanilla upload, so we need it.
|
|
|
|
|
$data = PhabricatorStartup::getRawInput();
|
|
|
|
|
|
|
|
|
|
$is_chunk_upload = $request->getBool('uploadchunk');
|
|
|
|
|
if ($is_chunk_upload) {
|
|
|
|
|
$params = array(
|
|
|
|
|
'filePHID' => $file_phid,
|
|
|
|
|
'byteStart' => $request->getInt('byteStart'),
|
|
|
|
|
'data' => $data,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$result = id(new ConduitCall('file.uploadchunk', $params))
|
|
|
|
|
->setUser($viewer)
|
|
|
|
|
->execute();
|
|
|
|
|
|
|
|
|
|
$file = $this->loadFile($file_phid);
|
|
|
|
|
if ($file->getIsPartial()) {
|
|
|
|
|
$result = array();
|
|
|
|
|
} else {
|
|
|
|
|
$result = array(
|
|
|
|
|
'complete' => true,
|
|
|
|
|
) + $this->getFileDictionary($file);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return id(new AphrontAjaxResponse())->setContent($result);
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-07 06:17:00 -07:00
|
|
|
$file = PhabricatorFile::newFromXHRUpload(
|
2011-05-22 11:55:10 -07:00
|
|
|
$data,
|
|
|
|
|
array(
|
|
|
|
|
'name' => $request->getStr('name'),
|
Give files uploaded to objects a very restrictive view policy
Summary:
Fixes T4589. This implements much better policy behavior for files that aligns with user expectations.
Currently, all files have permissive visibility.
The new behavior is:
- Files uploaded via drag-and-drop to the home page or file upload page get permissive visibility, for ease of quickly sharing things like screenshots.
- Files uploaded via the manual file upload control get permissive visibility by default, but the user can select the policy they want at upload time in an explicit/obvious way.
- Files uploaded via drag-and-drop anywhere else (e.g., comments or Pholio) get restricted visibility (only the uploader).
- When the user applies a transaction to the object which uses the file, we attach the file to the object and punch a hole through the policies: if you can see the object, you can see the file.
- This rule requires things to use ApplicationTransactions, which is why this took so long to fix.
- The "attach stuff to the object" code has been in place for a long time and works correctly.
I'll land D8498 after this lands, too.
Test Plan:
- Uploaded via global homepage upload and file drag-and-drop upload, saw permissive visibility.
- Uploaded via comment area, saw restricted visibility.
- After commenting, verified links were established and the file became visible to users who could see the attached object.
- Verified Pholio (which is a bit of a special case) correctly attaches images.
Reviewers: btrahan
Reviewed By: btrahan
Subscribers: epriestley
Maniphest Tasks: T4589
Differential Revision: https://secure.phabricator.com/D10131
2014-08-02 14:46:13 -07:00
|
|
|
'authorPHID' => $viewer->getPHID(),
|
|
|
|
|
'viewPolicy' => $view_policy,
|
2013-03-22 04:59:50 -07:00
|
|
|
'isExplicitUpload' => true,
|
2011-05-22 11:55:10 -07:00
|
|
|
));
|
|
|
|
|
|
2015-03-13 11:30:36 -07:00
|
|
|
$result = $this->getFileDictionary($file);
|
|
|
|
|
return id(new AphrontAjaxResponse())->setContent($result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function getFileDictionary(PhabricatorFile $file) {
|
|
|
|
|
return array(
|
|
|
|
|
'id' => $file->getID(),
|
|
|
|
|
'phid' => $file->getPHID(),
|
|
|
|
|
'uri' => $file->getBestURI(),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function loadFile($file_phid) {
|
|
|
|
|
$viewer = $this->getViewer();
|
|
|
|
|
|
|
|
|
|
$file = id(new PhabricatorFileQuery())
|
|
|
|
|
->setViewer($viewer)
|
|
|
|
|
->withPHIDs(array($file_phid))
|
|
|
|
|
->executeOne();
|
|
|
|
|
if (!$file) {
|
|
|
|
|
throw new Exception(pht('Failed to load file.'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $file;
|
2011-05-22 11:55:10 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|