From ff1d8b9e599a1ec315a9c34c279ba3645218c766 Mon Sep 17 00:00:00 2001
From: Jared Hancock <gravydish@gmail.com>
Date: Tue, 19 Jun 2012 22:49:47 -0500
Subject: [PATCH] Implement simple CSRF protection scheme

Protect againts cross-site request forgery attacks by requiring a special
form-field or header to be sent with requests that modify ticket system
data.

This meant a slight change to the AJAX ticket locking mechanism. It was
defined to lock with a GET request; however, GET requests are defined as
safe methods and should not modify backend data (such as a lock
acquisition). Therefore, the the lock acquire AJAX method was changed to
require a POST method.

Also remove old, no-longer-used staff panel include files
---
 include/ajax.tickets.php                      |   6 +
 include/class.ajax.php                        |   4 +
 include/class.csrf.php                        |  82 ++
 include/staff/apikey.inc.php                  |   1 +
 include/staff/apikeys.inc.php                 |   1 +
 include/staff/banlist.inc.php                 |   1 +
 include/staff/banrule.inc.php                 |   1 +
 include/staff/cannedreplies.inc.php           |   1 +
 include/staff/cannedreply.inc.php             |   1 +
 include/staff/categories.inc.php              |   1 +
 include/staff/category.inc.php                |   1 +
 include/staff/department.inc.php              |   1 +
 include/staff/departments.inc.php             |   1 +
 include/staff/email.inc.php                   |   1 +
 include/staff/emails.inc.php                  |   1 +
 include/staff/filter.inc.php                  |   1 +
 include/staff/filters.inc.php                 |   1 +
 include/staff/group.inc.php                   |   1 +
 include/staff/groups.inc.php                  |   1 +
 include/staff/header.inc.php                  |   1 +
 include/staff/helptopic.inc.php               |   1 +
 include/staff/helptopics.inc.php              |   1 +
 include/staff/preference.inc.php              | 498 ------------
 include/staff/profile.inc.php                 |   1 +
 include/staff/settings-alerts.inc.php         |   1 +
 include/staff/settings-attachments.inc.php    |   1 +
 include/staff/settings-autoresponders.inc.php |   1 +
 include/staff/settings-dates.inc.php          |   1 +
 include/staff/settings-emails.inc.php         |   1 +
 include/staff/settings-general.inc.php        |   1 +
 include/staff/settings-kb.inc.php             |   3 +-
 include/staff/settings-tickets.inc.php        |   1 +
 include/staff/settings.php                    | 721 ------------------
 include/staff/slaplan.inc.php                 |   1 +
 include/staff/slaplans.inc.php                |   1 +
 include/staff/staff.inc.php                   |   1 +
 include/staff/staffmembers.inc.php            |   1 +
 include/staff/syslogs.inc.php                 |   1 +
 include/staff/team.inc.php                    |   1 +
 include/staff/teams.inc.php                   |   1 +
 include/staff/template.inc.php                |   1 +
 include/staff/templates.inc.php               |   1 +
 include/staff/ticket-edit.inc.php             |   1 +
 include/staff/ticket-open.inc.php             |   1 +
 include/staff/ticket-view.inc.php             |   4 +
 scp/ajax.php                                  |   2 +-
 scp/js/scp.js                                 |   1 -
 scp/js/ticket.js                              |   2 +-
 scp/staff.inc.php                             |   4 +
 49 files changed, 141 insertions(+), 1224 deletions(-)
 create mode 100644 include/class.csrf.php
 delete mode 100644 include/staff/preference.inc.php
 delete mode 100644 include/staff/settings.php

diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php
index f67581005..46df9eb23 100644
--- a/include/ajax.tickets.php
+++ b/include/ajax.tickets.php
@@ -180,6 +180,8 @@ class TicketsAjaxAPI extends AjaxController {
 
     function acquireLock($tid) {
         global $cfg,$thisstaff;
+
+        $this->csrf_protect();
         
         if(!$tid or !is_numeric($tid) or !$thisstaff or !$cfg) 
             return 0;
@@ -214,6 +216,8 @@ class TicketsAjaxAPI extends AjaxController {
     function renewLock($tid, $id) {
         global $thisstaff;
 
+        $this->csrf_protect();
+
         if(!$id or !is_numeric($id) or !$thisstaff)
             return $this->json_encode(array('id'=>0, 'retry'=>true));
        
@@ -233,6 +237,8 @@ class TicketsAjaxAPI extends AjaxController {
     function releaseLock($tid, $id=0) {
         global $thisstaff;
 
+        $this->csrf_protect();
+
         if($id && is_numeric($id)){ //Lock Id provided!
         
             $lock = TicketLock::lookup($id, $tid);
diff --git a/include/class.ajax.php b/include/class.ajax.php
index 0240d91f8..5870f8039 100644
--- a/include/class.ajax.php
+++ b/include/class.ajax.php
@@ -51,6 +51,10 @@ class AjaxController extends ApiController {
         return $this->json_encode($what);
     }
 
+    function csrf_protect() {
+        csrf_ensure_cookie();
+    }
+
     function get($var, $default=null) {
         return (isset($_GET[$var])) ? $_GET[$var] : $default;
     }
diff --git a/include/class.csrf.php b/include/class.csrf.php
new file mode 100644
index 000000000..bf281499c
--- /dev/null
+++ b/include/class.csrf.php
@@ -0,0 +1,82 @@
+<?php
+/*********************************************************************
+    class.csrf.php
+
+    Provides mechanisms to protect against cross-site request forgery
+    attacks. This is accomplished by using a token that is not stored in a
+    cookie, but required to make changes to the system.
+
+    This can be accomplished by emitting a hidden field in a form, or
+    sending a separate header (X-CSRFToken) when forms are submitted.
+
+    This technique is based on the protection mechanism in the Django
+    project, detailed at and thanks to
+    https://docs.djangoproject.com/en/dev/ref/contrib/csrf/.
+
+    Jared Hancock 
+    Copyright (c)  2006-2012 osTicket
+    http://www.osticket.com
+
+    Released under the GNU General Public License WITHOUT ANY WARRANTY.
+    See LICENSE.TXT for details.
+
+    vim: expandtab sw=4 ts=4 sts=4:
+**********************************************************************/
+
+function csrf_token() {
+    ?>
+    <input type="hidden" name="__CSRFToken__" value="<?php
+        echo csrf_get_token(); ?>" />
+    <?php
+}
+
+function csrf_get_token($length=32) {
+    if (!isset($_SESSION['CSRFToken'])) {
+        for ($i = 0; $i <= $length; $i++)
+            $r .= chr(mt_rand(0, 255));
+        $_SESSION['CSRFToken'] = base64_encode($r);
+    }
+    return $_SESSION['CSRFToken'];
+}
+
+function csrf_ensure_cookie() {
+    $token = csrf_get_token();
+    if (isset($_POST['__CSRFToken__'])) {
+        if ($token == $_POST['__CSRFToken__'])
+            return true;
+    }
+    elseif (isset($_SERVER['HTTP_X_CSRFTOKEN'])) {
+        if ($token == $_SERVER['HTTP_X_CSRFTOKEN'])
+            return true;
+    }
+    Http::response(400, 'CSRF Token Required');
+}
+
+# Many thanks to https://docs.djangoproject.com/en/dev/ref/contrib/csrf/
+function csrf_enable_ajax() { ?>
+<script type="text/javascript">
+jQuery(document).ajaxSend(function(event, xhr, settings) {
+    function sameOrigin(url) {
+        // url could be relative or scheme relative or absolute
+        var host = document.location.host; // host + port
+        var protocol = document.location.protocol;
+        var sr_origin = '//' + host;
+        var origin = protocol + sr_origin;
+        // Allow absolute or scheme relative URLs to same origin
+        return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
+            (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
+            // or any other URL that isn't scheme relative or absolute i.e
+            // relative.
+            !(/^(\/\/|http:|https:).*/.test(url));
+    }
+    function safeMethod(method) {
+        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
+    }
+    if (!safeMethod(settings.type) && sameOrigin(settings.url)) {
+        xhr.setRequestHeader("X-CSRFToken", "<?php echo csrf_get_token(); ?>");
+    }
+});
+</script>
+<?php }
+
+?>
diff --git a/include/staff/apikey.inc.php b/include/staff/apikey.inc.php
index 7bcac1cb0..ff5592b46 100644
--- a/include/staff/apikey.inc.php
+++ b/include/staff/apikey.inc.php
@@ -20,6 +20,7 @@ if($api && $_REQUEST['a']!='add'){
 $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
 ?>
 <form action="apikeys.php?<?php echo $qstr; ?>" method="post" id="save">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="<?php echo $action; ?>">
  <input type="hidden" name="a" value="<?php echo Format::htmlchars($_REQUEST['a']); ?>">
  <input type="hidden" name="id" value="<?php echo $info['id']; ?>">
diff --git a/include/staff/apikeys.inc.php b/include/staff/apikeys.inc.php
index 3deccb941..fc0d418e7 100644
--- a/include/staff/apikeys.inc.php
+++ b/include/staff/apikeys.inc.php
@@ -46,6 +46,7 @@ else
  <b><a href="apikeys.php?a=add" class="Icon newapi">Add New API Key</a></b></div>
 <div class="clear"></div>
 <form action="apikeys.php" method="POST" name="keys" onSubmit="return checkbox_checker(this,1,0);">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="mass_process" >
  <table class="list" border="0" cellspacing="1" cellpadding="0" width="940">
     <caption><?php echo $showing; ?></caption>
diff --git a/include/staff/banlist.inc.php b/include/staff/banlist.inc.php
index 430b51f48..0b61d1e8b 100644
--- a/include/staff/banlist.inc.php
+++ b/include/staff/banlist.inc.php
@@ -72,6 +72,7 @@ if($search)
     
 ?>
 <form action="banlist.php" method="POST" name="banlist" onSubmit="return checkbox_checker(this,1,0);">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="mass_process" >
  <table class="list" border="0" cellspacing="1" cellpadding="0" width="940">
     <caption><?php echo $showing; ?></caption>
diff --git a/include/staff/banrule.inc.php b/include/staff/banrule.inc.php
index 0560b4a4d..1f1314736 100644
--- a/include/staff/banrule.inc.php
+++ b/include/staff/banrule.inc.php
@@ -20,6 +20,7 @@ if($rule && $_REQUEST['a']!='add'){
 $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
 ?>
 <form action="banlist.php?<?php echo $qstr; ?>" method="post" id="save">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="<?php echo $action; ?>">
  <input type="hidden" name="a" value="<?php echo Format::htmlchars($_REQUEST['a']); ?>">
  <input type="hidden" name="id" value="<?php echo $info['id']; ?>">
diff --git a/include/staff/cannedreplies.inc.php b/include/staff/cannedreplies.inc.php
index 39aaaae81..5464bf8d6 100644
--- a/include/staff/cannedreplies.inc.php
+++ b/include/staff/cannedreplies.inc.php
@@ -53,6 +53,7 @@ else
     <b><a href="canned.php?a=add" class="Icon newReply">Add New Reply</a></b></div>
 <div class="clear"></div>
 <form action="canned.php" method="POST" name="canned" onSubmit="return checkbox_checker(this,1,0);">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="mass_process" >
  <table class="list" border="0" cellspacing="1" cellpadding="0" width="940">
     <caption><?php echo $showing; ?></caption>
diff --git a/include/staff/cannedreply.inc.php b/include/staff/cannedreply.inc.php
index 55e29db7d..4e87d5854 100644
--- a/include/staff/cannedreply.inc.php
+++ b/include/staff/cannedreply.inc.php
@@ -20,6 +20,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
 
 ?>
 <form action="canned.php?<?php echo $qstr; ?>" method="post" id="save" enctype="multipart/form-data">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="<?php echo $action; ?>">
  <input type="hidden" name="a" value="<?php echo Format::htmlchars($_REQUEST['a']); ?>">
  <input type="hidden" name="id" value="<?php echo $info['id']; ?>">
diff --git a/include/staff/categories.inc.php b/include/staff/categories.inc.php
index 9e90869c0..df750fe79 100644
--- a/include/staff/categories.inc.php
+++ b/include/staff/categories.inc.php
@@ -47,6 +47,7 @@ else
     <b><a href="categories.php?a=add" class="Icon newCategory">Add New Category</a></b></div>
 <div class="clear"></div>
 <form action="categories.php" method="POST" name="cat" onSubmit="return checkbox_checker(this,1,0);">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="mass_process" >
  <table class="list" border="0" cellspacing="1" cellpadding="0" width="940">
     <caption><?php echo $showing; ?></caption>
diff --git a/include/staff/category.inc.php b/include/staff/category.inc.php
index 8272d7da1..c682219b0 100644
--- a/include/staff/category.inc.php
+++ b/include/staff/category.inc.php
@@ -19,6 +19,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
 
 ?>
 <form action="categories.php?<?php echo $qstr; ?>" method="post" id="save">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="<?php echo $action; ?>">
  <input type="hidden" name="a" value="<?php echo Format::htmlchars($_REQUEST['a']); ?>">
  <input type="hidden" name="id" value="<?php echo $info['id']; ?>">
diff --git a/include/staff/department.inc.php b/include/staff/department.inc.php
index 521cee9bf..943bfc90b 100644
--- a/include/staff/department.inc.php
+++ b/include/staff/department.inc.php
@@ -22,6 +22,7 @@ if($dept && $_REQUEST['a']!='add'){
 $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
 ?>
 <form action="departments.php?<?php echo $qstr; ?>" method="post" id="save">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="<?php echo $action; ?>">
  <input type="hidden" name="a" value="<?php echo Format::htmlchars($_REQUEST['a']); ?>">
  <input type="hidden" name="id" value="<?php echo $info['id']; ?>">
diff --git a/include/staff/departments.inc.php b/include/staff/departments.inc.php
index 71b702a06..a46115f42 100644
--- a/include/staff/departments.inc.php
+++ b/include/staff/departments.inc.php
@@ -47,6 +47,7 @@ else
     <b><a href="departments.php?a=add" class="Icon newDepartment">Add New Department</a></b></div>
 <div class="clear"></div>
 <form action="departments.php" method="POST" name="depts" onSubmit="return checkbox_checker(this,1,0);">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="mass_process" >
  <table class="list" border="0" cellspacing="1" cellpadding="0" width="940">
     <caption><?php echo $showing; ?></caption>
diff --git a/include/staff/email.inc.php b/include/staff/email.inc.php
index 2fd2b8857..e16b350bd 100644
--- a/include/staff/email.inc.php
+++ b/include/staff/email.inc.php
@@ -31,6 +31,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
 ?>
 <h2>Email Address</h2>
 <form action="emails.php?<?php echo $qstr; ?>" method="post" id="save">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="<?php echo $action; ?>">
  <input type="hidden" name="a" value="<?php echo Format::htmlchars($_REQUEST['a']); ?>">
  <input type="hidden" name="id" value="<?php echo $info['id']; ?>">
diff --git a/include/staff/emails.inc.php b/include/staff/emails.inc.php
index 8d5f22117..4ab93d221 100644
--- a/include/staff/emails.inc.php
+++ b/include/staff/emails.inc.php
@@ -49,6 +49,7 @@ else
     <b><a href="emails.php?a=add" class="Icon newEmail">Add New Email</a></b></div>
 <div class="clear"></div>
 <form action="emails.php" method="POST" name="emails" onSubmit="return checkbox_checker(this,1,0);">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="mass_process" >
  <table class="list" border="0" cellspacing="1" cellpadding="0" width="940">
     <caption><?php echo $showing; ?></caption>
diff --git a/include/staff/filter.inc.php b/include/staff/filter.inc.php
index 6f8cce2c4..22622e6c8 100644
--- a/include/staff/filter.inc.php
+++ b/include/staff/filter.inc.php
@@ -24,6 +24,7 @@ if($filter && $_REQUEST['a']!='add'){
 $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
 ?>
 <form action="filters.php?<?php echo $qstr; ?>" method="post" id="save">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="<?php echo $action; ?>">
  <input type="hidden" name="a" value="<?php echo Format::htmlchars($_REQUEST['a']); ?>">
  <input type="hidden" name="id" value="<?php echo $info['id']; ?>">
diff --git a/include/staff/filters.inc.php b/include/staff/filters.inc.php
index b5534bdde..7f3aab393 100644
--- a/include/staff/filters.inc.php
+++ b/include/staff/filters.inc.php
@@ -50,6 +50,7 @@ else
  <b><a href="filters.php?a=add" class="Icon newEmailFilter">Add New Filter</a></b></div>
 <div class="clear"></div>
 <form action="filters.php" method="POST" name="filters" onSubmit="return checkbox_checker(this,1,0);">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="mass_process" >
  <table class="list" border="0" cellspacing="1" cellpadding="0" width="940">
     <caption><?php echo $showing; ?></caption>
diff --git a/include/staff/group.inc.php b/include/staff/group.inc.php
index afb574f5f..8e2e99243 100644
--- a/include/staff/group.inc.php
+++ b/include/staff/group.inc.php
@@ -21,6 +21,7 @@ if($group && $_REQUEST['a']!='add'){
 $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
 ?>
 <form action="groups.php?<?php echo $qstr; ?>" method="post" id="save" name="group">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="<?php echo $action; ?>">
  <input type="hidden" name="a" value="<?php echo Format::htmlchars($_REQUEST['a']); ?>">
  <input type="hidden" name="id" value="<?php echo $info['id']; ?>">
diff --git a/include/staff/groups.inc.php b/include/staff/groups.inc.php
index ed5e3638a..95745e70c 100644
--- a/include/staff/groups.inc.php
+++ b/include/staff/groups.inc.php
@@ -43,6 +43,7 @@ else
     <b><a href="groups.php?a=add" class="Icon newgroup">Add New Group</a></b></div>
 <div class="clear"></div>
 <form action="groups.php" method="POST" name="groups" onSubmit="return checkbox_checker(this,1,0);">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="mass_process" >
  <table class="list" border="0" cellspacing="1" cellpadding="0" width="940">
     <caption><?php echo $showing; ?></caption>
diff --git a/include/staff/header.inc.php b/include/staff/header.inc.php
index c48ee8b36..f5bbd6102 100644
--- a/include/staff/header.inc.php
+++ b/include/staff/header.inc.php
@@ -21,6 +21,7 @@
     if($ost && ($headers=$ost->getExtraHeaders())) {
         echo "\n\t".implode("\n\t", $headers)."\n";
     }
+    csrf_enable_ajax();
     ?>
 </head>
 <body>
diff --git a/include/staff/helptopic.inc.php b/include/staff/helptopic.inc.php
index c0fdcd340..6c7c94211 100644
--- a/include/staff/helptopic.inc.php
+++ b/include/staff/helptopic.inc.php
@@ -20,6 +20,7 @@ if($topic && $_REQUEST['a']!='add'){
 $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
 ?>
 <form action="helptopics.php?<?php echo $qstr; ?>" method="post" id="save">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="<?php echo $action; ?>">
  <input type="hidden" name="a" value="<?php echo Format::htmlchars($_REQUEST['a']); ?>">
  <input type="hidden" name="id" value="<?php echo $info['id']; ?>">
diff --git a/include/staff/helptopics.inc.php b/include/staff/helptopics.inc.php
index b3d58c777..9e5482ff9 100644
--- a/include/staff/helptopics.inc.php
+++ b/include/staff/helptopics.inc.php
@@ -50,6 +50,7 @@ else
     <b><a href="helptopics.php?a=add" class="Icon newHelpTopic">Add New Help Topic</a></b></div>
 <div class="clear"></div>
 <form action="helptopics.php" method="POST" name="topics" onSubmit="return checkbox_checker(this,1,0);">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="mass_process" >
  <table class="list" border="0" cellspacing="1" cellpadding="0" width="940">
     <caption><?php echo $showing; ?></caption>
diff --git a/include/staff/preference.inc.php b/include/staff/preference.inc.php
deleted file mode 100644
index 6eb27354b..000000000
--- a/include/staff/preference.inc.php
+++ /dev/null
@@ -1,498 +0,0 @@
-<?php
-if(!defined('OSTADMININC') || !$thisstaff->isAdmin()) die('Access Denied');
-
-//Get the config info.
-$config=($errors && $_POST)?Format::input($_POST):Format::htmlchars($cfg->getConfigInfo());
-//Basic checks for warnings...
-$warn=array();
-if($config['allow_attachments'] && !$config['upload_dir']) {
-    $errors['allow_attachments']='You need to setup upload dir.';    
-}else{
-    if(!$config['allow_attachments'] && $config['allow_email_attachments'])
-        $warn['allow_email_attachments']='*Attachments Disabled.';
-    if(!$config['allow_attachments'] && ($config['allow_online_attachments'] or $config['allow_online_attachments_onlogin']))
-        $warn['allow_online_attachments']='<br>*Attachments Disabled.';
-}
-
-if(!$errors['enable_captcha'] && $config['enable_captcha'] && !extension_loaded('gd'))
-    $errors['enable_captcha']='GD required for captcha to work';
-    
-
-//Not showing err on post to avoid alarming the user...after an update.
-if(!$errors['err'] &&!$msg && $warn )
-    $errors['err']='Possible errors detected, please check the warnings below';
-    
-$gmtime=Misc::gmtime();
-$depts= db_query('SELECT dept_id,dept_name FROM '.DEPT_TABLE.' WHERE ispublic=1');
-$templates=db_query('SELECT tpl_id,name FROM '.EMAIL_TEMPLATE_TABLE.' WHERE cfg_id='.db_input($cfg->getId()));
-?>
-<div class="msg">System Preferences and Settings&nbsp;&nbsp;(v<?php echo $config['ostversion']; ?>)</div>
-<table width="100%" border="0" cellspacing=0 cellpadding=0>
- <form action="admin.php?t=pref" method="post">
- <input type="hidden" name="t" value="pref">
- <tr><td>
-    <table width="100%" border="0" cellspacing=0 cellpadding=2 class="tform">
-        <tr class="header" ><td colspan=2>General Settings</td></tr>
-        <tr class="subheader">
-            <td colspan=2">Offline mode will disable client interface and <b>only</b> allow <b>super admins</b> to login to Staff Control Panel</td>
-        </tr>
-        <tr><th><b>Helpdesk Status</b></th>
-            <td>
-                <input type="radio" name="isonline"  value="1"   <?php echo $config['isonline']?'checked':''; ?> /><b>Online</b> (Active)
-                <input type="radio" name="isonline"  value="0"   <?php echo !$config['isonline']?'checked':''; ?> /><b>Offline</b> (Disabled)
-                &nbsp;<font class="warn">&nbsp;<?php echo $config['isoffline']?'osTicket offline':''; ?></font>
-            </td>
-        </tr>
-        <tr><th>Helpdesk URL:</th>
-            <td>
-                <input type="text" size="40" name="helpdesk_url" value="<?php echo $config['helpdesk_url']; ?>"> 
-                &nbsp;<font class="error">*&nbsp;<?php echo $errors['helpdesk_url']; ?></font></td>
-        </tr>
-        <tr><th>Helpdesk Name/Title:</th>
-            <td><input type="text" size="40" name="helpdesk_title" value="<?php echo $config['helpdesk_title']; ?>"> </td>
-        </tr>
-        <tr><th>Default Email Templates:</th>
-            <td>
-                <select name="default_template_id">
-                    <option value=0>Select Default Template</option>
-                    <?php
-                    while (list($id,$name) = db_fetch_row($templates)){
-                        $selected = ($config['default_template_id']==$id)?'SELECTED':''; ?>
-                        <option value="<?php echo $id; ?>"<?php echo $selected; ?>><?php echo $name; ?></option>
-                    <?php
-                    } ?>
-                </select>&nbsp;<font class="error">*&nbsp;<?php echo $errors['default_template_id']; ?></font>
-            </td>
-        </tr>
-        <tr><th>Default Department:</th>
-            <td>
-                <select name="default_dept_id">
-                    <option value=0>Select Default Dept</option>
-                    <?php
-                    while (list($id,$name) = db_fetch_row($depts)){
-                    $selected = ($config['default_dept_id']==$id)?'SELECTED':''; ?>
-                    <option value="<?php echo $id; ?>"<?php echo $selected; ?>><?php echo $name; ?> Dept</option>
-                    <?php
-                    } ?>
-                </select>&nbsp;<font class="error">*&nbsp;<?php echo $errors['default_dept_id']; ?></font>
-            </td>
-        </tr>
-        <tr><th>Default Page Size:</th>
-            <td>
-                <select name="max_page_size">
-                    <?php
-                     $pagelimit=$config['max_page_size'];
-                    for ($i = 5; $i <= 50; $i += 5) {
-                        ?>
-                        <option <?php echo $config['max_page_size'] == $i ? 'SELECTED':''; ?> value="<?php echo $i; ?>"><?php echo $i; ?></option>
-                        <?php
-                    } ?>
-                </select>
-            </td>
-        </tr>
-        <tr><th>System Log Level:</th>
-            <td>
-                <select name="log_level">
-                    <option value=0 <?php echo $config['log_level'] == 0 ? 'selected="selected"':''; ?>>None (Disable Logger)</option>
-                    <option value=3 <?php echo $config['log_level'] == 3 ? 'selected="selected"':''; ?>> DEBUG</option>
-                    <option value=2 <?php echo $config['log_level'] == 2 ? 'selected="selected"':''; ?>> WARN</option>
-                    <option value=1 <?php echo $config['log_level'] == 1 ? 'selected="selected"':''; ?>> ERROR</option>
-                </select>
-                &nbsp;Purge logs after
-                <select name="log_graceperiod">
-                    <option value=0 selected> None (Disable)</option>
-                    <?php
-                    for ($i = 1; $i <=12; $i++) {
-                        ?>
-                        <option <?php echo $config['log_graceperiod'] == $i ? 'SELECTED':''; ?> value="<?php echo $i; ?>"><?php echo $i; ?>&nbsp;<?php echo ($i>1)?'Months':'Month'; ?></option>
-                        <?php
-                    } ?>
-                </select>
-            </td>
-        </tr>
-        <tr><th>Staff Excessive Logins:</th>
-            <td>
-                <select name="staff_max_logins">
-                  <?php
-                    for ($i = 1; $i <= 10; $i++) {
-                        echo sprintf('<option value="%d" %s>%d</option>',$i,(($config['staff_max_logins']==$i)?'selected="selected"':''),$i);
-                    }
-                    ?>
-                </select> attempt(s) allowed
-                &nbsp;before a
-                <select name="staff_login_timeout">
-                  <?php
-                    for ($i = 1; $i <= 10; $i++) {
-                        echo sprintf('<option value="%d" %s>%d</option>',$i,(($config['staff_login_timeout']==$i)?'selected="selected"':''),$i);
-                    }
-                    ?>
-                </select> min. timeout (penalty in minutes)
-            </td>
-        </tr>
-        <tr><th>Staff Session Timeout:</th>
-            <td>
-              <input type="text" name="staff_session_timeout" size=6 value="<?php echo $config['staff_session_timeout']; ?>">
-                (<i>Staff's max Idle time in minutes. Enter 0 to disable timeout</i>)
-            </td>
-        </tr>
-       <tr><th>Bind Staff Session to IP:</th>
-            <td>
-              <input type="checkbox" name="staff_ip_binding" <?php echo $config['staff_ip_binding']?'checked':''; ?>>
-               Bind staff's session to login IP.
-            </td>
-        </tr>
-
-        <tr><th>Client Excessive Logins:</th>
-            <td>
-                <select name="client_max_logins">
-                  <?php
-                    for ($i = 1; $i <= 10; $i++) {
-                        echo sprintf('<option value="%d" %s>%d</option>',$i,(($config['client_max_logins']==$i)?'selected="selected"':''),$i);
-                    }
-
-                    ?>
-                </select> attempt(s) allowed
-                &nbsp;before a
-                <select name="client_login_timeout">
-                  <?php
-                    for ($i = 1; $i <= 10; $i++) {
-                        echo sprintf('<option value="%d" %s>%d</option>',$i,(($config['client_login_timeout']==$i)?'selected="selected"':''),$i);
-                    }
-                    ?>
-                </select> min. timeout (penalty in minutes)
-            </td>
-        </tr>
-
-        <tr><th>Client Session Timeout:</th>
-            <td>
-              <input type="text" name="client_session_timeout" size=6 value="<?php echo $config['client_session_timeout']; ?>">
-                (<i>Client's max Idle time in minutes. Enter 0 to disable timeout</i>)
-            </td>
-        </tr>
-        <tr><th>Clickable URLs:</th>
-            <td>
-              <input type="checkbox" name="clickable_urls" <?php echo $config['clickable_urls']?'checked':''; ?>>
-                Make URLs clickable
-            </td>
-        </tr>
-        <tr><th>Enable Auto Cron:</th>
-            <td>
-              <input type="checkbox" name="enable_auto_cron" <?php echo $config['enable_auto_cron']?'checked':''; ?>>
-                Enable cron call on staff's activity
-            </td>
-        </tr>
-    </table>
-    
-    <table width="100%" border="0" cellspacing=0 cellpadding=2 class="tform">
-        <tr class="header"><td colspan=2>Date &amp; Time</td></tr>
-        <tr class="subheader">
-            <td colspan=2>Please refer to <a href="http://php.net/date" target="_blank">PHP Manual</a> for supported parameters.</td>
-        </tr>
-        <tr><th>Time Format:</th>
-            <td>
-                <input type="text" name="time_format" value="<?php echo $config['time_format']; ?>">
-                    &nbsp;<font class="error">*&nbsp;<?php echo $errors['time_format']; ?></font>
-                    <i><?php echo Format::date($config['time_format'],$gmtime,$config['timezone_offset'],$config['enable_daylight_saving']); ?></i></td>
-        </tr>
-        <tr><th>Date Format:</th>
-            <td><input type="text" name="date_format" value="<?php echo $config['date_format']; ?>">
-                        &nbsp;<font class="error">*&nbsp;<?php echo $errors['date_format']; ?></font>
-                        <i><?php echo Format::date($config['date_format'],$gmtime,$config['timezone_offset'],$config['enable_daylight_saving']); ?></i>
-            </td>
-        </tr>
-        <tr><th>Date &amp; Time Format:</th>
-            <td><input type="text" name="datetime_format" value="<?php echo $config['datetime_format']; ?>">
-                        &nbsp;<font class="error">*&nbsp;<?php echo $errors['datetime_format']; ?></font>
-                        <i><?php echo Format::date($config['datetime_format'],$gmtime,$config['timezone_offset'],$config['enable_daylight_saving']); ?></i>
-            </td>
-        </tr>
-        <tr><th>Day, Date &amp; Time Format:</th>
-            <td><input type="text" name="daydatetime_format" value="<?php echo $config['daydatetime_format']; ?>">
-                        &nbsp;<font class="error">*&nbsp;<?php echo $errors['daydatetime_format']; ?></font>
-                        <i><?php echo Format::date($config['daydatetime_format'],$gmtime,$config['timezone_offset'],$config['enable_daylight_saving']); ?></i>
-            </td>
-        </tr>
-        <tr><th>Default Timezone:</th>
-            <td>
-                <select name="timezone_offset">
-                    <?php
-                    $gmoffset = date("Z") / 3600; //Server's offset.
-                    echo"<option value=\"$gmoffset\">Server Time (GMT $gmoffset:00)</option>"; //Default if all fails.
-                    $timezones= db_query('SELECT offset,timezone FROM '.TIMEZONE_TABLE);
-                    while (list($offset,$tz) = db_fetch_row($timezones)){
-                        $selected = ($config['timezone_offset'] ==$offset) ?'SELECTED':'';
-                        $tag=($offset)?"GMT $offset ($tz)":" GMT ($tz)";
-                        ?>
-                        <option value="<?php echo $offset; ?>"<?php echo $selected; ?>><?php echo $tag; ?></option>
-                        <?php
-                    } ?>
-                </select>
-            </td>
-        </tr>
-        <tr>
-            <th>Daylight Saving:</th>
-            <td>
-                <input type="checkbox" name="enable_daylight_saving" <?php echo $config['enable_daylight_saving'] ? 'checked': ''; ?>>Observe daylight savings
-            </td>
-        </tr>
-    </table>
-   
-    <table width="100%" border="0" cellspacing=0 cellpadding=2 class="tform">
-        <tr class="header"><td colspan=2>Ticket Options &amp; Settings</td></tr>
-        <tr class="subheader"><td colspan=2>If enabled ticket lock get auto-renewed on form activity.</td></tr>
-        <tr><th valign="top">Ticket IDs:</th>
-            <td>
-                <input type="radio" name="random_ticket_ids"  value="0"   <?php echo !$config['random_ticket_ids']?'checked':''; ?> /> Sequential
-                <input type="radio" name="random_ticket_ids"  value="1"   <?php echo $config['random_ticket_ids']?'checked':''; ?> />Random  (recommended)
-            </td>
-        </tr>
-        <tr><th valign="top">Ticket Priority:</th>
-            <td>
-                <select name="default_priority_id">
-                    <?php
-                    $priorities= db_query('SELECT priority_id,priority_desc FROM '.TICKET_PRIORITY_TABLE);
-                    while (list($id,$tag) = db_fetch_row($priorities)){ ?>
-                        <option value="<?php echo $id; ?>"<?php echo ($config['default_priority_id']==$id)?'selected':''; ?>><?php echo $tag; ?></option>
-                    <?php
-                    } ?>
-                </select> &nbsp;Default priority<br/>
-                <input type="checkbox" name="allow_priority_change" <?php echo $config['allow_priority_change'] ?'checked':''; ?>>
-                    Allow user to overwrite/set priority (new web tickets)<br/>
-                <input type="checkbox" name="use_email_priority" <?php echo $config['use_email_priority'] ?'checked':''; ?> >
-                    Use email priority when available (new emailed tickets)
-
-            </td>
-        </tr>
-        <tr><th>Maximum <b>Open</b> Tickets:</th>
-            <td>
-              <input type="text" name="max_open_tickets" size=4 value="<?php echo $config['max_open_tickets']; ?>"> 
-                per email. (<i>Helps with spam and flood control. Enter 0 for unlimited</i>)
-            </td>
-        </tr>
-        <tr><th>Auto-Lock Time:</td>
-            <td>
-              <input type="text" name="autolock_minutes" size=4 value="<?php echo $config['autolock_minutes']; ?>">
-                 <font class="error"><?php echo $errors['autolock_minutes']; ?></font>
-                (<i>Minutes to lock a ticket on activity. Enter 0 to disable locking</i>)
-            </td>
-        </tr>
-        <tr><th>Ticket Grace Period:</th>
-            <td>
-              <input type="text" name="overdue_grace_period" size=4 value="<?php echo $config['overdue_grace_period']; ?>">
-                (<i>Hours before ticket is marked overdue. Enter 0 to disable aging.</i>)
-            </td>
-        </tr>
-        <tr><th>Reopened Tickets:</th>
-            <td>
-              <input type="checkbox" name="auto_assign_reopened_tickets" <?php echo $config['auto_assign_reopened_tickets'] ? 'checked': ''; ?>> 
-                Auto-assign reopened tickets to last respondent 'available'. (<i> 3 months limit</i>)
-            </td>
-        </tr>
-        <tr><th>Assigned Tickets:</th>
-            <td>
-              <input type="checkbox" name="show_assigned_tickets" <?php echo $config['show_assigned_tickets']?'checked':''; ?>>
-                Show assigned tickets on open queue.
-            </td>
-        </tr>
-        <tr><th>Answered Tickets:</th>
-            <td>
-              <input type="checkbox" name="show_answered_tickets" <?php echo $config['show_answered_tickets']?'checked':''; ?>>
-                Show answered tickets on open queue.
-            </td>
-        </tr>
-        <tr><th>Ticket Activity Log:</th>
-            <td>
-              <input type="checkbox" name="log_ticket_activity" <?php echo $config['log_ticket_activity']?'checked':''; ?>>
-                Log ticket's activity as internal notes.
-            </td>
-        </tr>
-        <tr><th>Staff Identity:</th>
-            <td>
-              <input type="checkbox" name="hide_staff_name" <?php echo $config['hide_staff_name']?'checked':''; ?>>
-                Hide staff's name on responses.
-            </td>
-        </tr>
-        <tr><th>Human Verification:</th>
-            <td>
-                <?php
-                   if($config['enable_captcha'] && !$errors['enable_captcha']) { ?>
-                        <img src="../captcha.php" border="0" align="left">&nbsp;
-                <?php } ?>
-              <input type="checkbox" name="enable_captcha" <?php echo $config['enable_captcha']?'checked':''; ?>>
-                Enable captcha on new web tickets.&nbsp;<font class="error">&nbsp;<?php echo $errors['enable_captcha']; ?></font><br/>
-            </td>
-        </tr>
-
-    </table>
-    <table width="100%" border="0" cellspacing=0 cellpadding=2 class="tform">
-        <tr class="header"><td colspan=2 >Email Settings</td></tr>
-        <tr class="subheader"><td colspan=2>Note that global settings can be disabled at dept/email level.</td></tr>
-        <tr><th valign="top"><br><b>Incoming Emails</b>:</th>
-            <td><i>For mail fetcher (POP/IMAP) to work you must set a cron job or simply enable auto-cron</i><br/>
-                <input type="checkbox" name="enable_mail_fetch" value=1 <?php echo $config['enable_mail_fetch']? 'checked': ''; ?>  > Enable POP/IMAP email fetch
-                    &nbsp;&nbsp;(<i>Global setting which can be disabled at email level</i>) <br/>
-                <input type="checkbox" name="enable_email_piping" value=1 <?php echo $config['enable_email_piping']? 'checked': ''; ?>  > Enable email piping
-                   &nbsp;(<i>You pipe we accept policy</i>)<br/>
-                <input type="checkbox" name="strip_quoted_reply" <?php echo $config['strip_quoted_reply'] ? 'checked':''; ?>>
-                    Strip quoted reply (<i>depends on the tag below</i>)<br/>
-                <input type="text" name="reply_separator" value="<?php echo $config['reply_separator']; ?>"> Reply Separator Tag
-                &nbsp;<font class="error">&nbsp;<?php echo $errors['reply_separator']; ?></font>
-            </td>
-        </tr>
-        <tr><th valign="top"><br><b>Outgoing Emails</b>:</th>
-            <td>
-                <i><b>Default Email:</b> Only applies to outgoing emails with no SMTP settings.</i><br/>
-                <select name="default_smtp_id"
-                    onChange="document.getElementById('overwrite').style.display=(this.options[this.selectedIndex].value>0)?'block':'none';">
-                    <option value=0>Select One</option>
-                    <option value=0 selected="selected">None: Use PHP mail function</option>
-                    <?php
-                    $emails=db_query('SELECT email_id,email,name,smtp_host FROM '.EMAIL_TABLE.' WHERE smtp_active=1');
-                    if($emails && db_num_rows($emails)) {
-                        while (list($id,$email,$name,$host) = db_fetch_row($emails)){
-                            $email=$name?"$name &lt;$email&gt;":$email;
-                            $email=sprintf('%s (%s)',$email,$host);
-                            ?>
-                            <option value="<?php echo $id; ?>"<?php echo ($config['default_smtp_id']==$id)?'selected="selected"':''; ?>><?php echo $email; ?></option>
-                        <?php
-                        }
-                    } ?>
-                 </select>&nbsp;&nbsp;<font class="error">&nbsp;<?php echo $errors['default_smtp_id']; ?></font><br/>
-                 <span id="overwrite" style="display:<?php echo ($config['default_smtp_id']?'display':'none'); ?>">
-                    <input type="checkbox" name="spoof_default_smtp" <?php echo $config['spoof_default_smtp'] ? 'checked':''; ?>>
-                        Allow spoofing (No Overwrite).&nbsp;<font class="error">&nbsp;<?php echo $errors['spoof_default_smtp']; ?></font><br/>
-                        </span>
-             </td>
-        </tr>
-        <tr><th>Default System Email:</th>
-            <td>
-                <select name="default_email_id">
-                    <option value=0 disabled>Select One</option>
-                    <?php
-                    $emails=db_query('SELECT email_id,email,name FROM '.EMAIL_TABLE);
-                    while (list($id,$email,$name) = db_fetch_row($emails)){ 
-                        $email=$name?"$name &lt;$email&gt;":$email;
-                        ?>
-                     <option value="<?php echo $id; ?>"<?php echo ($config['default_email_id']==$id)?'selected':''; ?>><?php echo $email; ?></option>
-                    <?php
-                    } ?>
-                 </select>
-                 &nbsp;<font class="error">*&nbsp;<?php echo $errors['default_email_id']; ?></font></td>
-        </tr>
-        <tr><th valign="top">Default Alert Email:</th>
-            <td>
-                <select name="alert_email_id">
-                    <option value=0 disabled>Select One</option>
-                    <option value=0 selected="selected">Use Default System Email (above)</option>
-                    <?php
-                    $emails=db_query('SELECT email_id,email,name FROM '.EMAIL_TABLE.' WHERE email_id != '.db_input($config['default_email_id']));
-                    while (list($id,$email,$name) = db_fetch_row($emails)){
-                        $email=$name?"$name &lt;$email&gt;":$email;
-                        ?>
-                     <option value="<?php echo $id; ?>"<?php echo ($config['alert_email_id']==$id)?'selected':''; ?>><?php echo $email; ?></option>
-                    <?php
-                    } ?>
-                 </select>
-                 &nbsp;<font class="error">*&nbsp;<?php echo $errors['alert_email_id']; ?></font>
-                <br/><i>Used to send out alerts and notices to staff.</i>
-            </td>
-        </tr>
-        <tr><th>System Admin Email Address:</th>
-            <td>
-                <input type="text" size=25 name="admin_email" value="<?php echo $config['admin_email']; ?>">
-                    &nbsp;<font class="error">*&nbsp;<?php echo $errors['admin_email']; ?></font></td>
-        </tr>
-    </table>
-
-    <table width="100%" border="0" cellspacing=0 cellpadding=2 class="tform">
-        <tr class="header"><td colspan=2>Autoresponders &nbsp;(Global Setting)</td></tr>
-        <tr class="subheader"><td colspan=2">This is global setting which can be disabled at department level.</td></tr>
-        <tr><th valign="top">New Ticket:</th>
-            <td><i>Autoresponse includes the ticket ID required to check status of the ticket</i><br>
-                <input type="radio" name="ticket_autoresponder"  value="1"   <?php echo $config['ticket_autoresponder']?'checked':''; ?> />Enable
-                <input type="radio" name="ticket_autoresponder"  value="0"   <?php echo !$config['ticket_autoresponder']?'checked':''; ?> />Disable
-            </td>
-        </tr>
-        <tr><th valign="top">New Ticket by Staff:</th>
-            <td><i>Notice sent when staff creates a ticket on behalf of the user (Staff can disable)</i><br>
-                <input type="radio" name="ticket_notice_active"  value="1"   <?php echo $config['ticket_notice_active']?'checked':''; ?> />Enable
-                <input type="radio" name="ticket_notice_active"  value="0"   <?php echo !$config['ticket_notice_active']?'checked':''; ?> />Disable
-            </td>
-        </tr>
-        <tr><th valign="top">New Message:</th>
-            <td><i>Message appended to an existing ticket confirmation</i><br>
-                <input type="radio" name="message_autoresponder"  value="1"   <?php echo $config['message_autoresponder']?'checked':''; ?> />Enable
-                <input type="radio" name="message_autoresponder"  value="0"   <?php echo !$config['message_autoresponder']?'checked':''; ?> />Disable
-            </td>
-        </tr>
-        <tr><th valign="top">Overlimit notice:</th>
-            <td><i>Ticket denied notice sent <b>only once</b> on limit violation to the user.</i><br/>               
-                <input type="radio" name="overlimit_notice_active"  value="1"   <?php echo $config['overlimit_notice_active']?'checked':''; ?> />Enable
-                <input type="radio" name="overlimit_notice_active"  value="0"   <?php echo !$config['overlimit_notice_active']?'checked':''; ?> />Disable
-                <br><i><b>Note:</b> Admin gets alerts on ALL denials by default.</i><br>
-            </td>
-        </tr>
-    </table>
-    <table width="100%" border="0" cellspacing=0 cellpadding=2 class="tform">
-        <tr class="header"><td colspan=2>&nbsp;Alerts &amp; Notices</td></tr>
-        <tr class="subheader"><td colspan=2>
-            Notices sent to user use 'No Reply Email' whereas alerts to staff use 'Alert Email' set above as FROM address respectively.</td>
-        </tr>
-        <tr><th valign="top">New Ticket Alert:</th>
-            <td>
-                <input type="radio" name="ticket_alert_active"  value="1"   <?php echo $config['ticket_alert_active']?'checked':''; ?> />Enable
-                <input type="radio" name="ticket_alert_active"  value="0"   <?php echo !$config['ticket_alert_active']?'checked':''; ?> />Disable
-                <br><i>Select recipients</i>&nbsp;<font class="error">&nbsp;<?php echo $errors['ticket_alert_active']; ?></font><br>
-                <input type="checkbox" name="ticket_alert_admin" <?php echo $config['ticket_alert_admin']?'checked':''; ?>> Admin Email
-                <input type="checkbox" name="ticket_alert_dept_manager" <?php echo $config['ticket_alert_dept_manager']?'checked':''; ?>> Department Manager
-                <input type="checkbox" name="ticket_alert_dept_members" <?php echo $config['ticket_alert_dept_members']?'checked':''; ?>> Department Members (spammy)
-            </td>
-        </tr>
-        <tr><th valign="top">New Message Alert:</th>
-            <td>
-              <input type="radio" name="message_alert_active"  value="1"   <?php echo $config['message_alert_active']?'checked':''; ?> />Enable
-              <input type="radio" name="message_alert_active"  value="0"   <?php echo !$config['message_alert_active']?'checked':''; ?> />Disable
-              <br><i>Select recipients</i>&nbsp;<font class="error">&nbsp;<?php echo $errors['message_alert_active']; ?></font><br>
-              <input type="checkbox" name="message_alert_laststaff" <?php echo $config['message_alert_laststaff']?'checked':''; ?>> Last Respondent
-              <input type="checkbox" name="message_alert_assigned" <?php echo $config['message_alert_assigned']?'checked':''; ?>> Assigned Staff
-              <input type="checkbox" name="message_alert_dept_manager" <?php echo $config['message_alert_dept_manager']?'checked':''; ?>> Department Manager (spammy)
-            </td>
-        </tr>
-        <tr><th valign="top">New Internal Note Alert:</th>
-            <td>
-              <input type="radio" name="note_alert_active"  value="1"   <?php echo $config['note_alert_active']?'checked':''; ?> />Enable
-              <input type="radio" name="note_alert_active"  value="0"   <?php echo !$config['note_alert_active']?'checked':''; ?> />Disable
-              <br><i>Select recipients</i>&nbsp;<font class="error">&nbsp;<?php echo $errors['note_alert_active']; ?></font><br>
-              <input type="checkbox" name="note_alert_laststaff" <?php echo $config['note_alert_laststaff']?'checked':''; ?>> Last Respondent
-              <input type="checkbox" name="note_alert_assigned" <?php echo $config['note_alert_assigned']?'checked':''; ?>> Assigned Staff
-              <input type="checkbox" name="note_alert_dept_manager" <?php echo $config['note_alert_dept_manager']?'checked':''; ?>> Department Manager (spammy)
-            </td>
-        </tr>
-        <tr><th valign="top">Overdue Ticket Alert:</th>
-            <td>
-              <input type="radio" name="overdue_alert_active"  value="1"   <?php echo $config['overdue_alert_active']?'checked':''; ?> />Enable
-              <input type="radio" name="overdue_alert_active"  value="0"   <?php echo !$config['overdue_alert_active']?'checked':''; ?> />Disable
-              <br><i>Admin Email gets an alert by default. Select additional recipients below</i>&nbsp;<font class="error">&nbsp;<?php echo $errors['overdue_alert_active']; ?></font><br>
-              <input type="checkbox" name="overdue_alert_assigned" <?php echo $config['overdue_alert_assigned']?'checked':''; ?>> Assigned Staff
-              <input type="checkbox" name="overdue_alert_dept_manager" <?php echo $config['overdue_alert_dept_manager']?'checked':''; ?>> Department Manager
-              <input type="checkbox" name="overdue_alert_dept_members" <?php echo $config['overdue_alert_dept_members']?'checked':''; ?>> Department Members (spammy)
-            </td>
-        </tr>
-        <tr><th valign="top">System Errors:</th>
-            <td><i>Enabled errors are sent to admin email set above</i><br>
-              <input type="checkbox" name="send_sys_errors" <?php echo $config['send_sys_errors']?'checked':'checked'; ?> disabled>System Errors
-              <input type="checkbox" name="send_sql_errors" <?php echo $config['send_sql_errors']?'checked':''; ?>>SQL errors
-              <input type="checkbox" name="send_login_errors" <?php echo $config['send_login_errors']?'checked':''; ?>>Excessive Login attempts
-            </td>
-        </tr> 
-        
-    </table>
- </td></tr>
- <tr>
-    <td style="padding:10px 0 10px 240px;">
-        <input class="button" type="submit" name="submit" value="Save Changes">
-        <input class="button" type="reset" name="reset" value="Reset Changes">
-    </td>
- </tr>
- </form>
-</table>
diff --git a/include/staff/profile.inc.php b/include/staff/profile.inc.php
index 39eaf80a5..073a7c8a4 100644
--- a/include/staff/profile.inc.php
+++ b/include/staff/profile.inc.php
@@ -6,6 +6,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
 $info['id']=$staff->getId();
 ?>
 <form action="profile.php" method="post" id="save" autocomplete="off">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="update">
  <input type="hidden" name="id" value="<?php echo $info['id']; ?>">
  <h2>My Account Profile</h2>
diff --git a/include/staff/settings-alerts.inc.php b/include/staff/settings-alerts.inc.php
index a71b9e8a8..5bb5d3932 100644
--- a/include/staff/settings-alerts.inc.php
+++ b/include/staff/settings-alerts.inc.php
@@ -1,4 +1,5 @@
 <form action="settings.php?t=alerts" method="post" id="save">
+<?php csrf_token(); ?>
 <input type="hidden" name="t" value="alerts" >
 <table class="form_table settings_table" width="940" border="0" cellspacing="0" cellpadding="2">
     <thead>
diff --git a/include/staff/settings-attachments.inc.php b/include/staff/settings-attachments.inc.php
index 572c5da5a..b381fa40d 100644
--- a/include/staff/settings-attachments.inc.php
+++ b/include/staff/settings-attachments.inc.php
@@ -4,6 +4,7 @@ if(!($maxfileuploads=ini_get('max_file_uploads')))
 
 ?>
 <form action="settings.php?t=attachments" method="post" id="save">
+<?php csrf_token(); ?>
 <input type="hidden" name="t" value="attachments" >
 <table class="form_table settings_table" width="940" border="0" cellspacing="0" cellpadding="2">
     <thead>
diff --git a/include/staff/settings-autoresponders.inc.php b/include/staff/settings-autoresponders.inc.php
index 70bddc826..106e7f3f4 100644
--- a/include/staff/settings-autoresponders.inc.php
+++ b/include/staff/settings-autoresponders.inc.php
@@ -1,4 +1,5 @@
 <form action="settings.php?t=autoresponders" method="post" id="save">
+<?php csrf_token(); ?>
 <input type="hidden" name="t" value="autoresponders" >
 <table class="form_table settings_table" width="940" border="0" cellspacing="0" cellpadding="2">
     <thead>
diff --git a/include/staff/settings-dates.inc.php b/include/staff/settings-dates.inc.php
index 0434e94c7..f8085cfc3 100644
--- a/include/staff/settings-dates.inc.php
+++ b/include/staff/settings-dates.inc.php
@@ -2,6 +2,7 @@
 $gmtime=Misc::gmtime();
 ?>
 <form action="settings.php?t=dates" method="post" id="save">
+<?php csrf_token(); ?>
 <input type="hidden" name="t" value="dates" >
 <table class="form_table settings_table" width="940" border="0" cellspacing="0" cellpadding="2">
     <thead>
diff --git a/include/staff/settings-emails.inc.php b/include/staff/settings-emails.inc.php
index 017eb29ec..e4ccaf3a4 100644
--- a/include/staff/settings-emails.inc.php
+++ b/include/staff/settings-emails.inc.php
@@ -1,4 +1,5 @@
 <form action="settings.php?t=emails" method="post" id="save">
+<?php csrf_token(); ?>
 <input type="hidden" name="t" value="emails" >
 <table class="form_table settings_table" width="940" border="0" cellspacing="0" cellpadding="2">
     <thead>
diff --git a/include/staff/settings-general.inc.php b/include/staff/settings-general.inc.php
index 2e1e347be..20bbd9486 100644
--- a/include/staff/settings-general.inc.php
+++ b/include/staff/settings-general.inc.php
@@ -1,4 +1,5 @@
 <form action="settings.php?t=general" method="post" id="save">
+<?php csrf_token(); ?>
 <input type="hidden" name="t" value="general" >
 <table class="form_table settings_table" width="940" border="0" cellspacing="0" cellpadding="2">
     <thead>
diff --git a/include/staff/settings-kb.inc.php b/include/staff/settings-kb.inc.php
index 2d368b3ba..6fe8433f5 100644
--- a/include/staff/settings-kb.inc.php
+++ b/include/staff/settings-kb.inc.php
@@ -1,6 +1,5 @@
-<?php
-?>
 <form action="settings.php?t=kb" method="post" id="save">
+<?php csrf_token(); ?>
 <input type="hidden" name="t" value="kb" >
 <table class="form_table settings_table" width="940" border="0" cellspacing="0" cellpadding="2">
     <thead>
diff --git a/include/staff/settings-tickets.inc.php b/include/staff/settings-tickets.inc.php
index 5ada80f48..280abca08 100644
--- a/include/staff/settings-tickets.inc.php
+++ b/include/staff/settings-tickets.inc.php
@@ -1,4 +1,5 @@
 <form action="settings.php?t=tickets" method="post" id="save">
+<?php csrf_token(); ?>
 <input type="hidden" name="t" value="tickets" >
 <table class="form_table settings_table" width="940" border="0" cellspacing="0" cellpadding="2">
     <thead>
diff --git a/include/staff/settings.php b/include/staff/settings.php
deleted file mode 100644
index 1dac69a5c..000000000
--- a/include/staff/settings.php
+++ /dev/null
@@ -1,721 +0,0 @@
-<?php include "./include/header.php" ?>
-<h2>System Preferences and Settings  (v1.6 ST)</h2>
-
-<form action="settings.php" method="post">
-<br>
-<a href="#" class="expand_all">Expand All</a> |
-<a href="#" class="collapse_all">Collapse All</a>
-<table class="form_table settings_table" width="940" border="0" cellspacing="0" cellpadding="2">
-    <thead>
-        <tr>
-            <th colspan="2">
-                <h4><a href="#"><span>&ndash;</span>&nbsp;General Settings</a></h4>
-                <em>Offline mode will disable client interface and only allow super admins to login to Staff Control Panel</em>
-            </th>
-        </tr>
-    </thead>
-    <tbody>
-        <tr>
-            <td width="220" class="required">
-                Helpdesk Status:
-            </td>
-            <td>
-                <input type="radio" name="isonline" value="1" checked="checked"><strong>Online</strong> (Active)
-                <input type="radio" name="isonline" value="0"><strong>Offline</strong> (Disabled)
-                &nbsp;<span class="warn">&nbsp;</span>
-            </td>
-        </tr>
-        <tr>
-            <td width="220" class="required">
-                Helpdesk URL:
-            </td>
-            <td>
-                <input type="text" size="40" name="helpdesk_url" value="http://helpdesk.enhancesoft.com/">
-                &nbsp;<span class="error">&nbsp;</span>
-            </td>
-        </tr>
-        <tr>
-            <td width="220">
-                Helpdesk Name/Title:
-            </td>
-            <td>
-                <input type="text" size="40" name="helpdesk_title" value="Enhancesoft :: Support Ticket System">
-            </td>
-        </tr>
-        <tr>
-            <td width="220" class="required">
-                Default E-Mail Templates:
-            </td>
-            <td>
-                <select name="default_template_id">
-                    <option value="0">Select Default Template</option>
-                    <option value="1">osTicket Default Template</option>
-                    <option value="3" selected="selected">No Links</option>
-                </select>
-                &nbsp;<span class="error">&nbsp;</span>
-            </td>
-        </tr>
-        <tr>
-            <td width="220" class="required">
-                Default Department:
-            </td>
-            <td>
-                <select name="default_dept_id">
-                    <option value="0">Select Default Dept</option>
-                    <option value="1" selected="selected">Support Dept</option>
-                    <option value="2">Billing Dept</option>
-                    <option value="4">Test Dept</option>
-                </select>
-                &nbsp;<span class="error">&nbsp;</span>
-            </td>
-        </tr>
-        <tr>
-            <td width="220">
-                Default Page Size:
-            </td>
-            <td>
-                <select name="max_page_size">
-                    <option value="5">5</option>
-                    <option value="10">10</option>
-                    <option value="15">15</option>
-                    <option value="20">20</option>
-                    <option value="25" selected="selected">25</option>
-                    <option value="30">30</option>
-                    <option value="35">35</option>
-                    <option value="40">40</option>
-                    <option value="45">45</option>
-                    <option value="50">50</option>
-                </select>
-            </td>
-        </tr>
-        <tr>
-            <td width="220">
-                Default Log Level:
-            </td>
-            <td>
-                <select name="log_level">
-                    <option value="0">None (Disable Logger)</option>
-                    <option value="3">DEBUG</option>
-                    <option value="2" selected="selected">WARN</option>
-                    <option value="1">ERROR</option>
-                </select>
-            </td>
-        </tr>
-        <tr>
-            <td width="220">
-                Purge Logs:
-            </td>
-            <td>
-                <select name="log_graceperiod">
-                    <option value="0" selected>Never Purge Logs</option>
-                    <option value="1">After 1 Month</option>
-                    <option value="2">After 2 Months</option>
-                    <option value="3">After 3 Months</option>
-                    <option value="4">After 4 Months</option>
-                    <option value="5">After 5 Months</option>
-                    <option value="6">After 6 Months</option>
-                    <option value="7">After 7 Months</option>
-                    <option value="8">After 8 Months</option>
-                    <option value="9">After 9 Months</option>
-                    <option value="10">After 10 Months</option>
-                    <option value="11">After 11 Months</option>
-                    <option value="12">After 12 Months</option>
-                </select>
-            </td>
-        </tr>
-        <tr>
-            <td width="220">
-                Excessive Staff Logins:
-            </td>
-            <td>
-                <select name="staff_max_logins">
-                    <option value="1">1</option>
-                    <option value="2">2</option>
-                    <option value="3">3</option>
-                    <option value="4" selected="selected">4</option>
-                    <option value="5">5</option>
-                    <option value="6">6</option>
-                    <option value="7">7</option>
-                    <option value="8">8</option>
-                    <option value="9">9</option>
-                    <option value="10">10</option>
-                </select> failed login attempt(s) allowed before a
-                <select name="staff_login_timeout">
-                    <option value="1">1</option>
-                    <option value="2" selected="selected">2</option>
-                    <option value="3">3</option>
-                    <option value="4">4</option>
-                    <option value="5">5</option>
-                    <option value="6">6</option>
-                    <option value="7">7</option>
-                    <option value="8">8</option>
-                    <option value="9">9</option>
-                    <option value="10">10</option>
-                </select> minute lock-out is enforced.
-            </td>
-        </tr>
-        <tr>
-            <td width="220">
-                Staff Session Timeout:
-            </td>
-            <td>
-                <input type="text" name="staff_session_timeout" size="4" value="0">
-                &nbsp;Maximum idle time in minutes before a staff member must log in again (enter 0 to disable).
-            </td>
-        </tr>
-        <tr>
-            <td width="220">
-                Staff Session IP Binding:
-            </td>
-            <td>
-                <input type="checkbox" name="staff_ip_binding" checked="checked" value="1">
-                <em>(binds staff session to originating IP address upon login)</em>
-            </td>
-        </tr>
-        <tr>
-            <td width="220">
-                Excessive Client Logins:
-            </td>
-            <td>
-                <select name="client_max_logins">
-                    <option value="1">1</option>
-                    <option value="2">2</option>
-                    <option value="3">3</option>
-                    <option value="4" selected="selected">4</option>
-                    <option value="5">5</option>
-                    <option value="6">6</option>
-                    <option value="7">7</option>
-                    <option value="8">8</option>
-                    <option value="9">9</option>
-                    <option value="10">10</option>
-                </select> failed login attempt(s) allowed before a
-                <select name="client_login_timeout">
-                    <option value="1">1</option>
-                    <option value="2" selected="selected">2</option>
-                    <option value="3">3</option>
-                    <option value="4">4</option>
-                    <option value="5">5</option>
-                    <option value="6">6</option>
-                    <option value="7">7</option>
-                    <option value="8">8</option>
-                    <option value="9">9</option>
-                    <option value="10">10</option>
-                </select> minute lock-out is enforced.
-            </td>
-        </tr>
-        <tr>
-            <td width="220">
-                Client Session Timeout:
-            </td>
-            <td>
-                <input type="text" name="client_session_timeout" size="4" value="0">
-                &nbsp;Maximum idle time in minutes before a client must log in again (enter 0 to disable).
-            </td>
-        </tr>
-        <tr>
-            <td width="220">
-                Clickable URLs:
-            </td>
-            <td>
-                <input type="checkbox" name="clickable_urls" checked="checked" value="1">
-                <em>(converts URLs in messages to clickable links)</em>
-            </td>
-        </tr>
-        <tr>
-            <td width="220">
-                Enable Auto-cron:
-            </td>
-            <td>
-                <input type="checkbox" name="enable_auto_cron" value="1">
-                <em>(executes cron jobs based on staff activity - not recommended)</em>
-            </td>
-        </tr>
-    </tbody>
-</table>
-
-<table class="form_table settings_table" width="940" border="0" cellspacing="0" cellpadding="2">
-    <thead>
-        <tr>
-            <th colspan="2">
-                <h4><a href="#"><span>&ndash;</span>&nbsp;Date and Time Settings</a></h4>
-                <em>Please refer to <a href="http://php.net/date" target="_blank">PHP Manual</a> for supported parameters.</em>
-            </th>
-        </tr>
-    </thead>
-    <tbody>
-        <tr>
-            <td width="220" class="required">
-                Time Format:
-            </td>
-            <td>
-                <input type="text" name="time_format" value="h:i A">
-                &nbsp;<span class="error">&nbsp;</span>
-                <em> 09:24 AM</em>
-            </td>
-        </tr>
-        <tr>
-            <td width="220" class="required">
-                Date Format:
-            </td>
-            <td>
-                <input type="text" name="date_format" value="m/d/Y">
-                &nbsp;<span class="error">&nbsp;</span>
-                <em>05/06/2011</em>
-            </td>
-        </tr>
-        <tr>
-            <td width="220" class="required">
-                Date &amp; Time Format:
-            </td>
-            <td>
-                <input type="text" name="datetime_format" value="m/d/Y g:i a">
-                &nbsp;<span class="error">&nbsp;</span>
-                <em>05/06/2011 9:24 am</em>
-            </td>
-        </tr>
-        <tr>
-            <td width="220" class="required">
-                Day, Date &amp; Time Format:
-            </td>
-            <td>
-                <input type="text" name="daydatetime_format" value="D, M j Y g:ia">
-                &nbsp;<span class="error">*&nbsp;</span>
-                <em>Fri, May 6 2011 9:24am</em>
-            </td>
-        </tr>
-        <tr>
-            <td width="220">
-                Default Timezone:
-            </td>
-            <td>
-                <select name="timezone_offset">
-                    <option value="0">Server Time (GMT 0:00)</option>                        <option value="-12.0">GMT -12.0 (Eniwetok, Kwajalein)</option>
-                    <option value="-11.0">GMT -11.0 (Midway Island, Samoa)</option>
-                    <option value="-10.0">GMT -10.0 (Hawaii)</option>
-                    <option value="-9.0">GMT -9.0 (Alaska)</option>
-                    <option value="-8.0">GMT -8.0 (Pacific Time (US & Canada))</option>
-                    <option value="-7.0">GMT -7.0 (Mountain Time (US & Canada))</option>
-                    <option value="-6.0">GMT -6.0 (Central Time (US & Canada), Mexico City)</option>
-                    <option value="-5.0" selected="selected">GMT -5.0 (Eastern Time (US & Canada), Bogota, Lima)</option>
-                    <option value="-4.0">GMT -4.0 (Atlantic Time (Canada), Caracas, La Paz)</option>
-                    <option value="-3.5">GMT -3.5 (Newfoundland)</option>
-                    <option value="-3.0">GMT -3.0 (Brazil, Buenos Aires, Georgetown)</option>
-                    <option value="-2.0">GMT -2.0 (Mid-Atlantic)</option>
-                    <option value="-1.0">GMT -1.0 (Azores, Cape Verde Islands)</option>
-                    <option value="0.0">GMT 0.0 (Western Europe Time, London, Lisbon, Casablanca)</option>
-                    <option value="1.0">GMT 1.0 (Brussels, Copenhagen, Madrid, Paris)</option>
-                    <option value="2.0">GMT 2.0 (Kaliningrad, South Africa)</option>
-                    <option value="3.0">GMT 3.0 (Baghdad, Riyadh, Moscow, St. Petersburg)</option>
-                    <option value="3.5">GMT 3.5 (Tehran)</option>
-                    <option value="4.0">GMT 4.0 (Abu Dhabi, Muscat, Baku, Tbilisi)</option>
-                    <option value="4.5">GMT 4.5 (Kabul)</option>
-                    <option value="5.0">GMT 5.0 (Ekaterinburg, Islamabad, Karachi, Tashkent)</option>
-                    <option value="5.5">GMT 5.5 (Bombay, Calcutta, Madras, New Delhi)</option>
-                    <option value="6.0">GMT 6.0 (Almaty, Dhaka, Colombo)</option>
-                    <option value="7.0">GMT 7.0 (Bangkok, Hanoi, Jakarta)</option>
-                    <option value="8.0">GMT 8.0 (Beijing, Perth, Singapore, Hong Kong)</option>
-                    <option value="9.0">GMT 9.0 (Tokyo, Seoul, Osaka, Sapporo, Yakutsk)</option>
-                    <option value="9.5">GMT 9.5 (Adelaide, Darwin)</option>
-                    <option value="10.0">GMT 10.0 (Eastern Australia, Guam, Vladivostok)</option>
-                    <option value="11.0">GMT 11.0 (Magadan, Solomon Islands, New Caledonia)</option>
-                    <option value="12.0">GMT 12.0 (Auckland, Wellington, Fiji, Kamchatka)</option>
-                </select>
-            </td>
-        </tr>
-        <tr>
-            <td width="220">
-                Daylight Savings
-            </td>
-            <td>
-                <input type="checkbox" name="daylight_savings" value="1">
-                <em>observe daylight savings time</em>
-            </td>
-        </tr>
-    </tbody>
-</table>
-<table class="form_table settings_table" width="940" border="0" cellspacing="0" cellpadding="2">
-    <thead>
-        <tr>
-            <th colspan="2">
-                <h4><a href="#"><span>&ndash;</span>&nbsp;Ticket Options and Settings</a></h4>
-                <em>If enabled ticket lock get auto-renewed on form activity.</em>
-            </th>
-        </tr>
-    </thead>
-    <tbody>
-        <tr>
-            <td width="220">
-                Ticket IDs:
-            </td>
-            <td>
-                <input type="radio" name="random_ticket_ids" value="0"> Sequential
-                <input type="radio" name="random_ticket_ids" value="1" checked="checked">Random  (recommended)
-            </td>
-        </tr>
-        <tr>
-            <td width="220" class="multi-line">
-                Ticket Priority:
-            </td>
-            <td>
-                <select name="default_priority_id">
-                    <option value="1">Low</option>
-                    <option value="2" selected="selected">Normal</option>
-                    <option value="3">High</option>
-                    <option value="4">Emergency</option>
-                </select> &nbsp;Default Priority<br>
-                <input type="checkbox" name="allow_priority_change" >
-                Allow user to overwrite/set priority (new web tickets)<br>
-
-                <input type="checkbox" name="use_email_priority"  >
-                Use email priority when available (new emailed tickets)
-            </td>
-        </tr>
-        <tr>
-            <td width="220">
-                Maximum <strong>Open</strong> Tickets:
-            </td>
-            <td>
-                <input type="text" name="max_open_tickets" size="4" value="0">
-                per email <em>(helps with spam and flood control - enter 0 for unlimited)</em>
-            </td>
-        </tr>
-        <tr>
-            <td width="220">
-                Ticket Auto-lock Time:
-            </td>
-            <td>
-                <input type="text" name="autolock_minutes" size="4" value="3">
-                <em>(minutes to lock a ticket on activity - enter 0 to disable locking)</em>
-            </td>
-        </tr>
-        <tr>
-            <td width="220">
-                Ticket Grace Period:
-            </td>
-            <td>
-                <input type="text" name="overdue_grace_period" size=4 value="0">
-                <em>(hours before ticket is marked overdue - enter 0 to disable aging)</em>
-            </td>
-        </tr>
-        <tr>
-            <td width="220">
-                Reopened Tickets:
-            </td>
-            <td>
-                <input type="checkbox" name="auto_assign_reopened_tickets" checked="checked">
-                Auto-assign reopened tickets to last available respondent. <em>(3 months limit)</em>
-            </td>
-        </tr>
-        <tr>
-            <td width="220">
-                Assigned Tickets:
-            </td>
-            <td>
-                <input type="checkbox" name="show_assigned_tickets">
-                Show assigned tickets on open queue.
-            </td>
-        </tr>
-        <tr>
-            <td width="220">
-                Answered Tickets:
-            </td>
-            <td>
-                <input type="checkbox" name="show_nswered_tickets">
-                Show answered tickets on open queue.
-            </td>
-        </tr>
-        <tr>
-            <td width="220">
-                Ticket Activity Log:
-            </td>
-            <td>
-                <input type="checkbox" name="log_ticket_activity">
-                Log ticket activity as an internal note.
-            </td>
-        </tr>
-        <tr>
-            <td width="220">
-                Staff Identity Masking:
-            </td>
-            <td>
-                <input type="checkbox" name="hide_staff_name">
-                Hide staff's name on responses.
-            </td>
-        </tr>
-        <tr>
-            <td width="220">
-                Human Verification:
-            </td>
-            <td>
-                <input type="checkbox" name="enable_captcha">
-                Enable CAPTCHA on new web tickets.
-                <em>(requires GDLib)</em>
-            </td>
-        </tr>
-    </tbody>
-</table>
-<table class="form_table settings_table" width="940" border="0" cellspacing="0" cellpadding="2">
-    <thead>
-        <tr>
-            <th colspan="2">
-                <h4><a href="#"><span>&ndash;</span>&nbsp;E-mail Settings</a></h4>
-                <em>Note that global settings can be disabled at dept/e-mail level.</em>
-            </th>
-        </tr>
-    </thead>
-    <tbody>
-        <tr>
-            <td width="220" class="required multi-line">
-                Incoming Email:
-                <br><em>For mail fetcher (POP/IMAP) to work you must set a cron job or enable auto-cron</em>
-            </td>
-            <td>
-                <input type="checkbox" name="enable_mail_fetch" value="1" checked="checked"> Enable POP/IMAP email fetch
-                &nbsp;<em>(Global setting which can be disabled at email level)</em><br>
-
-                <input type="checkbox" name="enable_email_piping" value="1" checked="checked"> Enable email piping
-                &nbsp;<em>(You pipe we accept policy)</em><br>
-
-                <input type="checkbox" name="strip_quoted_reply" checked="checked">
-                Strip quoted reply <em>(depends on the tag below)</em><br><br>
-
-                Reply Separator Tag:
-                <input type="text" name="reply_separator" value="-- do not edit --">
-                &nbsp;<span class="error">&nbsp;</span>
-            </td>
-        </tr>
-        <tr>
-            <td width="220" class="required multi-line">
-                Outgoing Email:
-                <br><em><strong>Default Email:</strong> Only applies to outgoing emails with no SMTP settings.</em><br/>
-
-            </td>
-            <td>
-                <select name="default_smtp_id" onChange="document.getElementById('overwrite').style.display=(this.options[this.selectedIndex].value>0)?'block':'none';">
-                    <option value="0">Select One</option>
-                    <option value="0">None: Use PHP mail function</option>
-                    <option value="1" selected="selected">osTicket Support &lt;support@osticket.com&gt; (smtp.gmail.com)</option>
-                </select>
-
-                <span id="overwrite" style="display:display">
-                <br><input type="checkbox" name="spoof_default_smtp" >
-                    Allow spoofing (No Overwrite).
-                </span>
-            </td>
-        </tr>
-        <tr>
-            <td width="220" class="required">
-                Default System E-Mail:
-            </td>
-            <td>
-                <select name="default_email_id">
-                    <option value="0">Select One</option>
-                    <option value="1" selected="selected">osTicket Support &lt;support@osticket.com&gt;</option>
-                    <option value="2">osTicket Alerts &lt;alerts@osticket.com&gt;</option>
-                    <option value="3">noreply@osticket.com</option>
-                    <option value="5">lvcta.com (Test) &lt;support@lvcta.com&gt;</option>
-                </select>
-            </td>
-        </tr>
-        <tr>
-            <td width="220" class="required">
-                Default Alert E-Mail:
-            </td>
-            <td>
-                <select name="alert_email_id">
-                    <option value="0">Select One</option>
-                    <option value="1">osTicket Support &lt;support@osticket.com&gt;</option>
-                    <option value="2" selected="selected">osTicket Alerts &lt;alerts@osticket.com&gt;</option>
-                    <option value="3">noreply@osticket.com</option>
-                    <option value="5">lvcta.com (Test) &lt;support@lvcta.com&gt;</option>
-                </select>
-            </td>
-        </tr>
-        <tr>
-            <td width="220" class="required">
-                System Admin E-mail Address:
-            </td>
-            <td>
-                <input type="text" size="25" name="admin_email" value="peter@osticket.com">
-                &nbsp;<span class="error">&nbsp;</span>
-            </td>
-        </tr>
-    </tbody>
-</table>
-<table class="form_table settings_table" width="940" border="0" cellspacing="0" cellpadding="2">
-    <thead>
-        <tr>
-            <th colspan="2">
-                <h4><a href="#"><span>&ndash;</span>&nbsp;Autoresponders (Global Setting)</a></h4>
-                <em>This is global setting which can be disabled at department level.</em>
-            </th>
-        </tr>
-    </thead>
-    <tbody>
-        <tr>
-            <td width="220" class="multi-line">
-                New Ticket:
-            </td>
-            <td>
-                <em>Autoresponse includes the ticket ID required to check status of the ticket</em><br>
-                <input type="radio" name="ticket_autoresponder"  value="1">Enable
-                <input type="radio" name="ticket_autoresponder"  value="0" checked="checked">Disable
-                <br><br>
-            </td>
-        </tr>
-        <tr>
-            <td width="220" class="multi-line">
-                New Ticket by Staff:
-            </td>
-            <td>
-                <em>Notice sent when staff creates a ticket on behalf of the user (Staff can disable)</em><br>
-                <input type="radio" name="ticket_notice_active" value="1" checked="checked">Enable
-                <input type="radio" name="ticket_notice_active" value="0">Disable
-                <br><br>
-            </td>
-        </tr>
-        <tr>
-            <td width="220" class="multi-line">
-                New Message:
-            </td>
-            <td>
-                <em>Message appended to an existing ticket confirmation</em><br>
-                <input type="radio" name="message_autoresponder" value="1">Enable
-                <input type="radio" name="message_autoresponder" value="0" checked="checked">Disable
-                <br><br>
-            </td>
-        </tr>
-        <tr>
-            <td width="220" class="multi-line">
-                Ticket Denied:
-            </td>
-            <td>
-                <em>Ticket denied notice sent <strong>only once</strong> on limit violation to the user.</em><br>
-                <input type="radio" name="overlimit_notice_active"  value="1">Enable
-                <input type="radio" name="overlimit_notice_active"  value="0" checked="checked">Disable
-                <em><strong>Note:</strong> Admin gets alerts on ALL denials by default.</em>
-                <br><br>
-            </td>
-        </tr>
-    </tbody>
-</table>
-<table class="form_table settings_table" width="940" border="0" cellspacing="0" cellpadding="2">
-    <thead>
-        <tr>
-            <th colspan="2">
-                <h4><a href="#"><span>&ndash;</span>&nbsp;Alerts and Notices</a></h4>
-                <em>Notices sent to user use 'No Reply Email' whereas alerts to staff use 'Alert Email' set above as FROM address respectively.</em>
-            </th>
-        </tr>
-    </thead>
-    <tbody>
-        <tr>
-            <td width="220" class="multi-line">
-                New Ticket Alert:
-            </td>
-            <td>
-                <input type="radio" name="ticket_alert_active" value="1" checked="checked">Enable
-                <input type="radio" name="ticket_alert_active" value="0">Disable
-                <br>
-                <strong>Select recipients:</strong>&nbsp;
-                <input type="checkbox" name="ticket_alert_admin" checked="checked"> Admin Email
-                <input type="checkbox" name="ticket_alert_dept_manager"> Department Manager
-                <input type="checkbox" name="ticket_alert_dept_members"> Department Members (spammy)
-            </td>
-        </tr>
-        <tr>
-            <td width="220" class="multi-line">
-                New Message Alert:
-            </td>
-            <td>
-                <input type="radio" name="message_alert_active" value="1" checked="checked">Enable
-                <input type="radio" name="message_alert_active" value="0">Disable
-                <br>
-                <strong>Select recipients:</strong>&nbsp;
-                <input type="checkbox" name="message_alert_laststaff" checked="checked"> Last Respondent
-                <input type="checkbox" name="message_alert_assigned" checked="checked"> Assigned Staff
-                <input type="checkbox" name="message_alert_dept_manager"> Department Manager (spammy)
-            </td>
-        </tr>
-        <tr>
-            <td width="220">
-                New Internal Note Alert:
-            </td>
-            <td>
-                <input type="radio" name="note_alert_active" value="1" checked="checked">Enable
-                <input type="radio" name="note_alert_active" value="0">Disable
-                <br>
-                <strong>Select recipients:</strong>&nbsp;
-                <input type="checkbox" name="note_alert_laststaff" checked="checked"> Last Respondent
-                <input type="checkbox" name="note_alert_assigned" checked="checked"> Assigned Staff
-                <input type="checkbox" name="note_alert_dept_manager"> Department Manager (spammy)
-            </td>
-        </tr>
-        <tr>
-            <td width="220" class="multi-line">
-                Overdue Ticket Alert:
-            </td>
-            <td>
-                <input type="radio" name="overdue_alert_active" value="1" checked="checked">Enable
-                <input type="radio" name="overdue_alert_active"  value="0">Disable
-                <br>
-                <strong>Select recipients:</strong>
-                <input type="checkbox" name="overdue_alert_assigned" checked="checked"> Assigned Staff
-                <input type="checkbox" name="overdue_alert_dept_manager" checked="checked"> Department Manager
-                <input type="checkbox" name="overdue_alert_dept_members"> Department Members (spammy)
-                <br><em><strong>Note:</strong> Admin gets all overdue alerts by default.</em>
-            </td>
-        </tr>
-        <tr>
-            <td width="220" class="multi-line">
-                System Errors:
-            </td>
-            <td>
-                <input type="checkbox" name="send_sys_errors" checked="checked" disabled="disabled">System Errors
-                <input type="checkbox" name="send_sql_errors" checked="checked">SQL errors
-                <input type="checkbox" name="send_login_errors" checked="checked">Excessive Login attempts
-                <br><em>Enabled errors are sent to admin email set above</em>
-            </td>
-        </tr>
-    </tbody>
-</table>
-<p class="centered">
-    <input class="btn_sm" type="submit" name="submit" value="Save Changes">
-    <input class="btn_sm" type="reset" name="reset" value="Reset Changes">
-</p>
-</form>
-
-<script type="text/javascript">
-    jQuery(function($) {
-        $('.expand_all').click(function(e) {
-            e.preventDefault();
-            $('.settings_table tbody').each(function() {
-                $(this).slideDown();
-            })
-            $('.settings_table h4 span').each(function() {
-                $(this).html('&ndash;');
-            })
-        })
-        $('.collapse_all').click(function(e) {
-            e.preventDefault();
-            $('.settings_table tbody').each(function() {
-                $(this).slideUp();
-            })
-            $('.settings_table h4 span').each(function() {
-                $(this).text('+');
-            })
-        })
-        $('.settings_table h4 a').click(function(e) {
-            e.preventDefault();
-            var parent_elem = $(this).parent().parent().parent().parent().parent();
-            $('tbody', parent_elem).slideToggle();
-            if($('th span', parent_elem).text() == '+') {
-                $('th span', parent_elem).html('&ndash;')
-            } else {
-                $('th span', parent_elem).text('+')
-            }
-        })
-    });
-</script>
-
-<?php include "./include/footer.php" ?>
diff --git a/include/staff/slaplan.inc.php b/include/staff/slaplan.inc.php
index 70db620e8..d9c1574fe 100644
--- a/include/staff/slaplan.inc.php
+++ b/include/staff/slaplan.inc.php
@@ -21,6 +21,7 @@ if($sla && $_REQUEST['a']!='add'){
 $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
 ?>
 <form action="slas.php?<?php echo $qstr; ?>" method="post" id="save">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="<?php echo $action; ?>">
  <input type="hidden" name="a" value="<?php echo Format::htmlchars($_REQUEST['a']); ?>">
  <input type="hidden" name="id" value="<?php echo $info['id']; ?>">
diff --git a/include/staff/slaplans.inc.php b/include/staff/slaplans.inc.php
index b8997b6a3..c30d4459a 100644
--- a/include/staff/slaplans.inc.php
+++ b/include/staff/slaplans.inc.php
@@ -46,6 +46,7 @@ else
  <b><a href="slas.php?a=add" class="Icon newsla">Add New SLA Plan</a></b></div>
 <div class="clear"></div>
 <form action="slas.php" method="POST" name="slas" onSubmit="return checkbox_checker(this,1,0);">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="mass_process" >
  <table class="list" border="0" cellspacing="1" cellpadding="0" width="940">
     <caption><?php echo $showing; ?></caption>
diff --git a/include/staff/staff.inc.php b/include/staff/staff.inc.php
index 396512271..ab10d7d19 100644
--- a/include/staff/staff.inc.php
+++ b/include/staff/staff.inc.php
@@ -27,6 +27,7 @@ if($staff && $_REQUEST['a']!='add'){
 $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
 ?>
 <form action="staff.php?<?php echo $qstr; ?>" method="post" id="save" autocomplete="off">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="<?php echo $action; ?>">
  <input type="hidden" name="a" value="<?php echo Format::htmlchars($_REQUEST['a']); ?>">
  <input type="hidden" name="id" value="<?php echo $info['id']; ?>">
diff --git a/include/staff/staffmembers.inc.php b/include/staff/staffmembers.inc.php
index b01e3387f..d923815a0 100644
--- a/include/staff/staffmembers.inc.php
+++ b/include/staff/staffmembers.inc.php
@@ -116,6 +116,7 @@ else
     $showing='No staff found!';
 ?>
 <form action="staff.php" method="POST" name="staff" onSubmit="return checkbox_checker(this,1,0);">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="mass_process" >
  <table class="list" border="0" cellspacing="1" cellpadding="0" width="940">
     <caption><?php echo $showing; ?></caption>
diff --git a/include/staff/syslogs.inc.php b/include/staff/syslogs.inc.php
index e0f5d2098..944652a85 100644
--- a/include/staff/syslogs.inc.php
+++ b/include/staff/syslogs.inc.php
@@ -105,6 +105,7 @@ else
  </form>
 </div>
 <form action="syslogs.php" method="POST" name="logs" onSubmit="return checkbox_checker(this,1,0);">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="mass_process" >
  <table class="list" border="0" cellspacing="1" cellpadding="0" width="940">
     <caption><?php echo $showing; ?></caption>
diff --git a/include/staff/team.inc.php b/include/staff/team.inc.php
index 51b06ce2d..f533bf12b 100644
--- a/include/staff/team.inc.php
+++ b/include/staff/team.inc.php
@@ -21,6 +21,7 @@ if($team && $_REQUEST['a']!='add'){
 $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
 ?>
 <form action="teams.php?<?php echo $qstr; ?>" method="post" id="save">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="<?php echo $action; ?>">
  <input type="hidden" name="a" value="<?php echo Format::htmlchars($_REQUEST['a']); ?>">
  <input type="hidden" name="id" value="<?php echo $info['id']; ?>">
diff --git a/include/staff/teams.inc.php b/include/staff/teams.inc.php
index ab3a2f58d..d9dcee5bb 100644
--- a/include/staff/teams.inc.php
+++ b/include/staff/teams.inc.php
@@ -45,6 +45,7 @@ else
     <b><a href="teams.php?a=add" class="Icon newteam">Add New Team</a></b></div>
 <div class="clear"></div>
 <form action="teams.php" method="POST" name="teams" onSubmit="return checkbox_checker(this,1,0);">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="mass_process" >
  <table class="list" border="0" cellspacing="1" cellpadding="0" width="940">
     <caption><?php echo $showing; ?></caption>
diff --git a/include/staff/template.inc.php b/include/staff/template.inc.php
index ac5c09a74..aff5f8e3b 100644
--- a/include/staff/template.inc.php
+++ b/include/staff/template.inc.php
@@ -20,6 +20,7 @@ if($template && $_REQUEST['a']!='add'){
 $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
 ?>
 <form action="templates.php?<?php echo $qstr; ?>" method="post" id="save">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="<?php echo $action; ?>">
  <input type="hidden" name="a" value="<?php echo Format::htmlchars($_REQUEST['a']); ?>">
  <input type="hidden" name="id" value="<?php echo $info['id']; ?>">
diff --git a/include/staff/templates.inc.php b/include/staff/templates.inc.php
index f60e3b010..dfdfb91c8 100644
--- a/include/staff/templates.inc.php
+++ b/include/staff/templates.inc.php
@@ -49,6 +49,7 @@ else
  <b><a href="templates.php?a=add" class="Icon newEmailTemplate">Add New Template</a></b></div>
 <div class="clear"></div>
 <form action="templates.php" method="POST" name="tpls" onSubmit="return checkbox_checker(this,1,0);">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="mass_process" >
  <table class="list" border="0" cellspacing="1" cellpadding="0" width="940">
     <caption><?php echo $showing; ?></caption>
diff --git a/include/staff/ticket-edit.inc.php b/include/staff/ticket-edit.inc.php
index 7bbf0921e..a01381188 100644
--- a/include/staff/ticket-edit.inc.php
+++ b/include/staff/ticket-edit.inc.php
@@ -4,6 +4,7 @@ if(!defined('OSTSCPINC') || !$thisstaff || !$thisstaff->canEditTickets() || !$ti
 $info=Format::htmlchars(($errors && $_POST)?$_POST:$ticket->getUpdateInfo());
 ?>
 <form action="tickets.php?id=<?php echo $ticket->getId(); ?>&a=edit" method="post" id="save"  enctype="multipart/form-data">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="update">
  <input type="hidden" name="a" value="edit">
  <input type="hidden" name="id" value="<?php echo $ticket->getId(); ?>">
diff --git a/include/staff/ticket-open.inc.php b/include/staff/ticket-open.inc.php
index 680fbad15..a61c7bfcb 100644
--- a/include/staff/ticket-open.inc.php
+++ b/include/staff/ticket-open.inc.php
@@ -4,6 +4,7 @@ $info=array();
 $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
 ?>
 <form action="tickets.php?a=open" method="post" id="save"  enctype="multipart/form-data">
+ <?php csrf_token(); ?>
  <input type="hidden" name="do" value="create">
  <input type="hidden" name="a" value="open">
  <h2>Open New Ticket</h2>
diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php
index b8a2e8097..feb98294b 100644
--- a/include/staff/ticket-view.inc.php
+++ b/include/staff/ticket-view.inc.php
@@ -280,6 +280,7 @@ if(!$cfg->showNotesInline()) { ?>
     </ul>
 
     <form id="reply" action="tickets.php?id=<?php echo $ticket->getId(); ?>#reply" name="reply" method="post" enctype="multipart/form-data">
+        <?php csrf_token(); ?>
         <input type="hidden" name="id" value="<?php echo $ticket->getId(); ?>">
         <input type="hidden" name="msgId" value="<?php echo $msgId; ?>">
         <input type="hidden" name="a" value="reply">
@@ -390,6 +391,7 @@ if(!$cfg->showNotesInline()) { ?>
         </p>
     </form>
     <form id="note" action="tickets.php?id=<?php echo $ticket->getId(); ?>#note" name="note" method="post" enctype="multipart/form-data">
+        <?php csrf_token(); ?>
         <input type="hidden" name="id" value="<?php echo $ticket->getId(); ?>">
         <input type="hidden" name="a" value="postnote">
         <table border="0" cellspacing="0" cellpadding="3">
@@ -478,6 +480,7 @@ if(!$cfg->showNotesInline()) { ?>
     <?php
     if($thisstaff->canTransferTickets()) { ?>
     <form id="transfer" action="tickets.php?id=<?php echo $ticket->getId(); ?>#transfer" name="transfer" method="post" enctype="multipart/form-data">
+        <?php csrf_token(); ?>
         <input type="hidden" name="ticket_id" value="<?php echo $ticket->getId(); ?>">
         <input type="hidden" name="a" value="transfer">
         <table border="0" cellspacing="0" cellpadding="3">
@@ -526,6 +529,7 @@ if(!$cfg->showNotesInline()) { ?>
     <?php
     if($thisstaff->canAssignTickets()) { ?>
     <form id="assign" action="tickets.php?id=<?php echo $ticket->getId(); ?>#assign" name="assign" method="post" enctype="multipart/form-data">
+        <?php csrf_token(); ?>
         <input type="hidden" name="id" value="<?php echo $ticket->getId(); ?>">
         <input type="hidden" name="a" value="assign">
         <table border="0" cellspacing="0" cellpadding="3">
diff --git a/scp/ajax.php b/scp/ajax.php
index 2310fc67a..d14727c85 100644
--- a/scp/ajax.php
+++ b/scp/ajax.php
@@ -61,7 +61,7 @@ $dispatcher = patterns('',
     url_get('^/users$', array('ajax.users.php:UsersAjaxAPI', 'search')),
     url('^/tickets/', patterns('ajax.tickets.php:TicketsAjaxAPI',
         url_get('^(?P<tid>\d+)/preview', 'previewTicket'),
-        url_get('^(?P<tid>\d+)/lock', 'acquireLock'),
+        url_post('^(?P<tid>\d+)/lock', 'acquireLock'),
         url_post('^(?P<tid>\d+)/lock/(?P<id>\d+)/renew', 'renewLock'),
         url_post('^(?P<tid>\d+)/lock/(?P<id>\d+)/release', 'releaseLock'),
         url_get('^lookup', 'lookup'),
diff --git a/scp/js/scp.js b/scp/js/scp.js
index b31f673f0..294c47a69 100644
--- a/scp/js/scp.js
+++ b/scp/js/scp.js
@@ -323,5 +323,4 @@ $(document).ready(function(){
                 $('.buttons', elem).show();
              });
     });
-
 });
diff --git a/scp/js/ticket.js b/scp/js/ticket.js
index 22a97d623..5b6872f58 100644
--- a/scp/js/ticket.js
+++ b/scp/js/ticket.js
@@ -152,7 +152,7 @@ var autoLock = {
             autoLock.renewLock(e);
         } else {
             $.ajax({
-                type: "GET",
+                type: "POST",
                 url: 'ajax.php/tickets/'+autoLock.tid+'/lock',
                 dataType: 'json',
                 cache: false,
diff --git a/scp/staff.inc.php b/scp/staff.inc.php
index a8310f5ed..633c897c7 100644
--- a/scp/staff.inc.php
+++ b/scp/staff.inc.php
@@ -39,6 +39,7 @@ define('KB_PREMADE_TABLE',TABLE_PREFIX.'kb_premade');
 require_once(INCLUDE_DIR.'class.staff.php');
 require_once(INCLUDE_DIR.'class.group.php');
 require_once(INCLUDE_DIR.'class.nav.php');
+require_once(INCLUDE_DIR.'class.csrf.php');
 
 /* First order of the day is see if the user is logged in and with a valid session.
     * User must be valid staff beyond this point 
@@ -80,6 +81,9 @@ if(!$thisstaff->isAdmin()) {
 //Keep the session activity alive
 $thisstaff->refreshSession();
 
+// Enforce CSRF protection for POSTS
+if ($_POST) csrf_ensure_cookie();
+
 /******* SET STAFF DEFAULTS **********/
 //Set staff's timezone offset.
 $_SESSION['TZ_OFFSET']=$thisstaff->getTZoffset();
-- 
GitLab