[CORE] Attachments and thumbnails aren't accessed directly by the file under the file storage folder, but indirectly from PHP, so that access to the file folder can be blocked in the server config

This commit is contained in:
Miguel Dantas 2019-06-25 23:20:17 +01:00 committed by Diogo Cordeiro
parent b669f57068
commit 3c9a07677e
6 changed files with 44 additions and 43 deletions

View File

@ -1,4 +1,4 @@
# GNU social 1.22.x
# GNU social 1.23.x
(c) 2010-2019 Free Software Foundation, Inc
This is the README file for GNU social, the free

View File

@ -57,11 +57,44 @@ class Attachment_thumbnailAction extends AttachmentAction
{
// Returns a File_thumbnail object or throws exception if not available
try {
$thumbnail = $this->attachment->getThumbnail($this->thumb_w, $this->thumb_h, $this->thumb_c);
$file = $this->attachment->getThumbnail($this->thumb_w, $this->thumb_h, $this->thumb_c)->getFile();
} catch (UseFileAsThumbnailException $e) {
common_redirect($e->file->getUrl(), 302);
// With this exception, the file exists locally
$file = $e->file;
}
common_redirect(File_thumbnail::url($thumbnail->getFilename()), 302);
if (!$file->isLocal()) {
// Not locally stored, redirect to the URL the file came from
// Don't use getURL because it can give us a local URL, which we don't want
common_redirect($file->url, 302);
} else {
$filepath = $this->attachment->getPath();
$filename = MediaFile::getDisplayName($file);
// Disable errors, to not mess with the file contents (suppress errors in case access to this
// function is blocked, like in some shared hosts). Automatically reset at the end of the
// script execution, and we don't want to have any more errors until then, so don't reset it
@ini_set('display_errors', 0);
header("Content-Description: File Transfer");
header("Content-Type: {$file->mimetype}");
header("Content-Disposition: inline; filename=\"{$filename}\"");
header('Expires: 0');
header('Content-Transfer-Encoding: binary');
$filesize = $this->file->size;
// 'if available', it says, so ensure we have it
if (empty($filesize)) {
$filesize = filesize($this->attachment->filename);
}
header("Content-Length: {$filesize}");
// header('Cache-Control: private, no-transform, no-store, must-revalidate');
$ret = @readfile($filepath);
if ($ret === false || $ret !== $filesize) {
common_log(LOG_ERR, "The lengths of the file as recorded on the DB (or on disk) for the file " .
"{$filepath}, with id={$this->attachment->id} differ from what was sent to the user.");
}
}
}
}

View File

@ -594,6 +594,11 @@ class File extends Managed_DataObject
return common_local_url('attachment', array('attachment'=>$this->getID()));
}
public function getAttachmentDownloadUrl()
{
return common_local_url('attachment_download', array('attachment'=>$this->getID()));
}
/**
* @param mixed $use_local true means require local, null means prefer local, false means use whatever is stored
* @return string

View File

@ -56,6 +56,6 @@ class Attachment extends AttachmentListItem
}
function linkAttr() {
return array('rel' => 'external', 'href' => $this->attachment->getUrl());
return array('rel' => 'external', 'href' => $this->attachment->getAttachmentDownloadUrl());
}
}

View File

@ -32,7 +32,7 @@ defined('GNUSOCIAL') || die();
define('GNUSOCIAL_ENGINE', 'GNU social');
define('GNUSOCIAL_ENGINE_URL', 'https://www.gnu.org/software/social/');
define('GNUSOCIAL_BASE_VERSION', '1.22.1');
define('GNUSOCIAL_BASE_VERSION', '1.23.0');
define('GNUSOCIAL_LIFECYCLE', 'dev'); // 'dev', 'alpha[0-9]+', 'beta[0-9]+', 'rc[0-9]+', 'release'
define('GNUSOCIAL_VERSION', GNUSOCIAL_BASE_VERSION . '-' . GNUSOCIAL_LIFECYCLE);

View File

@ -83,9 +83,7 @@ class MediaFile
array('attachment' => $this->fileRecord->id)
);
$this->maybeAddRedir($this->fileRecord->id, $this->fileurl);
$this->short_fileurl = common_shorten_url($this->fileurl);
$this->maybeAddRedir($this->fileRecord->id, $this->short_fileurl);
}
}
@ -210,41 +208,6 @@ class MediaFile
return $file;
}
public function rememberFile($file, $short)
{
$this->maybeAddRedir($file->id, $short);
}
/**
* Adds Redir if needed.
*
* @param $file_id
* @param $url
* @return bool false if no need to add, true if added
* @throws ClientException If failed adding
*/
public function maybeAddRedir($file_id, $url)
{
try {
File_redirection::getByUrl($url);
return false;
} catch (NoResultException $e) {
$file_redir = new File_redirection;
$file_redir->urlhash = File::hashurl($url);
$file_redir->url = $url;
$file_redir->file_id = $file_id;
$result = $file_redir->insert();
if ($result===false) {
common_log_db_error($file_redir, "INSERT", __FILE__);
// TRANS: Client exception thrown when a database error was thrown during a file upload operation.
throw new ClientException(_('There was a database error while saving your file. Please try again.'));
}
return $result;
}
}
/**
* The maximum allowed file size, as a string
*/