The bok-choy framework includes the ability to perform XSS (cross-site scripting) audits on web pages using a short XSS locator defined in https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#XSS_Locator.
You might already have some bok-choy tests written for your web application. To leverage existing bok-choy tests and have them fail on finding XSS vulnerabilities, follow these steps.
XSS_INJECTIONstring defined in
bok_choy.page_objectinto your page content.
VERIFY_XSSenvironment variable to
With this environment variable set, an XSS audit is triggered whenever a page object’s
that is embedded within HTML.
If errors are found on the page, an XSSExposureError is raised.
Here is an example of a bok-choy test that will check for XSS vulnerabilities. It clicks a button on the page, and the user’s name is inserted into the page. If the user name is not properly escaped, the display of the name (which is data provided by the user and thus potentially malicious) can cause XSS issues.
In the case of the
test_button_click_output test case in the example below,
an audit will be done in the
visit() method calls,
as each of those will call out to
If any XSS errors are found, then the test case will fail with an XSSExposureError.
from bok_choy.page_object import PageObject, XSS_INJECTION class MyPage(PageObject): def url(self): return 'https://www.mysite.com/page' def is_browser_on_page(self): return self.q(css='div#fixture button').present def click_button(self): """ Click on the button element (id="button"). On my example page this will trigger an ajax call that updates the #output div with the user's name. """ self.q(css='div#fixture button').first.click() self.wait_for_ajax() @property def output(self): """ Return the contents of the "#output" div on the page. In the example page, it will contain the user's name after being updated by the ajax call that is triggered by clicking the button. """ text_list = self.q(css='#output').text if len(text_list) < 1: return None else: return text_list class MyPageTest(WebAppTest): def setUp(self): """ Log in as a particular user. """ super(MyPageTest, self).setUp() self.user_name = XSS_INJECTION self.log_in_as_user(self.user_name) def test_button_click_output(self): page = MyPage(self.browser) page.visit() page.click_button() self.assertEqual(page.output, self.user_name) def log_in_as_user(self, user_name): """ Would be implemented to log in as a particular user with a potentially malicious, user-provided name. """ pass