mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2026-06-20 14:40:36 +00:00
76 lines
2.6 KiB
Python
76 lines
2.6 KiB
Python
#!/usr/bin/env python
|
|
|
|
"""
|
|
Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
|
|
See the file 'LICENSE' for copying permission
|
|
|
|
Assorted request-shaping helpers in lib/core/common.py:
|
|
chunkSplitPostData (HTTP chunked-transfer evasion), randomizeParameterValue
|
|
(tamper/cache-buster), getHostHeader (Host header derivation).
|
|
|
|
chunkSplitPostData uses random chunk sizes, so its output is asserted
|
|
structurally (reassembles to the original, terminates correctly) rather than
|
|
byte-for-byte; randomizeParameterValue is asserted via its invariants.
|
|
"""
|
|
|
|
import os
|
|
import re
|
|
import sys
|
|
import unittest
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
from _testutils import bootstrap
|
|
bootstrap()
|
|
|
|
from lib.core.common import chunkSplitPostData, randomizeParameterValue, getHostHeader
|
|
|
|
|
|
def _dechunk(data):
|
|
"""Reassemble an HTTP/1.1 chunked body back into its payload."""
|
|
out = []
|
|
i = 0
|
|
while i < len(data):
|
|
nl = data.index("\r\n", i)
|
|
size = int(data[i:nl].split(";")[0], 16) # size; optional chunk-extension
|
|
start = nl + 2
|
|
out.append(data[start:start + size])
|
|
i = start + size + 2 # skip chunk data + trailing CRLF
|
|
if size == 0:
|
|
break
|
|
return "".join(out)
|
|
|
|
|
|
class TestChunkSplit(unittest.TestCase):
|
|
def test_reassembles_to_original(self):
|
|
for payload in ("a=1&b=2", "x" * 50, "single=value", ""):
|
|
self.assertEqual(_dechunk(chunkSplitPostData(payload)), payload,
|
|
msg="chunk reassembly failed for %r" % payload)
|
|
|
|
def test_terminates_with_zero_chunk(self):
|
|
self.assertTrue(chunkSplitPostData("a=1&b=2").endswith("0\r\n\r\n"))
|
|
|
|
|
|
class TestRandomizeParameterValue(unittest.TestCase):
|
|
def test_length_preserved(self):
|
|
for v in ("abc123", "value", "42", "MixedCASE99"):
|
|
self.assertEqual(len(randomizeParameterValue(v)), len(v), msg="length changed for %r" % v)
|
|
|
|
def test_char_class_preserved(self):
|
|
# letters stay letters, digits stay digits (positionally)
|
|
src = "abc123XYZ789"
|
|
out = randomizeParameterValue(src)
|
|
for a, b in zip(src, out):
|
|
self.assertEqual(a.isdigit(), b.isdigit(), msg="char class changed: %r -> %r" % (a, b))
|
|
self.assertEqual(a.isalpha(), b.isalpha(), msg="char class changed: %r -> %r" % (a, b))
|
|
|
|
|
|
class TestGetHostHeader(unittest.TestCase):
|
|
def test_with_port(self):
|
|
self.assertEqual(getHostHeader("http://h:8080/p"), "h:8080")
|
|
|
|
def test_without_port(self):
|
|
self.assertEqual(getHostHeader("http://example.com/path"), "example.com")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main(verbosity=2)
|