diff --git a/include/class.attachment.php b/include/class.attachment.php index 10159f5e82842892398a9de147534e2807cc3b09..c605b7ca03d6ed8e0d5a4818d110b4ba16df7307 100644 --- a/include/class.attachment.php +++ b/include/class.attachment.php @@ -171,7 +171,6 @@ class GenericAttachments { $attachments = array(); foreach ($this->attachments as $a) { if ($a['inline'] != $separate || $a['inline'] == $inlines) { - $a['key'] = md5($a['id'].session_id().$a['key']); $a['file_id'] = $a['id']; $attachments[] = $a; } diff --git a/include/class.faq.php b/include/class.faq.php index d009d58c3bce290d758fa05edeb12b3872c938e9..09d5b2dcb0280e1e39c31ff322d2247d19d6c5a5 100644 --- a/include/class.faq.php +++ b/include/class.faq.php @@ -195,7 +195,7 @@ class FAQ { if(($attachments=$this->attachments->getSeparates())) { foreach($attachments as $attachment ) { /* The h key must match validation in file.php */ - $hash=$attachment['hash'].md5($attachment['id'].session_id().$attachment['hash']); + $hash=$attachment['key'].md5($attachment['id'].session_id().strtolower($attachment['key'])); if($attachment['size']) $size=sprintf(' <small>(<i>%s</i>)</small>',Format::file_size($attachment['size'])); diff --git a/include/class.file.php b/include/class.file.php index d68a3b11b1f403a4a0aacc1a58db37c61151eb68..902eaf2eaec83f32eeda2d23e614fe0051dee0ac 100644 --- a/include/class.file.php +++ b/include/class.file.php @@ -112,7 +112,8 @@ class AttachmentFile { * download this file */ function getDownloadHash() { - return strtolower($this->getKey() . md5($this->getId().session_id().$this->getKey())); + return strtolower($this->getKey() + . md5($this->getId().session_id().strtolower($this->getKey()))); } function open() { @@ -200,7 +201,8 @@ class AttachmentFile { if ($bk->sendRedirectUrl('inline')) return; $this->makeCacheable(); - Http::download($this->getName(), $this->getType() ?: 'application/octet-stream'); + Http::download($this->getName(), $this->getType() ?: 'application/octet-stream', + null, 'inline'); header('Content-Length: '.$this->getSize()); $this->sendData(false); exit(); diff --git a/include/class.format.php b/include/class.format.php index 5cbcd048e9a26527e97311790a653a18b1855952..c8980326d08c7b404e8511942f35aebd0d79204c 100644 --- a/include/class.format.php +++ b/include/class.format.php @@ -383,7 +383,7 @@ class Format { function viewableImages($html, $script='image.php') { - return preg_replace_callback('/"cid:([\w.-_]{32})"/', + return preg_replace_callback('/"cid:([\w._-]{32})"/', function($match) use ($script) { $hash = $match[1]; if (!($file = AttachmentFile::lookup($hash))) diff --git a/include/class.http.php b/include/class.http.php index a96ab84ab2f124f190c178d554c8d3aaaaaf44ce..3baea958a9495b3e8967510818f36cb561069ec4 100644 --- a/include/class.http.php +++ b/include/class.http.php @@ -95,14 +95,15 @@ class Http { return "filename*=UTF-8''".rawurlencode($filename); } - function download($filename, $type, $data=null) { + function download($filename, $type, $data=null, $disposition='attachment') { header('Pragma: private'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Cache-Control: private'); header('Content-Type: '.$type); - header('Content-Disposition: attachment; %s;', - self::getDispositionFilename(basename($filename))); + header(sprintf('Content-Disposition: %s; %s', + $disposition, + self::getDispositionFilename(basename($filename)))); header('Content-Transfer-Encoding: binary'); if ($data !== null) { header('Content-Length: '.strlen($data)); diff --git a/include/staff/cannedresponse.inc.php b/include/staff/cannedresponse.inc.php index d82baad74ffb9a98cd6dc494f3ab4ce9ae55c8fb..a14beb43a983548997e2e02945bc410d246d709e 100644 --- a/include/staff/cannedresponse.inc.php +++ b/include/staff/cannedresponse.inc.php @@ -87,7 +87,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); if($canned && ($files=$canned->attachments->getSeparates())) { echo '<div id="canned_attachments"><span class="faded">Uncheck to delete the attachment on submit</span><br>'; foreach($files as $file) { - $hash=$file['hash'].md5($file['id'].session_id().$file['hash']); + $hash=$file['key'].md5($file['id'].session_id().strtolower($file['key'])); echo sprintf('<label><input type="checkbox" name="files[]" id="f%d" value="%d" checked="checked"> <a href="file.php?h=%s">%s</a> </label> ', $file['id'], $file['id'], $hash, $file['name']); diff --git a/include/staff/faq.inc.php b/include/staff/faq.inc.php index 8b390c3de8d43762ce79f5560d07486e2c8bc636..8f412bdb69d27a4461dad20cd1f43aebe14b723a 100644 --- a/include/staff/faq.inc.php +++ b/include/staff/faq.inc.php @@ -101,7 +101,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); if($faq && ($files=$faq->attachments->getSeparates())) { echo '<div class="faq_attachments"><span class="faded">Uncheck to delete the attachment on submit</span><br>'; foreach($files as $file) { - $hash=$file['hash'].md5($file['id'].session_id().$file['hash']); + $hash=$file['key'].md5($file['id'].session_id().strtolower($file['key'])); echo sprintf('<label><input type="checkbox" name="files[]" id="f%d" value="%d" checked="checked"> <a href="file.php?h=%s">%s</a> </label> ', $file['id'], $file['id'], $hash, $file['name']); diff --git a/scp/file.php b/scp/file.php index 4ccc3b828c04f240de799714319781974a0353bd..9d6518d0ae4f4d53656389503bb83c71682a8963 100644 --- a/scp/file.php +++ b/scp/file.php @@ -23,7 +23,7 @@ $h=trim($_GET['h']); //basic checks if(!$h || strlen($h)!=64 //32*2 || !($file=AttachmentFile::lookup(substr($h,0,32))) //first 32 is the file hash. - || strcasecmp(substr($h,-32),md5($file->getId().session_id().strtolower($file->getKey())))) //next 32 is file id + session hash. + || $file->getDownloadHash() != $h) //next 32 is file id + session hash. die('Unknown or invalid file. #'.Format::htmlchars($_GET['h'])); $file->download();