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('&nbsp;<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>&nbsp;&nbsp;</label>&nbsp;',
                                       $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>&nbsp;&nbsp;</label>&nbsp;',
                                       $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();