async def test_xss_with_strong_csp():
    persister = AsyncMock()
    request = Request("http://127.0.0.1:65081/strong_csp.php?content=Hello%20there")
    request.path_id = 42
    crawler = AsyncCrawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options, Event())
    module.do_post = False
    await module.attack(request)

    assert persister.add_payload.call_count
    assert _("Warning: Content-Security-Policy is present!") in persister.add_payload.call_args_list[0][1]["info"]
    await crawler.close()
async def test_title_false_positive():
    # We should fail at escaping the title tag and we should be aware of it
    persister = AsyncMock()
    request = Request("http://127.0.0.1:65081/title_false_positive.php?title=yolo&fixed=yes")
    request.path_id = 42
    crawler = AsyncCrawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options, Event())
    module.do_post = False
    await module.attack(request)

    assert not persister.add_payload.call_count
    await crawler.close()
def test_title_false_positive():
    # We should fail at escaping the title tag and we should be aware of it
    persister = FakePersister()
    request = Request(
        "http://127.0.0.1:65081/title_false_positive.php?title=yolo&fixed=yes")
    request.path_id = 42
    crawler = Crawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options)
    module.do_post = False
    module.attack(request)

    assert persister.vulnerabilities == []
def test_bad_separator_used():
    persister = FakePersister()
    request = Request("http://127.0.0.1:65081/confuse_separator.php?number=42")
    request.path_id = 42
    crawler = Crawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options)
    module.do_post = False
    module.attack(request)

    assert persister.vulnerabilities
    used_payload = persister.vulnerabilities[0][1].lower()
    assert used_payload.startswith("\">")
async def test_rare_tag_and_event():
    persister = AsyncMock()
    request = Request("http://127.0.0.1:65081/filter_common_keywords.php?msg=test")
    request.path_id = 42
    crawler = AsyncCrawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options, Event())
    module.do_post = False
    await module.attack(request)

    assert persister.add_payload.call_count
    used_payload = persister.add_payload.call_args_list[0][1]["request"].get_params[0][1].lower()
    assert used_payload.startswith("<custom\nchecked\nonpointerenter=")
    await crawler.close()
async def test_escape_with_style():
    persister = AsyncMock()
    request = Request("http://127.0.0.1:65081/escape_with_style.php?color=green")
    request.path_id = 42
    crawler = AsyncCrawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options, Event())
    module.do_post = False
    await module.attack(request)

    assert persister.add_payload.call_count
    used_payload = persister.add_payload.call_args_list[0][1]["request"].get_params[0][1].lower()
    assert used_payload.startswith("</style>")
    await crawler.close()
async def test_bad_separator_used():
    persister = AsyncMock()
    request = Request("http://127.0.0.1:65081/confuse_separator.php?number=42")
    request.path_id = 42
    crawler = AsyncCrawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options, Event())
    module.do_post = False
    await module.attack(request)

    assert persister.add_payload.call_count
    used_payload = persister.add_payload.call_args_list[0][1]["request"].get_params[0][1].lower()
    assert used_payload.startswith("\">")
    await crawler.close()
def test_rare_tag_and_event():
    persister = FakePersister()
    request = Request(
        "http://127.0.0.1:65081/filter_common_keywords.php?msg=test")
    request.path_id = 42
    crawler = Crawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options)
    module.do_post = False
    module.attack(request)

    assert persister.vulnerabilities
    used_payload = persister.vulnerabilities[0][1].lower()
    assert used_payload.startswith("<custom\nchecked\nonpointerenter=")
def test_attr_escape():
    # We should succeed at closing the attribute value and the opening tag
    persister = FakePersister()
    request = Request("http://127.0.0.1:65081/attr_escape.php?state=checked")
    request.path_id = 42
    crawler = Crawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options)
    module.do_post = False
    module.attack(request)

    assert persister.vulnerabilities
    assert persister.vulnerabilities[0][0] == "state"
    assert persister.vulnerabilities[0][1].lower().startswith("><script>")
def test_xss_with_weak_csp():
    persister = FakePersister()
    request = Request(
        "http://127.0.0.1:65081/weak_csp.php?content=Hello%20there")
    request.path_id = 42
    crawler = Crawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options)
    module.do_post = False
    module.attack(request)

    assert persister.vulnerabilities
    assert _("Warning: Content-Security-Policy is present!"
             ) not in persister.vulnerabilities[0][2]
def test_escape_with_style():
    persister = FakePersister()
    request = Request(
        "http://127.0.0.1:65081/escape_with_style.php?color=green")
    request.path_id = 42
    crawler = Crawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options)
    module.do_post = False
    module.attack(request)

    assert persister.vulnerabilities
    used_payload = persister.vulnerabilities[0][1].lower()
    assert used_payload.startswith("</style>")
def test_xss_inside_tag_input():
    persister = FakePersister()
    request = Request("http://127.0.0.1:65081/input_text_strip_tags.php?uid=5")
    request.path_id = 42
    crawler = Crawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options)
    module.do_post = False
    module.attack(request)

    assert persister.vulnerabilities
    assert persister.vulnerabilities[0][0] == "uid"
    used_payload = persister.vulnerabilities[0][1].lower()
    assert "<" not in used_payload and ">" not in used_payload and "autofocus/onfocus" in used_payload
示例#13
0
async def test_xss_uppercase_no_script():
    persister = AsyncMock()
    request = Request("http://127.0.0.1:65081/uppercase_no_script.php?name=obiwan")
    request.path_id = 42
    crawler = AsyncCrawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options, Event())
    module.do_post = False
    await module.attack(request)

    assert persister.add_payload.call_count
    assert persister.add_payload.call_args_list[0][1]["parameter"] == "name"
    used_payload = persister.add_payload.call_args_list[0][1]["request"].get_params[0][1].lower()
    assert used_payload.startswith("<svg onload=&")
    await crawler.close()
示例#14
0
async def test_frame_src_no_escape():
    persister = AsyncMock()
    request = Request("http://127.0.0.1:65081/frame_src_no_escape.php?url=https://wapiti.sourceforge.io/")
    request.path_id = 42
    crawler = AsyncCrawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options, Event())
    module.do_post = False
    await module.attack(request)

    assert persister.add_payload.call_count
    assert persister.add_payload.call_args_list[0][1]["parameter"] == "url"
    used_payload = persister.add_payload.call_args_list[0][1]["request"].get_params[0][1].lower()
    assert used_payload.startswith("javascript:alert(/w")
    await crawler.close()
def test_script_filter_bypass():
    # We should succeed at bypass the <script filter
    persister = FakePersister()
    request = Request(
        "http://127.0.0.1:65081/script_tag_filter.php?name=kenobi")
    request.path_id = 42
    crawler = Crawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options)
    module.do_post = False
    module.attack(request)

    assert persister.vulnerabilities
    assert persister.vulnerabilities[0][0] == "name"
    assert persister.vulnerabilities[0][1].lower().startswith("<svg")
示例#16
0
async def test_attr_quote_escape():
    # We should succeed at closing the attribute value and the opening tag
    persister = AsyncMock()
    request = Request("http://127.0.0.1:65081/attr_quote_escape.php?class=custom")
    request.path_id = 42
    crawler = AsyncCrawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options, Event())
    module.do_post = False
    await module.attack(request)

    assert persister.add_payload.call_count
    assert persister.add_payload.call_args_list[0][1]["parameter"] == "class"
    assert persister.add_payload.call_args_list[0][1]["request"].get_params[0][1].lower().startswith("'></pre>")
    await crawler.close()
示例#17
0
async def test_script_filter_bypass():
    # We should succeed at bypass the <script filter
    persister = AsyncMock()
    request = Request("http://127.0.0.1:65081/script_tag_filter.php?name=kenobi")
    request.path_id = 42
    crawler = AsyncCrawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options, Event())
    module.do_post = False
    await module.attack(request)

    assert persister.add_payload.call_count
    assert persister.add_payload.call_args_list[0][1]["parameter"] == "name"
    assert persister.add_payload.call_args_list[0][1]["request"].get_params[0][1].lower().startswith("<svg")
    await crawler.close()
示例#18
0
async def test_xss_inside_tag_link():
    persister = AsyncMock()
    request = Request("http://127.0.0.1:65081/link_href_strip_tags.php?url=http://perdu.com/")
    request.path_id = 42
    crawler = AsyncCrawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options, Event())
    module.do_post = False
    await module.attack(request)

    assert persister.add_payload.call_count
    assert persister.add_payload.call_args_list[0][1]["parameter"] == "url"
    used_payload = persister.add_payload.call_args_list[0][1]["request"].get_params[0][1].lower()
    assert "<" not in used_payload and ">" not in used_payload and "autofocus href onfocus" in used_payload
    await crawler.close()
def test_xss_uppercase_no_script():
    persister = FakePersister()
    request = Request(
        "http://127.0.0.1:65081/uppercase_no_script.php?name=obiwan")
    request.path_id = 42
    crawler = Crawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options)
    module.do_post = False
    module.attack(request)

    assert persister.vulnerabilities
    assert persister.vulnerabilities[0][0] == "name"
    used_payload = persister.vulnerabilities[0][1].lower()
    assert used_payload.startswith("<svg onload=&")
示例#20
0
def test_title_positive():
    # We should succeed at escaping the title tag
    persister = FakePersister()
    request = Request("http://127.0.0.1:65081/title_false_positive.php?title=yolo")
    request.path_id = 42
    persister.requests.append(request)
    crawler = Crawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options)
    module.do_post = False
    for __ in module.attack():
        pass

    assert persister.vulnerabilities
    assert persister.vulnerabilities[0][0] == "title"
    assert persister.vulnerabilities[0][1].startswith("</title>")
示例#21
0
def test_tag_name_escape():
    # We should succeed at closing the attribute value and the opening tag
    persister = FakePersister()
    request = Request("http://127.0.0.1:65081/tag_name_escape.php?tag=textarea")
    request.path_id = 42
    persister.requests.append(request)
    crawler = Crawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options)
    module.do_post = False
    for __ in module.attack():
        pass

    assert persister.vulnerabilities
    assert persister.vulnerabilities[0][0] == "tag"
    assert persister.vulnerabilities[0][1].lower().startswith("script>")
示例#22
0
def test_xss_inside_tag_link():
    persister = FakePersister()
    request = Request("http://127.0.0.1:65081/link_href_strip_tags.php?url=http://perdu.com/")
    request.path_id = 42
    persister.requests.append(request)
    crawler = Crawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options)
    module.do_post = False
    for __ in module.attack():
        pass

    assert persister.vulnerabilities
    assert persister.vulnerabilities[0][0] == "url"
    used_payload = persister.vulnerabilities[0][1].lower()
    assert "<" not in used_payload and ">" not in used_payload and "autofocus href onfocus" in used_payload
def test_frame_src_no_escape():
    persister = FakePersister()
    request = Request(
        "http://127.0.0.1:65081/frame_src_no_escape.php?url=https://wapiti.sourceforge.io/"
    )
    request.path_id = 42
    crawler = Crawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options)
    module.do_post = False
    module.attack(request)

    assert persister.vulnerabilities
    assert persister.vulnerabilities[0][0] == "url"
    used_payload = persister.vulnerabilities[0][1].lower()
    assert used_payload.startswith("javascript:alert(/w")
示例#24
0
async def test_attr_double_quote_escape():
    # We should succeed at closing the attribute value and the opening tag
    persister = FakePersister()
    request = Request(
        "http://127.0.0.1:65081/attr_double_quote_escape.php?class=custom")
    request.path_id = 42
    crawler = AsyncCrawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options, Event())
    module.do_post = False
    await module.attack(request)

    assert persister.vulnerabilities
    assert persister.vulnerabilities[0][0] == "class"
    assert persister.vulnerabilities[0][1].lower().startswith("\"></pre>")
    await crawler.close()
示例#25
0
async def test_partial_tag_name_escape():
    # We should succeed at closing the attribute value and the opening tag
    persister = FakePersister()
    request = Request(
        "http://127.0.0.1:65081/partial_tag_name_escape.php?importance=2")
    request.path_id = 42
    crawler = AsyncCrawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options, Event())
    module.do_post = False
    await module.attack(request)

    assert persister.vulnerabilities
    assert persister.vulnerabilities[0][0] == "importance"
    assert persister.vulnerabilities[0][1].lower().startswith("/><script>")
    await crawler.close()
def test_title_positive():
    # We should succeed at escaping the title tag
    persister = FakePersister()
    request = Request(
        "http://127.0.0.1:65081/title_false_positive.php?title=yolo")
    request.path_id = 42
    crawler = Crawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options)
    module.do_post = False
    module.attack(request)

    assert persister.vulnerabilities
    assert persister.vulnerabilities[0][0] == "title"
    assert persister.vulnerabilities[0][1].startswith("</title>")
    assert _("Warning: Content-Security-Policy is present!"
             ) not in persister.vulnerabilities[0][2]
示例#27
0
async def test_whole_stuff():
    # Test attacking all kind of parameter without crashing
    respx.get(url__regex=r"http://perdu\.com/.*").mock(
        return_value=httpx.Response(200, text="Hello there"))
    respx.post(url__regex=r"http://perdu\.com/.*").mock(
        return_value=httpx.Response(200, text="Hello there"))

    persister = AsyncMock()
    all_requests = []

    request = Request("http://perdu.com/")
    request.path_id = 1
    all_requests.append(request)

    request = Request("http://perdu.com/?foo=bar")
    request.path_id = 2
    all_requests.append(request)

    request = Request("http://perdu.com/?foo=bar",
                      post_params=[["a", "b"]],
                      file_params=[[
                          "file",
                          ("calendar.xml", "<xml>Hello there</xml",
                           "application/xml")
                      ]])
    request.path_id = 3
    all_requests.append(request)

    crawler = AsyncCrawler("http://perdu.com/", timeout=1)
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options, Event())
    module.verbose = 2
    module.do_post = True
    for request in all_requests:
        await module.attack(request)

    assert True
    await crawler.close()
示例#28
0
async def test_title_positive():
    # We should succeed at escaping the title tag
    persister = AsyncMock()
    request = Request("http://127.0.0.1:65081/title_false_positive.php?title=yolo")
    request.path_id = 42
    crawler = AsyncCrawler("http://127.0.0.1:65081/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options, Event())
    module.do_post = False
    await module.attack(request)

    assert persister.add_payload.call_count
    assert persister.add_payload.call_args_list[0][1]["module"] == "xss"
    assert persister.add_payload.call_args_list[0][1]["category"] == _("Cross Site Scripting")
    assert persister.add_payload.call_args_list[0][1]["parameter"] == "title"
    assert persister.add_payload.call_args_list[0][1]["request"].get_params[0][1].startswith("</title>")
    assert _(
        "Warning: Content-Security-Policy is present!"
    ) not in persister.add_payload.call_args_list[0][1]["info"]
    await crawler.close()
示例#29
0
def test_whole_stuff():
    # Test attacking all kind of parameter without crashing
    responses.add(responses.GET,
                  re.compile(r"http://perdu.com/"),
                  body="Hello there")

    responses.add(responses.POST,
                  re.compile(r"http://perdu.com/"),
                  body="Hello there")

    persister = FakePersister()

    request = Request("http://perdu.com/")
    request.path_id = 1
    persister.requests.append(request)

    request = Request("http://perdu.com/?foo=bar")
    request.path_id = 2
    persister.requests.append(request)

    request = Request(
        "http://perdu.com/?foo=bar",
        post_params=[["a", "b"]],
        file_params=[["file", ["calendar.xml", "<xml>Hello there</xml"]]])
    request.path_id = 3
    persister.requests.append(request)

    crawler = Crawler("http://perdu.com/", timeout=1)
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_xss(crawler, persister, logger, options)
    module.verbose = 2
    module.do_post = True
    for __ in module.attack():
        pass

    assert True