comparison doc/customizing.txt @ 5201:a9ace22e0a2f

issue 2550690 - Adding anti-csrf measures to roundup following https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet and https://seclab.stanford.edu/websec/csrf/csrf.pdf Basically implement Synchronizer (CSRF) Tokens per form on a page. Single use (destroyed once used). Random input data for the token includes: system random implementation in python using /dev/urandom (fallback to random based on timestamp as the seed. Not as good, but should be ok for the short lifetime of the token??) the id (in cpython it's the memory address) of the object requesting a token. In theory this depends on memory layout, the history of the process (how many previous objects have been allocated from the heap etc.) I claim without any proof that for long running processes this is another source of randomness. For short running processes with little activity it could be guessed. last the floating point time.time() value is added. This may only have 1 second resolution so may be guessable. Hopefully for a short lived (2 week by default) token this is sufficient. Also in the current implementation the user is notified when validation fails and is told why. This allows the roundup admin to find the log entry (at error level) and try to resolve the issue. In the future user notification may change but for now this is probably best.
author John Rouillard <rouilj@ieee.org>
date Sat, 18 Mar 2017 16:59:01 -0400
parents e0732fd6a6c7
children 8d2c1c9a49e1
comparison
equal deleted inserted replaced
5200:16a8a3f0772c 5201:a9ace22e0a2f
1642 **editCSV** 1642 **editCSV**
1643 Determine whether the user has permission to edit this class. 1643 Determine whether the user has permission to edit this class.
1644 **search** 1644 **search**
1645 Determine whether the user has permission to view this class. 1645 Determine whether the user has permission to view this class.
1646 1646
1647 Protecting users from web application attacks
1648 ---------------------------------------------
1649
1650 There is a class of attacks known as Cross Site Request Forgeries
1651 (CSRF). Malicious code running in the browser can making a
1652 request to roundup while you are logged into roundup. The
1653 malicious code piggy backs on your existing roundup session to
1654 make changes without your knowledge. Roundup 1.6 has support for
1655 defending against this by analyzing the
1656
1657 * Referer,
1658 * Origin, and
1659 * Host or
1660 * X-Forwarded-Host
1661
1662 HTTP headers. It compares the headers to the value of the web setting
1663 in the [tracker] section of the tracker's ``config.ini``.
1664
1665 Also a per form token (also called a nonce) can be enabled for
1666 the tracker using the ``csrf_enforce_token`` option in
1667 config.ini. When enabled, roundup will validate a hidden form
1668 field called ``@csrf``. If the validation fails (or the token
1669 is used more than one) the request is rejected. The ``@csrf``
1670 input field is added automatically by calling the ``submit``
1671 function/path. It can also be added manually by calling
1672 anti_csrf_nonce() directly. For example:
1673
1674 <input name="@csrf" type="hidden"
1675 tal:attributes="value python:utils.anti_csrf_nonce(lifetime=10)">
1676
1677 By default a nonce lifetime is 2 weeks. However the lifetime (in
1678 minutes) can be set by passing a lifetime argument as shown
1679 above. The example above makes the nonce lifetime 10 minutes.
1680
1681 Search for @csrf in this document for more examples. There are
1682 more examples and information in ``upgrading.txt``.
1683
1684 The token protects you because malicious code supplied by another
1685 site is unable to obtain the token. Thus many attempts they make
1686 to submit a request are rejected.
1687
1688 The protection on the xmlrpc interface is untested, but is based
1689 on a valid header check against the roundup url and the presence
1690 of the ``X-REQUESTED-WITH`` header. Work to improve this is a
1691 future project after the 1.6 release.
1692
1693 The enforcement levels an be modified in ``config.ini``. Refer to
1694 that file for details.
1647 1695
1648 Special form variables 1696 Special form variables
1649 ---------------------- 1697 ----------------------
1650 1698
1651 Item properties and their values are edited with html FORM 1699 Item properties and their values are edited with html FORM
2364 2412
2365 If the "form" arg is given, it's passed through to the 2413 If the "form" arg is given, it's passed through to the
2366 javascript help_window function - it's the name of the form 2414 javascript help_window function - it's the name of the form
2367 the "property" belongs to. 2415 the "property" belongs to.
2368 2416
2369 submit generate a submit button (and action hidden element) 2417 submit generate a submit button (and action and @csrf hidden elements)
2370 renderWith render this class with the given template. 2418 renderWith render this class with the given template.
2371 history returns 'New node - no history' :) 2419 history returns 'New node - no history' :)
2372 is_edit_ok is the user allowed to Edit the current class? 2420 is_edit_ok is the user allowed to Edit the current class?
2373 is_view_ok is the user allowed to View the current class? 2421 is_view_ok is the user allowed to View the current class?
2374 =========== ============================================================= 2422 =========== =============================================================
2397 There are several methods available on these wrapper objects: 2445 There are several methods available on these wrapper objects:
2398 2446
2399 =============== ======================================================== 2447 =============== ========================================================
2400 Method Description 2448 Method Description
2401 =============== ======================================================== 2449 =============== ========================================================
2402 submit generate a submit button (and action hidden element) 2450 submit generate a submit button (and action and @csrf hidden elements)
2403 journal return the journal of the current item (**not 2451 journal return the journal of the current item (**not
2404 implemented**) 2452 implemented**)
2405 history render the journal of the current item as HTML 2453 history render the journal of the current item as HTML
2406 renderQueryForm specific to the "query" class - render the search form 2454 renderQueryForm specific to the "query" class - render the search form
2407 for the query 2455 for the query
3608 <td colspan="3" tal:content="structure context/submit"> 3656 <td colspan="3" tal:content="structure context/submit">
3609 submit button will go here 3657 submit button will go here
3610 </td> 3658 </td>
3611 </tr> 3659 </tr>
3612 3660
3661 The ``context/submit`` bit generates the submit button but also
3662 generates the @action and @csrf hidden fields. The @action field is
3663 used to tell roundup how to process the form. The @csrf field provides
3664 a unique single use token to defend against CSRF attacks. (More about
3665 anti-csrf measures can be found in ``upgrading.txt``.)
3666
3613 Finally we finish off the tags we used at the start to do the METAL 3667 Finally we finish off the tags we used at the start to do the METAL
3614 stuff:: 3668 stuff::
3615 3669
3616 </td> 3670 </td>
3617 </tal:block> 3671 </tal:block>
5095 3. after the ``tal:block`` which lists the index items (marked by 5149 3. after the ``tal:block`` which lists the index items (marked by
5096 ``tal:repeat="i batch"``) add a new table row:: 5150 ``tal:repeat="i batch"``) add a new table row::
5097 5151
5098 <tr> 5152 <tr>
5099 <td tal:attributes="colspan python:len(request.columns)"> 5153 <td tal:attributes="colspan python:len(request.columns)">
5154 <input name="@csrf" type="hidden"
5155 tal:attributes="value python:utils.anti_csrf_nonce()">
5100 <input type="submit" value=" Save Changes "> 5156 <input type="submit" value=" Save Changes ">
5101 <input type="hidden" name="@action" value="edit"> 5157 <input type="hidden" name="@action" value="edit">
5102 <tal:block replace="structure request/indexargs_form" /> 5158 <tal:block replace="structure request/indexargs_form" />
5103 </td> 5159 </td>
5104 </tr> 5160 </tr>
5105 5161
5106 which gives us a submit button, indicates that we are performing an edit 5162 which gives us a submit button, indicates that we are performing an
5107 on any changed statuses. The final ``tal:block`` will make sure that the 5163 edit on any changed statuses, and provides a defense against cross
5108 current index view parameters (filtering, columns, etc) will be used in 5164 site request forgery attacks.
5109 rendering the next page (the results of the editing). 5165
5166 The final ``tal:block`` will make sure that the current index view
5167 parameters (filtering, columns, etc) will be used in rendering the
5168 next page (the results of the editing).
5110 5169
5111 5170
5112 Displaying only message summaries in the issue display 5171 Displaying only message summaries in the issue display
5113 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 5172 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5114 5173
5187 that category. The first page includes a table of help, explaining 5246 that category. The first page includes a table of help, explaining
5188 what the category names mean, and then the core of the form:: 5247 what the category names mean, and then the core of the form::
5189 5248
5190 <form method="POST" onSubmit="return submit_once()" 5249 <form method="POST" onSubmit="return submit_once()"
5191 enctype="multipart/form-data"> 5250 enctype="multipart/form-data">
5251 <input name="@csrf" type="hidden"
5252 tal:attributes="value python:utils.anti_csrf_nonce()">
5192 <input type="hidden" name="@template" value="add_page1"> 5253 <input type="hidden" name="@template" value="add_page1">
5193 <input type="hidden" name="@action" value="page1_submit"> 5254 <input type="hidden" name="@action" value="page1_submit">
5194 5255
5195 <strong>Category:</strong> 5256 <strong>Category:</strong>
5196 <tal:block tal:replace="structure context/category/menu" /> 5257 <tal:block tal:replace="structure context/category/menu" />
5203 <form method="POST" onSubmit="return submit_once()" 5264 <form method="POST" onSubmit="return submit_once()"
5204 enctype="multipart/form-data" 5265 enctype="multipart/form-data"
5205 tal:condition="context/is_edit_ok" 5266 tal:condition="context/is_edit_ok"
5206 tal:define="cat request/form/category/value"> 5267 tal:define="cat request/form/category/value">
5207 5268
5269 <input name="@csrf" type="hidden"
5270 tal:attributes="value python:utils.anti_csrf_nonce()">
5208 <input type="hidden" name="@template" value="add_page2"> 5271 <input type="hidden" name="@template" value="add_page2">
5209 <input type="hidden" name="@required" value="title"> 5272 <input type="hidden" name="@required" value="title">
5210 <input type="hidden" name="category" tal:attributes="value cat"> 5273 <input type="hidden" name="category" tal:attributes="value cat">
5211 . 5274 .
5212 . 5275 .

Roundup Issue Tracker: http://roundup-tracker.org/