Skip to content

Commit

Permalink
security: HTML File Browser Execution (Windows: Firefox/IE)
Browse files Browse the repository at this point in the history
This addresses an issue reported by Aishwarya Iyer where attached HTML files
are executed in the browser instead of forcing download in Firefox and IE
for Windows specifically. This is caused by an incorrect
`Content-Disposition` set in the `AttachmentFile::download` function.
Instead of attachments having a disposition of `attachment` (which forces
download) they have a disposition of `inline` (which displays the file
contents in the browser). This updates the download function to use whatever
disposition is passed (for S3 plugin), if none it defaults to `attachment`.
In addition, this overwrites the disposition and sets it to `attachment`
after the `$bk->sendRedirectURL()` so that S3 attachments still work and the
issue of an attacker passing their own disposition is mitigated.
  • Loading branch information
JediKev committed Jul 24, 2019
1 parent 9e5a476 commit 33ed106
Showing 1 changed file with 4 additions and 2 deletions.
6 changes: 4 additions & 2 deletions include/class.file.php
Expand Up @@ -240,14 +240,16 @@ static function _genUrlSignature($id, $key, $signature, $expires) {
} }


function download($disposition=false, $expires=false) { function download($disposition=false, $expires=false) {
$disposition = $disposition ?: 'inline'; $disposition = ($disposition && strcasecmp($disposition, 'inline') == 0
&& strpos($this->getType(), 'image/') !== false)
? 'inline' : 'attachment';
$bk = $this->open(); $bk = $this->open();
if ($bk->sendRedirectUrl($disposition)) if ($bk->sendRedirectUrl($disposition))
return; return;
$ttl = ($expires) ? $expires - Misc::gmtime() : false; $ttl = ($expires) ? $expires - Misc::gmtime() : false;
$this->makeCacheable($ttl); $this->makeCacheable($ttl);
$type = $this->getType() ?: 'application/octet-stream'; $type = $this->getType() ?: 'application/octet-stream';
Http::download($this->getName(), $type, null, 'inline'); Http::download($this->getName(), $type, null, $disposition);
header('Content-Length: '.$this->getSize()); header('Content-Length: '.$this->getSize());
$this->sendData(false); $this->sendData(false);
exit(); exit();
Expand Down

0 comments on commit 33ed106

Please sign in to comment.