Return a XSSDict if there is a XSS otherwise return None
(
body: str | bytes, request_URL: str, injection_point: str
)
| 337 | |
| 338 | |
| 339 | def get_XSS_data( |
| 340 | body: str | bytes, request_URL: str, injection_point: str |
| 341 | ) -> XSSData | None: |
| 342 | """Return a XSSDict if there is a XSS otherwise return None""" |
| 343 | |
| 344 | def in_script(text, index, body) -> bool: |
| 345 | """Whether the Numberth occurrence of the first string in the second |
| 346 | string is inside a script tag""" |
| 347 | paths = paths_to_text(body.decode("utf-8"), text.decode("utf-8")) |
| 348 | try: |
| 349 | path = paths[index] |
| 350 | return "script" in path |
| 351 | except IndexError: |
| 352 | return False |
| 353 | |
| 354 | def in_HTML(text: bytes, index: int, body: bytes) -> bool: |
| 355 | """Whether the Numberth occurrence of the first string in the second |
| 356 | string is inside the HTML but not inside a script tag or part of |
| 357 | a HTML attribute""" |
| 358 | # if there is a < then lxml will interpret that as a tag, so only search for the stuff before it |
| 359 | text = text.split(b"<")[0] |
| 360 | paths = paths_to_text(body.decode("utf-8"), text.decode("utf-8")) |
| 361 | try: |
| 362 | path = paths[index] |
| 363 | return "script" not in path |
| 364 | except IndexError: |
| 365 | return False |
| 366 | |
| 367 | def inject_javascript_handler(html: str) -> bool: |
| 368 | """Whether you can inject a Javascript:alert(0) as a link""" |
| 369 | |
| 370 | class injectJSHandlerHTMLParser(HTMLParser): |
| 371 | injectJSHandler = False |
| 372 | |
| 373 | def handle_starttag(self, tag, attrs): |
| 374 | for name, value in attrs: |
| 375 | if name == "href" and value.startswith(FRONT_WALL.decode("utf-8")): |
| 376 | self.injectJSHandler = True |
| 377 | |
| 378 | parser = injectJSHandlerHTMLParser() |
| 379 | parser.feed(html) |
| 380 | return parser.injectJSHandler |
| 381 | |
| 382 | # Only convert the body to bytes if needed |
| 383 | if isinstance(body, str): |
| 384 | body = bytes(body, "utf-8") |
| 385 | # Regex for between 24 and 72 (aka 24*3) characters encapsulated by the walls |
| 386 | regex = re.compile(b"""%s.{24,72}?%s""" % (FRONT_WALL, BACK_WALL)) |
| 387 | matches = regex.findall(body) |
| 388 | for index, match in enumerate(matches): |
| 389 | # Where the string is injected into the HTML |
| 390 | in_script_val = in_script(match, index, body) |
| 391 | in_HTML_val = in_HTML(match, index, body) |
| 392 | in_tag = not in_script_val and not in_HTML_val |
| 393 | in_single_quotes = inside_quote("'", match, index, body) |
| 394 | in_double_quotes = inside_quote('"', match, index, body) |
| 395 | # Whether you can inject: |
| 396 | inject_open_angle = b"ao<ac" in match # open angle brackets |
searching dependent graphs…