GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — sqlmap/tests/test_crawler.py at master · sqlmapproject/sqlmap

Expand file tree

/

test_crawler.py

Copy path
More file actions
More file actions

Latest commit

 

History

History
History
65 lines (48 loc) · 2.63 KB
/

test_crawler.py

Copy path

File metadata and controls

65 lines (48 loc) · 2.63 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
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
#!/usr/bin/env python
"""
Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
Crawler result normalization (lib/utils/crawler.py normalizeCrawlingResults).
--crawl can surface thousands of near-identical URLs; normalization keeps one
representative per distinct endpoint+parameter shape so the scan is not flooded
with value-only variants. The key must span the full path: collapsing on the
last path segment alone silently drops distinct endpoints that share an action
name (e.g. /users/edit vs /products/edit), losing real attack surface.
"""
import os
import sys
import unittest
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from _testutils import bootstrap
bootstrap()
from lib.utils.crawler import normalizeCrawlingResults
def _t(url, data=None):
# kb.targets tuple shape: (url, method, data, ...)
return (url, None, data, None, None)
class TestNormalizeCrawlingResults(unittest.TestCase):
def _urls(self, targets):
return [t[0] for t in normalizeCrawlingResults(targets)]
def test_value_only_variants_collapse(self):
kept = self._urls([_t("http://h/item?id=1"), _t("http://h/item?id=2"), _t("http://h/item?id=3")])
self.assertEqual(kept, ["http://h/item?id=1"])
def test_distinct_endpoints_sharing_action_are_kept(self):
# the regression: /users/edit and /products/edit must not collapse on the shared last segment
kept = self._urls([_t("http://h/users/edit?id=1"),
_t("http://h/products/edit?id=1"),
_t("http://h/orders/edit?id=1"),
_t("http://h/users/edit?id=2")])
self.assertEqual(set(kept), {"http://h/users/edit?id=1",
"http://h/products/edit?id=1",
"http://h/orders/edit?id=1"})
def test_different_parameter_names_are_kept(self):
kept = self._urls([_t("http://h/p?id=1"), _t("http://h/p?name=x")])
self.assertEqual(set(kept), {"http://h/p?id=1", "http://h/p?name=x"})
def test_different_hosts_are_kept(self):
kept = self._urls([_t("http://a.tld/edit?id=1"), _t("http://b.tld/edit?id=1")])
self.assertEqual(set(kept), {"http://a.tld/edit?id=1", "http://b.tld/edit?id=1"})
def test_post_data_folded_into_shape(self):
# POST body params participate in the shape, and value-only POST variants collapse
kept = self._urls([_t("http://h/login", "user=a&pass=b"), _t("http://h/login", "user=c&pass=d")])
self.assertEqual(kept, ["http://h/login"])
if __name__ == "__main__":
unittest.main(verbosity=2)
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.