File size: 4,467 Bytes
4815c43
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
"""Encoding / character issues (10 issues)."""

import numpy as np
import pandas as pd
from .base import Issue, pick_rows


def _sql_injection(df, rate, rng):
    df = df.copy()
    mask = pick_rows(df, rate, rng)
    payloads = [
        "'; DROP TABLE user_events; --",
        "1 OR 1=1",
        "' UNION SELECT * FROM users --",
        "admin'--",
        "\" OR \"1\"=\"1",
    ]
    df.loc[mask, "search_query"] = rng.choice(payloads, size=mask.sum())
    return df


def _html_tags(df, rate, rng):
    df = df.copy()
    mask = pick_rows(df, rate, rng)
    df.loc[mask, "page_url"] = df.loc[mask, "page_url"].apply(
        lambda u: f"<b>{u}</b>" if isinstance(u, str) else "<b>url</b>"
    )
    return df


def _emoji_in_event_type(df, rate, rng):
    df = df.copy()
    mask = pick_rows(df, rate, rng)
    emojis = ["click🖱️", "purchase🛒", "view👀", "login🔐", "search🔍"]
    df.loc[mask, "event_type"] = rng.choice(emojis, size=mask.sum())
    return df


def _null_bytes(df, rate, rng):
    df = df.copy()
    mask = pick_rows(df, rate, rng)
    df.loc[mask, "city"] = df.loc[mask, "city"].apply(
        lambda c: c + "\x00" if isinstance(c, str) else "\x00"
    )
    return df


def _very_long_string(df, rate, rng):
    df = df.copy()
    mask = pick_rows(df, rate, rng)
    df.loc[mask, "search_query"] = "A" * 10_001
    return df


def _control_characters(df, rate, rng):
    df = df.copy()
    mask = pick_rows(df, rate, rng)
    df.loc[mask, "city"] = df.loc[mask, "city"].apply(
        lambda c: c + "\x01\x02\x03" if isinstance(c, str) else "\x01\x02"
    )
    return df


def _unicode_special_chars(df, rate, rng):
    df = df.copy()
    mask = pick_rows(df, rate, rng)
    specials = [
        "\u200b",   # zero-width space
        "\u200f",   # right-to-left mark
        "\ufeff",   # BOM
        "\u202e",   # right-to-left override
        "\u0000",   # null
    ]
    df.loc[mask, "email"] = df.loc[mask, "email"].apply(
        lambda e: e + specials[0] if isinstance(e, str) else specials[0]
    )
    return df


def _xss_in_url(df, rate, rng):
    df = df.copy()
    mask = pick_rows(df, rate, rng)
    xss = [
        "http://example.com/<script>alert(1)</script>",
        "http://example.com/?q=<img src=x onerror=alert(1)>",
        "javascript:alert('xss')",
    ]
    df.loc[mask, "page_url"] = rng.choice(xss, size=mask.sum())
    return df


def _newlines_in_string(df, rate, rng):
    df = df.copy()
    mask = pick_rows(df, rate, rng)
    df.loc[mask, "city"] = df.loc[mask, "city"].apply(
        lambda c: c + "\nInjected\nLine" if isinstance(c, str) else "\nInjected"
    )
    return df


def _tabs_in_string(df, rate, rng):
    df = df.copy()
    mask = pick_rows(df, rate, rng)
    df.loc[mask, "city"] = df.loc[mask, "city"].apply(
        lambda c: c + "\t\tTabbed" if isinstance(c, str) else "\tTabbed"
    )
    return df


ISSUES = [
    Issue("sql_injection", "SQL injection in search_query", "encoding", "SQL injection payload in search_query field", "critical", 0.01, _sql_injection),
    Issue("html_tags", "HTML tags in page_url", "encoding", "Raw HTML tags injected into page_url field", "high", 0.02, _html_tags),
    Issue("emoji_in_event_type", "Emoji characters in event_type", "encoding", "event_type contains emoji characters", "medium", 0.02, _emoji_in_event_type),
    Issue("null_bytes", "Null bytes in city field", "encoding", "city contains \\x00 null byte characters", "high", 0.02, _null_bytes),
    Issue("very_long_string", "String field > 10,000 characters", "encoding", "search_query contains 10,001+ character string", "medium", 0.01, _very_long_string),
    Issue("control_characters", "Control characters in city", "encoding", "city contains ASCII control characters \\x01-\\x1f", "medium", 0.02, _control_characters),
    Issue("unicode_special_chars", "Zero-width / invisible unicode in email", "encoding", "email contains invisible unicode chars (BOM, RTL mark)", "medium", 0.02, _unicode_special_chars),
    Issue("xss_in_url", "XSS script tag in page_url", "encoding", "page_url contains JavaScript injection payload", "critical", 0.01, _xss_in_url),
    Issue("newlines_in_string", "Newline characters in city", "encoding", "city field contains embedded newline characters", "medium", 0.02, _newlines_in_string),
    Issue("tabs_in_string", "Tab characters in city", "encoding", "city field contains embedded tab characters", "low", 0.02, _tabs_in_string),
]