diff --git a/include/class.csrf.php b/include/class.csrf.php
index d55dcea0c716cd21db5fe46c17bed3d9cfdb6719..633828d9d7d5acdcca5eab4e4a6706a38cc04a84 100644
--- a/include/class.csrf.php
+++ b/include/class.csrf.php
@@ -4,15 +4,19 @@
 
     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.
+    session, 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.
+    sending a separate header (X-CSRFToken) when forms are submitted (e.g Ajax).
 
     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/.
 
+    * TIMEOUT
+    Token can be expired after X seconds of inactivity (timeout) independent of the session.
+    
+
     Jared Hancock 
     Copyright (c)  2006-2012 osTicket
     http://www.osticket.com
@@ -23,69 +27,66 @@
     vim: expandtab sw=4 ts=4 sts=4:
 **********************************************************************/
 
-function csrf_token() {
-    ?>
-    <input type="hidden" name="__CSRFToken__" value="<?php
-        echo csrf_get_token(); ?>" />
-    <?php
-}
+Class CSRF {
+
+    var $name;
+    var $timeout;
+
+    var $csrf;
 
-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);
+    function CSRF($name='__CSRFToken__', $timeout=0) {
+
+        $this->name = $name;
+        $this->timeout = $timeout;
+        $this->csrf = &$_SESSION['csrf'];
     }
-    return $_SESSION['CSRFToken'];
-}
 
-function csrf_ensure_cookie() {
-    global $csrf_unprotected;
-    if ($csrf_unprotected)
-        return true;
+    function reset() {
+        $this->csrf = array();
+    }
 
-    $token = csrf_get_token();
-    if (isset($_POST['__CSRFToken__'])) {
-        if ($token == $_POST['__CSRFToken__'])
-            return true;
+    function isExpired() {
+       return ($this->timeout && (time()-$this->csrf['time'])>$this->timeout);
     }
-    elseif (isset($_SERVER['HTTP_X_CSRFTOKEN'])) {
-        if ($token == $_SERVER['HTTP_X_CSRFTOKEN'])
-            return true;
+
+    function getTokenName() {
+        return $this->name;
     }
-    Http::response(400, 'CSRF Token Required');
-}
 
-function csrf_unprotect() {
-    global $csrf_unprotected;
-    $csrf_unprotected = true;
-}
+    function getToken($len=32) {
+
+        if(!$this->csrf['token'] || $this->isExpired()) {
+
+            $len = $len>8?$len:32;
+            for ($i = 0; $i <= $len; $i++)
+                $r .= chr(mt_rand(0, 255));
+        
+            $this->csrf['token'] = base64_encode(sha1(session_id().$r.SECRET_SALT));
+            $this->csrf['time'] = time();
+        } else {
+            //Reset the timer
+            $this->csrf['time'] = time();
+        }
 
-# 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));
+        return $this->csrf['token'];
     }
-    function safeMethod(method) {
-        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
+
+    function validateToken($token) {
+        return ($token && trim($token)==$this->getToken() && !$this->isExpired());
     }
-    if (!safeMethod(settings.type) && sameOrigin(settings.url)) {
-        xhr.setRequestHeader("X-CSRFToken", "<?php echo csrf_get_token(); ?>");
+
+    function getFormInput($name='') {
+        if(!$name) $name = $this->name;
+
+        return sprintf('<input type="hidden" name="%s" value="%s" />', $name, $this->getToken());
     }
-});
-</script>
-<?php }
+}
 
+/* global function to add hidden token input with to forms */
+function csrf_token() {
+    global $ost;
+
+    if($ost && $ost->getCSRF())
+        echo $ost->getCSRFFormInput();
+}
 ?>