|
5 | 5 | # |
6 | 6 |
|
7 | 7 | from __future__ import print_function |
8 | | -import unittest, os, shutil, errno, sys, difflib, re |
| 8 | +import unittest, os, shutil, errno, pytest, sys, difflib, re |
9 | 9 |
|
10 | 10 | from roundup.anypy import xmlrpc_ |
11 | 11 | MultiCall = xmlrpc_.client.MultiCall |
|
21 | 21 | from .test_mysql import skip_mysql |
22 | 22 | from .test_postgresql import skip_postgresql |
23 | 23 |
|
| 24 | +from .pytest_patcher import mark_class |
| 25 | +from roundup.anypy.xmlrpc_ import client |
| 26 | + |
| 27 | +if client.defusedxml: |
| 28 | + skip_defusedxml = lambda func, *args, **kwargs: func |
| 29 | + |
| 30 | + skip_defusedxml_used = mark_class(pytest.mark.skip( |
| 31 | + reason='Skipping non-defusedxml tests: defusedxml library in use')) |
| 32 | +else: |
| 33 | + skip_defusedxml = mark_class(pytest.mark.skip( |
| 34 | + reason='Skipping defusedxml tests: defusedxml library not available')) |
| 35 | + |
| 36 | + skip_defusedxml_used = lambda func, *args, **kwargs: func |
24 | 37 |
|
25 | 38 | class XmlrpcTest(object): |
26 | 39 |
|
@@ -314,6 +327,55 @@ class S: |
314 | 327 | for n, r in enumerate(result): |
315 | 328 | self.assertEqual(r, results[n]) |
316 | 329 |
|
| 330 | + @skip_defusedxml |
| 331 | + def testDefusedXmlBomb(self): |
| 332 | + self.XmlBomb(expectIn=b"defusedxml.common.EntitiesForbidden") |
| 333 | + |
| 334 | + @skip_defusedxml_used |
| 335 | + def testNonDefusedXmlBomb(self): |
| 336 | + self.XmlBomb(expectIn=b"1234567890"*511) |
| 337 | + |
| 338 | + def XmlBomb(self, expectIn=None): |
| 339 | + |
| 340 | + bombInput = """<?xml version='1.0'?> |
| 341 | + <!DOCTYPE xmlbomb [ |
| 342 | + <!ENTITY a "1234567890" > |
| 343 | + <!ENTITY b "&a;&a;&a;&a;&a;&a;&a;&a;"> |
| 344 | + <!ENTITY c "&b;&b;&b;&b;&b;&b;&b;&b;"> |
| 345 | + <!ENTITY d "&c;&c;&c;&c;&c;&c;&c;&c;"> |
| 346 | + ]> |
| 347 | + <methodCall> |
| 348 | + <methodName>filter</methodName> |
| 349 | + <params> |
| 350 | + <param> |
| 351 | + <value><string>&d;</string></value> |
| 352 | + </param> |
| 353 | + <param> |
| 354 | + <value><array><data> |
| 355 | + <value><string>0</string></value> |
| 356 | + <value><string>2</string></value> |
| 357 | + <value><string>3</string></value> |
| 358 | + </data></array></value> |
| 359 | + </param> |
| 360 | + <param> |
| 361 | + <value><struct> |
| 362 | + <member> |
| 363 | + <name>username</name> |
| 364 | + <value><string>demo</string></value> |
| 365 | + </member> |
| 366 | + </struct></value> |
| 367 | + </param> |
| 368 | + </params> |
| 369 | + </methodCall> |
| 370 | + """ |
| 371 | + translator = TranslationService.get_translation( |
| 372 | + language=self.instance.config["TRACKER_LANGUAGE"], |
| 373 | + tracker_home=self.instance.config["TRACKER_HOME"]) |
| 374 | + self.server = RoundupDispatcher(self.db, self.instance.actions, |
| 375 | + translator, allow_none = True) |
| 376 | + response = self.server.dispatch(bombInput) |
| 377 | + print(response) |
| 378 | + self.assertIn(expectIn, response) |
317 | 379 |
|
318 | 380 | class anydbmXmlrpcTest(XmlrpcTest, unittest.TestCase): |
319 | 381 | backend = 'anydbm' |
|
0 commit comments