Anonymous committed a4d31ef

0.10-stable branch: Use a separate cookie to store the form_token
value since this is slightly safer and works better with plugins that
play with the session/auth cookie.

Comments (0)

Files changed (1)

 from trac.core import *
 from trac.env import open_environment
 from trac.perm import PermissionCache, NoPermissionCache, PermissionError
-from trac.util import reversed, get_last_traceback
+from trac.util import reversed, get_last_traceback, hex_entropy
 from trac.util.datefmt import format_datetime, http_date
 from trac.util.html import Markup
 from trac.util.text import to_unicode
                     # Protect against CSRF attacks.
                     if (req.method == 'POST' and
                         req.args.get('__FORM_TOKEN') != req.form_token):
-                        raise TracError('Missing or invalid form token '
+                        raise TracError('Missing or invalid form token. '
                                         'Do you have cookies enabled?')
                     resp = chosen_handler.process_request(req)
     def _get_form_token(self, req):
         """Used to protect against CSRF.
-        The 'trac_auth' cookie is a good and strong shared secret, only
-        known by the user it belongs to and Trac itself.
-        The session id is our second best option, not as reliable since
-        it will change on each request if the user has cookies disabled in
-        his/her browser.
+        The 'form_token' is strong shared secret stored in a user cookie.
+        By requiring that every POST form to contain this value we're
+        able to protect against CSRF attacks. Since this value is only known
+        by the user and not by an attacker.
+        If the the user does not have a `trac_form_token` cookie a new
+        one is generated.
-        if req.incookie.has_key('trac_auth'):
-            return req.incookie['trac_auth'].value
+        if req.incookie.has_key('trac_form_token'):
+            return req.incookie['trac_form_token'].value
-            return req.session.sid
+            req.outcookie['trac_form_token'] = hex_entropy(24)
+            req.outcookie['trac_form_token']['path'] = req.base_path
+            req.outcookie['trac_form_token']['expires'] = 3600*24*90 # 90 days
+            return req.outcookie['trac_form_token'].value
 def dispatch_request(environ, start_response):
     """Main entry point for the Trac web interface.
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.