From c4579277329adfbd5ce8a427e79ff257a0d4d10f Mon Sep 17 00:00:00 2001
From: Jared Hancock <jared@osticket.com>
Date: Wed, 30 Mar 2016 21:12:46 -0500
Subject: [PATCH] files: Require authentication to view attachments

This feature adds a setting to the control panel to require signing in to
view attachments. This is in addition to the security already provided in
the download URLs. Currently, download URLs are signed for a specific help
desk, and automatically expire after about 24 hours. The exact timing is the
following midnight allowing for at least 12 hours cache time.

Administrators can impose this extra security feature to refuse serving
attachment files if the user is not currently signed in. This could prevent
third-party users from viewing an attachment if they were able to get access
to the download URL before it expired.
---
 file.php                                          | 15 +++++++++++++++
 include/class.config.php                          |  6 ++++++
 include/i18n/en_US/help/tips/settings.system.yaml | 13 ++++++++++++-
 include/staff/settings-system.inc.php             | 10 ++++++++++
 4 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/file.php b/file.php
index fda45974e..d62d588eb 100644
--- a/file.php
+++ b/file.php
@@ -26,6 +26,21 @@ if (!$_GET['key']
     Http::response(404, __('Unknown or invalid file'));
 }
 
+// Enforce security settings
+if ($cfg->isAuthRequiredForFiles() && !$thisclient) {
+    if (!($U = StaffAuthenticationBackend::getUser())) {
+        // Try and determine if a staff is viewing this page
+        if (strpos($_SERVER['HTTP_REFERRER'], ROOT_PATH .  'scp/') !== false) {
+            $_SESSION['_staff']['auth']['dest'] =
+                '/' . ltrim($_SERVER['REQUEST_URI'], '/');
+            Http::redirect(ROOT_PATH.'scp/login.php');
+        }
+        else {
+            require 'secure.inc.php';
+        }
+    }
+}
+
 // Validate session access hash - we want to make sure the link is FRESH!
 // and the user has access to the parent ticket!!
 if ($file->verifySignature($_GET['signature'], $_GET['expires'])) {
diff --git a/include/class.config.php b/include/class.config.php
index 165ad0846..190e58f68 100644
--- a/include/class.config.php
+++ b/include/class.config.php
@@ -207,6 +207,7 @@ class OsticketConfig extends Config {
         'agent_avatar' => 'gravatar.mm',
         'ticket_lock' => 2, // Lock on activity
         'max_open_tickets' => 0,
+        'files_req_auth' => 1,
     );
 
     function __construct($section=null) {
@@ -1150,6 +1151,7 @@ class OsticketConfig extends Config {
             'autolock_minutes' => $vars['autolock_minutes'],
             'enable_avatars' => isset($vars['enable_avatars']) ? 1 : 0,
             'enable_richtext' => isset($vars['enable_richtext']) ? 1 : 0,
+            'files_req_auth' => isset($vars['files_req_auth']) ? 1 : 0,
         ));
     }
 
@@ -1393,6 +1395,10 @@ class OsticketConfig extends Config {
         return ($id) ? AttachmentFile::lookup((int) $id) : null;
     }
 
+    function isAuthRequiredForFiles() {
+        return $this->get('files_req_auth');
+    }
+
     function updatePagesSettings($vars, &$errors) {
         global $ost;
 
diff --git a/include/i18n/en_US/help/tips/settings.system.yaml b/include/i18n/en_US/help/tips/settings.system.yaml
index 53ed8c65e..28b069775 100644
--- a/include/i18n/en_US/help/tips/settings.system.yaml
+++ b/include/i18n/en_US/help/tips/settings.system.yaml
@@ -142,7 +142,7 @@ default_storage_bk:
     title: File Storage Backend
     content: >
         Choose how attachments are stored.
-        <br<br>
+        <br><br>
         Additional storage backends can be added by installing storage plugins
 
 max_file_size:
@@ -155,3 +155,14 @@ max_file_size:
     links:
       - title: PHP ini settings
         href: "http://php.net/manual/en/ini.core.php#ini.upload-max-filesize"
+
+files_req_auth:
+    title: Require Login
+    content: >
+        Enable this setting to forbid serving attachments to unauthenticated
+        users. That is, users must sign into the system (both end users and
+        agents), in order to view attachments.
+        <br><br>
+        From a security perspective, be aware that the user's browser may
+        retain previously-viewed files in its cache. Furthermore, all file
+        links on your helpdesk automatically expire after about 24 hours.
diff --git a/include/staff/settings-system.inc.php b/include/staff/settings-system.inc.php
index 6560e7c20..6d0364220 100644
--- a/include/staff/settings-system.inc.php
+++ b/include/staff/settings-system.inc.php
@@ -359,6 +359,16 @@ $gmtime = Misc::gmtime();
                 <div class="error"><?php echo $errors['max_file_size']; ?></div>
             </td>
         </tr>
+        <tr>
+            <td width="180"><?php echo __('Login required');?>:</td>
+            <td>
+                <input type="checkbox" name="files_req_auth" <?php
+                    if ($config['files_req_auth']) echo 'checked="checked"';
+                    ?> />
+                <?php echo __('Require login to view any attachments'); ?>
+                <i class="help-tip icon-question-sign" href="#files_req_auth"></i>
+            </td>
+        </tr>
     </tbody>
 </table>
 <p style="text-align:center;">
-- 
GitLab