"""Tests for the PayloadGenerator module.""" import urllib.parse import pytest from intelliscan.modules.payload_gen import PayloadGenerator def test_generate_includes_original(): gen = PayloadGenerator() variants = gen.generate("' OR 1=1-- ", "sqli") assert "' OR 1=1-- " in variants def test_url_encoding_applied(): gen = PayloadGenerator() variants = gen.generate("' OR 1=1-- ", "sqli") encoded = urllib.parse.quote("' OR 1=1-- ", safe="") assert encoded in variants def test_double_url_encoding_applied(): gen = PayloadGenerator() variants = gen.generate("' OR 1=1-- ", "sqli") once = urllib.parse.quote("' OR 1=1-- ", safe="") twice = urllib.parse.quote(once, safe="") assert twice in variants def test_comment_insertion_only_for_sqli(): gen = PayloadGenerator() variants_sqli = gen.generate("' OR 1=1-- ", "sqli") variants_xss = gen.generate("", "xss") assert any("/**/" in v for v in variants_sqli) assert not any("/**/" in v for v in variants_xss) def test_html_entity_encode_only_for_xss(): """HTML entity encoding applies to XSS payloads, not SQLi or LFI.""" gen = PayloadGenerator() xss_variants = gen.generate("", "xss") sqli_variants = gen.generate("' OR 1=1-- ", "sqli") assert any("<" in v for v in xss_variants) assert not any("<" in v for v in sqli_variants) def test_whitespace_variation_produces_tab_and_comment(): gen = PayloadGenerator() variants = gen.generate("SELECT * FROM users", "sqli") assert any("\t" in v for v in variants) assert any("/**/" in v for v in variants) def test_lfi_skips_case_mutation(): """Unix paths are case-sensitive; case mutation should not apply to LFI.""" gen = PayloadGenerator() variants = gen.generate("/etc/passwd", "lfi") case_mutated = [v for v in variants if v != v.lower() and v != v.upper()] for v in case_mutated: assert "%" in v def test_generate_all_deduplicates(): gen = PayloadGenerator() base = ["' OR 1=1-- ", "' OR 1=1-- "] out = gen.generate_all(base, "sqli") assert len(out) == len(set(out)) def test_generate_increases_payload_count(): gen = PayloadGenerator() base = ["' OR 1=1-- "] out = gen.generate_all(base, "sqli") assert len(out) > len(base) def test_record_feedback_and_technique_stats(): gen = PayloadGenerator() for _ in range(10): gen.record_feedback("url_encode", detected=True) stats = gen.technique_stats() assert stats["url_encode"]["block_rate"] == pytest.approx(1.0) assert stats["url_encode"]["total"] == 10 def test_adaptive_skips_high_block_rate_technique(): """Technique with >80% block rate and >=5 samples is excluded.""" gen = PayloadGenerator() for _ in range(6): gen.record_feedback("url_encode", detected=True) skipped = gen._skipped_techniques() assert "url_encode" in skipped