~tribaal/txaws/xss-hardening

« back to all changes in this revision

Viewing changes to txaws/server/tests/test_resource.py

  • Committer: Christopher Glass
  • Date: 2013-08-15 11:14:55 UTC
  • Revision ID: christopher.glass@canonical.com-20130815111455-dckrxs9ppj7tev7h
HTML escape values then raising errors to prevent malicious users from tricking
legitimate users into accessing an error URL crafted with executable code.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
from cgi import escape
 
2
 
1
3
from cStringIO import StringIO
2
4
from datetime import datetime
3
5
 
428
430
 
429
431
        return self.api.handle(request).addCallback(check)
430
432
 
431
 
    def test_handle_with_parameter_error_is_api_content_type(self):
 
433
    def test_handle_error_is_api_content_type(self):
432
434
        """
433
435
        If an error occurs while parsing the parameters, L{QueryAPI.handle}
434
436
        responds with HTTP status 400, and the resulting response has a
445
447
            errors = self.flushLoggedErrors()
446
448
            self.assertEquals(0, len(errors))
447
449
            self.assertEqual(400, request.code)
 
450
 
448
451
            request_type = request.headers['Content-Type']
449
452
            self.assertEqual(self.api.content_type, request_type)
450
453
 
476
479
        self.api.principal = TestPrincipal(creds)
477
480
        return self.api.handle(request).addCallback(check)
478
481
 
 
482
    def test_api_error_is_HTML_safe(self):
 
483
        """
 
484
        In some cases, an attacker can trigger an API error in which the passed
 
485
        value is returned in the error message. Should a victim be tricked to
 
486
        a properly crafted URL, the error message would be passed unchecked to
 
487
        her web browser, resulting in arbitrary code execution.
 
488
        """
 
489
        creds = AWSCredentials("access", "secret")
 
490
        endpoint = AWSServiceEndpoint("http://uri")
 
491
        query = Query(action="SomeAction", creds=creds, endpoint=endpoint)
 
492
        query.sign()
 
493
        request = FakeRequest(query.params, endpoint)
 
494
 
 
495
        toxic = u"<script>alert('Owned!');</script>"
 
496
 
 
497
        escaped = escape(toxic)
 
498
 
 
499
        def fail_execute(call):
 
500
            raise APIError(400, code="LangError", message=toxic)
 
501
        self.api.execute = fail_execute
 
502
 
 
503
        def check(ignored):
 
504
            errors = self.flushLoggedErrors()
 
505
            self.assertEquals(0, len(errors))
 
506
            self.assertTrue(request.finished)
 
507
 
 
508
            self.assertTrue(toxic not in request.response)
 
509
            self.assertTrue(escaped in request.response)
 
510
            self.assertEqual(400, request.code)
 
511
 
 
512
        self.api.principal = TestPrincipal(creds)
 
513
        return self.api.handle(request).addCallback(check)
 
514
 
479
515
    def test_handle_unicode_error(self):
480
516
        """
481
517
        If an arbitrary error raised by an API method contains a unicode