"""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"{u}" if isinstance(u, str) else "url" ) 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/", "http://example.com/?q=", "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), ]