From 58011a4e8e7f5f168fd7dd1f53a23a3db1001138 Mon Sep 17 00:00:00 2001 From: epriestley Date: Tue, 4 Apr 2017 15:31:14 -0700 Subject: [PATCH] Upgrade File content hashing to SHA256 Summary: Ref T12464. This defuses any possible SHA1-collision attacks by using SHA256, for which there is no known collision. (SHA256 hashes are larger -- 256 bits -- so expand the storage column to 64 bytes to hold them.) Test Plan: - Uploaded the same file twice, saw the two files generate the same SHA256 content hash and use the same underlying data. - Tried with a fake hash algorihtm ("quackxyz") to make sure the failure mode worked/degraded correctly if we don't have SHA256 for some reason. Got two valid files with two copies of the same data, as expected. Reviewers: chad Reviewed By: chad Maniphest Tasks: T12464 Differential Revision: https://secure.phabricator.com/D17620 --- src/applications/files/storage/PhabricatorFile.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/applications/files/storage/PhabricatorFile.php b/src/applications/files/storage/PhabricatorFile.php index 08160f7cbc..1dfba734a7 100644 --- a/src/applications/files/storage/PhabricatorFile.php +++ b/src/applications/files/storage/PhabricatorFile.php @@ -94,7 +94,7 @@ final class PhabricatorFile extends PhabricatorFileDAO 'storageHandle' => 'text255', 'authorPHID' => 'phid?', 'secretKey' => 'bytes20?', - 'contentHash' => 'bytes40?', + 'contentHash' => 'bytes64?', 'ttl' => 'epoch?', 'isExplicitUpload' => 'bool?', 'mailKey' => 'bytes20', @@ -718,7 +718,17 @@ final class PhabricatorFile extends PhabricatorFileDAO } public static function hashFileContent($data) { - return null; + // NOTE: Hashing can fail if the algorithm isn't available in the current + // build of PHP. It's fine if we're unable to generate a content hash: + // it just means we'll store extra data when users upload duplicate files + // instead of being able to deduplicate it. + + $hash = hash('sha256', $data, $raw_output = false); + if ($hash === false) { + return null; + } + + return $hash; } public function loadFileData() {