comparison test/test_cgi.py @ 5203:9f490cc0effe

Also rename test to testCsrfProtection Add tests that include valid and invalid @csrf nonce
author John Rouillard <rouilj@ieee.org>
date Sat, 18 Mar 2017 22:19:51 -0400
parents a9ace22e0a2f
children 23b8eeaf9864
comparison
equal deleted inserted replaced
5202:47bd81998ddc 5203:9f490cc0effe
10 10
11 import unittest, os, shutil, errno, sys, difflib, cgi, re, StringIO 11 import unittest, os, shutil, errno, sys, difflib, cgi, re, StringIO
12 12
13 from roundup.cgi import client, actions, exceptions 13 from roundup.cgi import client, actions, exceptions
14 from roundup.cgi.exceptions import FormError 14 from roundup.cgi.exceptions import FormError
15 from roundup.cgi.templating import HTMLItem, HTMLRequest, NoTemplate 15 from roundup.cgi.templating import HTMLItem, HTMLRequest, NoTemplate, anti_csrf_nonce
16 from roundup.cgi.templating import HTMLProperty, _HTMLItem 16 from roundup.cgi.templating import HTMLProperty, _HTMLItem
17 from roundup.cgi.form_parser import FormParser 17 from roundup.cgi.form_parser import FormParser
18 from roundup import init, instance, password, hyperdb, date 18 from roundup import init, instance, password, hyperdb, date
19 19
20 # For testing very simple rendering 20 # For testing very simple rendering
855 <p><input type="text" name="superseder" value="5000" size="30"></p> 855 <p><input type="text" name="superseder" value="5000" size="30"></p>
856 </body> 856 </body>
857 </html> 857 </html>
858 """.strip ()) 858 """.strip ())
859 859
860 def testCsrfHeaderProtection(self): 860 def testCsrfProtection(self):
861 # need to set SENDMAILDEBUG to prevent 861 # need to set SENDMAILDEBUG to prevent
862 # downstream issue when email is sent on successful 862 # downstream issue when email is sent on successful
863 # issue creation. Also delete the file afterwards 863 # issue creation. Also delete the file afterwards
864 # just tomake sure that someother test looking for 864 # just tomake sure that someother test looking for
865 # SENDMAILDEBUG won't trip over ours. 865 # SENDMAILDEBUG won't trip over ours.
892 ':action': 'edit'} 892 ':action': 'edit'}
893 cl = self.setupClient(form, 'issue', '1') 893 cl = self.setupClient(form, 'issue', '1')
894 pt = RoundupPageTemplate() 894 pt = RoundupPageTemplate()
895 pt.pt_edit(page_template, 'text/html') 895 pt.pt_edit(page_template, 'text/html')
896 out = [] 896 out = []
897 print "out1: ", id(out), out
898 def wh(s): 897 def wh(s):
899 out.append(s) 898 out.append(s)
900 cl.write_html = wh 899 cl.write_html = wh
901 # Enable the following if we get a templating error: 900 # Enable the following if we get a templating error:
902 #def send_error (*args, **kw): 901 #def send_error (*args, **kw):
921 HTMLProperty.is_edit_ok = lambda x : True 920 HTMLProperty.is_edit_ok = lambda x : True
922 921
923 # test with no headers and config by default requires 1 922 # test with no headers and config by default requires 1
924 cl.inner_main() 923 cl.inner_main()
925 match_at=out[0].find('Unable to verify sufficient headers') 924 match_at=out[0].find('Unable to verify sufficient headers')
926 print out[0]
927 self.assertNotEqual(match_at, -1) 925 self.assertNotEqual(match_at, -1)
928 del(out[0]) 926 del(out[0])
929 927
930 # all the rest of these allow at least one header to pass 928 # all the rest of these allow at least one header to pass
931 # and the edit happens with a redirect back to issue 1 929 # and the edit happens with a redirect back to issue 1
969 # this raises an error as the header check passes and 967 # this raises an error as the header check passes and
970 # it did the edit and tries to send mail. 968 # it did the edit and tries to send mail.
971 cl.inner_main() 969 cl.inner_main()
972 match_at=out[0].find('Invalid X-FORWARDED-HOST whoami.net') 970 match_at=out[0].find('Invalid X-FORWARDED-HOST whoami.net')
973 self.assertNotEqual(match_at, -1) 971 self.assertNotEqual(match_at, -1)
972 del(cl.env['HTTP_X-FORWARDED-HOST'])
973 del(out[0])
974
975 import copy
976
977 form2 = copy.copy(form)
978 form2.update({'@csrf': 'booogus'})
979 # add a bogus csrf field to the form and rerun the inner_main
980 cl.form = makeForm(form2)
981
982 cl.env['HTTP_REFERER'] = 'http://whoami.com/path/'
983 cl.inner_main()
984 match_at=out[0].find('Invalid csrf token found: booogus')
985 self.assertEqual(match_at, 36)
986 del(out[0])
987
988 form2 = copy.copy(form)
989 nonce = anti_csrf_nonce(cl, cl)
990 form2.update({'@csrf': nonce})
991 # add a real csrf field to the form and rerun the inner_main
992 cl.form = makeForm(form2)
993 cl.inner_main()
994 # csrf passes and redirects to the new issue.
995 match_at=out[0].find('Redirecting to <a href="http://whoami.com/path/issue1?@ok_message')
996 self.assertEqual(match_at, 0)
997 del(cl.env['HTTP_REFERER'])
974 del(out[0]) 998 del(out[0])
975 999
976 # clean up from email log 1000 # clean up from email log
977 if os.path.exists(SENDMAILDEBUG): 1001 if os.path.exists(SENDMAILDEBUG):
978 os.remove(SENDMAILDEBUG) 1002 os.remove(SENDMAILDEBUG)

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