proxy2model 2.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. proxy2model/__init__.py +19 -0
  2. proxy2model/__main__.py +6 -0
  3. proxy2model/atomic.py +68 -0
  4. proxy2model/cli/__init__.py +3 -0
  5. proxy2model/cli/analyze.py +501 -0
  6. proxy2model/cli/app.py +408 -0
  7. proxy2model/cli/browse.py +279 -0
  8. proxy2model/cli/build.py +399 -0
  9. proxy2model/cli/common.py +190 -0
  10. proxy2model/cli/history.py +224 -0
  11. proxy2model/cli/mcp.py +184 -0
  12. proxy2model/cli/ui.py +62 -0
  13. proxy2model/core/__init__.py +1 -0
  14. proxy2model/core/changes.py +124 -0
  15. proxy2model/core/context.py +571 -0
  16. proxy2model/core/diff.py +330 -0
  17. proxy2model/core/domains.py +98 -0
  18. proxy2model/core/graph.py +562 -0
  19. proxy2model/core/methodology.py +343 -0
  20. proxy2model/core/model.py +998 -0
  21. proxy2model/core/stack.py +218 -0
  22. proxy2model/data/fonts/LICENSES.md +16 -0
  23. proxy2model/data/fonts/inter-latin-wght-normal.woff2 +0 -0
  24. proxy2model/data/fonts/jetbrains-mono-latin-wght-normal.woff2 +0 -0
  25. proxy2model/data/fonts/nippo-200.woff2 +0 -0
  26. proxy2model/data/fonts/nippo-300.woff2 +0 -0
  27. proxy2model/data/fonts/nippo-400.woff2 +0 -0
  28. proxy2model/data/fonts/nippo-500.woff2 +0 -0
  29. proxy2model/data/fonts/nippo-700.woff2 +0 -0
  30. proxy2model/data/public_suffix_list.dat +16497 -0
  31. proxy2model/db/__init__.py +1 -0
  32. proxy2model/db/bql.py +710 -0
  33. proxy2model/db/bql_js.py +278 -0
  34. proxy2model/db/store.py +547 -0
  35. proxy2model/export/__init__.py +1 -0
  36. proxy2model/export/openapi.py +248 -0
  37. proxy2model/ingest/__init__.py +1 -0
  38. proxy2model/ingest/browse.py +181 -0
  39. proxy2model/ingest/browser.py +1058 -0
  40. proxy2model/ingest/crawl.py +673 -0
  41. proxy2model/ingest/extract.py +208 -0
  42. proxy2model/ingest/infer.py +75 -0
  43. proxy2model/ingest/journey.py +148 -0
  44. proxy2model/ingest/live.py +96 -0
  45. proxy2model/ingest/parse.py +1275 -0
  46. proxy2model/ingest/redact.py +535 -0
  47. proxy2model/py.typed +0 -0
  48. proxy2model/recon/__init__.py +1 -0
  49. proxy2model/recon/osint.py +607 -0
  50. proxy2model/report/__init__.py +1 -0
  51. proxy2model/report/animate.py +163 -0
  52. proxy2model/report/dash.py +469 -0
  53. proxy2model/report/fonts.py +51 -0
  54. proxy2model/report/html.py +988 -0
  55. proxy2model/report/inventory.py +258 -0
  56. proxy2model/report/map.py +515 -0
  57. proxy2model/report/pages.py +537 -0
  58. proxy2model/report/query.py +306 -0
  59. proxy2model/report/shot.py +55 -0
  60. proxy2model/report/view.py +213 -0
  61. proxy2model-2.0.0.dist-info/METADATA +148 -0
  62. proxy2model-2.0.0.dist-info/RECORD +66 -0
  63. proxy2model-2.0.0.dist-info/WHEEL +5 -0
  64. proxy2model-2.0.0.dist-info/entry_points.txt +2 -0
  65. proxy2model-2.0.0.dist-info/licenses/LICENSE +201 -0
  66. proxy2model-2.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,218 @@
1
+ """What an app is built on, read from the capture: servers, frameworks, CDNs and third-party services.
2
+
3
+ Every entry is a hint tied to the requests that showed it, never a version scan. Signatures are
4
+ deliberately few and conservative. Detection runs per response while parsing (headers, cookie names,
5
+ HTML and script markers), and third-party hosts are matched to vendors when the model is built.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import re
11
+
12
+ # column order for the stack map
13
+ CATEGORIES = ["Edge & CDN", "Web server", "Language & framework", "Frontend", "CMS & platform",
14
+ "API", "Services"]
15
+
16
+ # (header, regex on its value, name, category); the capture group, if any, is the version
17
+ _HEADER_SIGNS = [
18
+ ("server", r"cloudflare", "Cloudflare", "Edge & CDN"),
19
+ ("server", r"akamaighost|akamai", "Akamai", "Edge & CDN"),
20
+ ("server", r"cloudfront", "Amazon CloudFront", "Edge & CDN"),
21
+ ("server", r"\bfastly\b", "Fastly", "Edge & CDN"),
22
+ ("server", r"netlify", "Netlify", "Edge & CDN"),
23
+ ("server", r"vercel", "Vercel", "Edge & CDN"),
24
+ ("server", r"sucuri", "Sucuri", "Edge & CDN"),
25
+ ("server", r"nginx(?:/([\d.]+))?", "nginx", "Web server"),
26
+ ("server", r"apache(?:/([\d.]+))?", "Apache", "Web server"),
27
+ ("server", r"microsoft-iis(?:/([\d.]+))?", "IIS", "Web server"),
28
+ ("server", r"openresty(?:/([\d.]+))?", "OpenResty", "Web server"),
29
+ ("server", r"litespeed", "LiteSpeed", "Web server"),
30
+ ("server", r"caddy", "Caddy", "Web server"),
31
+ ("server", r"gunicorn(?:/([\d.]+))?", "Gunicorn", "Web server"),
32
+ ("server", r"uvicorn", "Uvicorn", "Web server"),
33
+ ("server", r"kestrel", "Kestrel", "Web server"),
34
+ ("server", r"envoy", "Envoy", "Web server"),
35
+ ("server", r"jetty(?:\(?([\d.]+))?", "Jetty", "Web server"),
36
+ ("server", r"tomcat", "Apache Tomcat", "Web server"),
37
+ ("server", r"\bcowboy\b", "Cowboy", "Web server"),
38
+ ("server", r"werkzeug(?:/([\d.]+))?", "Werkzeug", "Web server"),
39
+ ("server", r"phusion passenger", "Passenger", "Web server"),
40
+ ("server", r"\bgws\b|\besf\b", "Google Frontend", "Edge & CDN"),
41
+ ("server", r"amazons3", "Amazon S3", "Edge & CDN"),
42
+ ("x-powered-by", r"php(?:/([\d.]+))?", "PHP", "Language & framework"),
43
+ ("x-powered-by", r"express", "Express", "Language & framework"),
44
+ ("x-powered-by", r"asp\.net", "ASP.NET", "Language & framework"),
45
+ ("x-powered-by", r"next\.js(?: ([\d.]+))?", "Next.js", "Language & framework"),
46
+ ("x-powered-by", r"servlet|jsp", "Java Servlet", "Language & framework"),
47
+ ("x-powered-by", r"phusion passenger", "Passenger", "Web server"),
48
+ ("x-powered-by", r"django", "Django", "Language & framework"),
49
+ ("x-powered-by", r"flask", "Flask", "Language & framework"),
50
+ ("x-powered-by", r"wp engine", "WP Engine", "CMS & platform"),
51
+ ("x-aspnet-version", r"([\d.]+)", "ASP.NET", "Language & framework"),
52
+ ("x-aspnetmvc-version", r"([\d.]+)", "ASP.NET MVC", "Language & framework"),
53
+ ("x-generator", r"drupal(?: ([\d.]+))?", "Drupal", "CMS & platform"),
54
+ ("x-generator", r"wordpress(?: ([\d.]+))?", "WordPress", "CMS & platform"),
55
+ ("x-generator", r"joomla", "Joomla", "CMS & platform"),
56
+ ("x-drupal-cache", r".", "Drupal", "CMS & platform"),
57
+ ("x-shopify-stage", r".", "Shopify", "CMS & platform"),
58
+ ("x-wix-request-id", r".", "Wix", "CMS & platform"),
59
+ ("x-vercel-id", r".", "Vercel", "Edge & CDN"),
60
+ ("x-nf-request-id", r".", "Netlify", "Edge & CDN"),
61
+ ("cf-ray", r".", "Cloudflare", "Edge & CDN"),
62
+ ("x-amz-cf-id", r".", "Amazon CloudFront", "Edge & CDN"),
63
+ ("x-akamai-transformed", r".", "Akamai", "Edge & CDN"),
64
+ ("x-azure-ref", r".", "Azure Front Door", "Edge & CDN"),
65
+ ("x-fastly-request-id", r".", "Fastly", "Edge & CDN"),
66
+ ("x-github-request-id", r".", "GitHub Pages", "Edge & CDN"),
67
+ ("x-sucuri-id", r".", "Sucuri", "Edge & CDN"),
68
+ ("x-served-by", r"cache-", "Fastly", "Edge & CDN"),
69
+ ("via", r"varnish", "Varnish", "Edge & CDN"),
70
+ ("via", r"cloudfront", "Amazon CloudFront", "Edge & CDN"),
71
+ ]
72
+
73
+ # cookie name patterns -> technology
74
+ _COOKIE_SIGNS = [
75
+ (r"^PHPSESSID$", "PHP", "Language & framework"),
76
+ (r"^JSESSIONID$", "Java", "Language & framework"),
77
+ (r"^ASP\.NET_SessionId$|^\.ASPXAUTH$", "ASP.NET", "Language & framework"),
78
+ (r"^laravel_session$", "Laravel", "Language & framework"),
79
+ (r"^csrftoken$|^django_language$", "Django", "Language & framework"),
80
+ (r"^connect\.sid$", "Express", "Language & framework"),
81
+ (r"^rack\.session$", "Rack", "Language & framework"),
82
+ (r"^_rails|^_session_id$", "Ruby on Rails", "Language & framework"),
83
+ (r"^wordpress_|^wp-settings", "WordPress", "CMS & platform"),
84
+ (r"^_shopify_", "Shopify", "CMS & platform"),
85
+ (r"^__cf_bm$|^cf_clearance$|^__cfduid$", "Cloudflare", "Edge & CDN"),
86
+ (r"^AWSALB|^AWSELB", "AWS Load Balancer", "Edge & CDN"),
87
+ (r"^BIGipServer|^TS[0-9a-f]{8}", "F5 BIG-IP", "Edge & CDN"),
88
+ (r"^NSC_", "Citrix NetScaler", "Edge & CDN"),
89
+ (r"^incap_ses|^visid_incap", "Imperva", "Edge & CDN"),
90
+ (r"^ak_bmsc$|^bm_sz$", "Akamai", "Edge & CDN"),
91
+ ]
92
+
93
+ # markers in HTML and script bodies -> technology (version from the first group when present)
94
+ _BODY_SIGNS = [
95
+ (r"/_next/static/|__NEXT_DATA__", "Next.js", "Language & framework"),
96
+ (r"window\.__NUXT__|/_nuxt/", "Nuxt", "Language & framework"),
97
+ (r"ng-version=\"([\d.]+)\"", "Angular", "Frontend"),
98
+ (r"<app-root|@angular/core", "Angular", "Frontend"),
99
+ (r"data-reactroot|__REACT_DEVTOOLS_GLOBAL_HOOK__|react-dom", "React", "Frontend"),
100
+ (r"data-v-[0-9a-f]{8}|vue(?:\.runtime)?(?:\.min)?\.js|__vue__", "Vue", "Frontend"),
101
+ (r"svelte-[a-z0-9]{5,}|__svelte", "Svelte", "Frontend"),
102
+ (r"jquery[-.]?([\d.]+\d)?(?:\.min)?\.js", "jQuery", "Frontend"),
103
+ (r"bootstrap[-.]?([\d.]+\d)?(?:\.bundle)?(?:\.min)?\.(?:js|css)", "Bootstrap", "Frontend"),
104
+ (r"webpackJsonp|webpackChunk|__webpack_require__", "Webpack", "Frontend"),
105
+ (r"/@vite/client|vite/modulepreload", "Vite", "Frontend"),
106
+ (r"wp-content/|wp-includes/", "WordPress", "CMS & platform"),
107
+ (r"/sites/default/files|Drupal\.settings", "Drupal", "CMS & platform"),
108
+ (r"cdn\.shopify\.com", "Shopify", "CMS & platform"),
109
+ (r"static\.parastorage\.com|wixstatic\.com", "Wix", "CMS & platform"),
110
+ (r"static1\.squarespace\.com", "Squarespace", "CMS & platform"),
111
+ (r"assets\.website-files\.com|webflow\.js", "Webflow", "CMS & platform"),
112
+ (r"socket\.io", "Socket.IO", "API"),
113
+ ]
114
+
115
+ _GENERATOR = re.compile(r"""<meta[^>]+name=["']generator["'][^>]+content=["']([^"']+)""", re.I)
116
+ _PATH_SIGNS = [
117
+ (r"/graphql\b", "GraphQL", "API"),
118
+ (r"/socket\.io/", "Socket.IO", "API"),
119
+ (r"/signalr\b", "SignalR", "API"),
120
+ ]
121
+
122
+ # third-party hosts (suffix match) -> (vendor, kind)
123
+ _VENDORS = [
124
+ ("google-analytics.com", "Google Analytics", "Analytics"), ("googletagmanager.com", "Google Tag Manager", "Analytics"),
125
+ ("doubleclick.net", "Google Ads", "Advertising"), ("googlesyndication.com", "Google Ads", "Advertising"),
126
+ ("connect.facebook.net", "Meta Pixel", "Advertising"), ("facebook.com", "Meta", "Advertising"),
127
+ ("hotjar.com", "Hotjar", "Analytics"), ("segment.io", "Segment", "Analytics"), ("segment.com", "Segment", "Analytics"),
128
+ ("mixpanel.com", "Mixpanel", "Analytics"), ("amplitude.com", "Amplitude", "Analytics"), ("fullstory.com", "FullStory", "Analytics"),
129
+ ("clarity.ms", "Microsoft Clarity", "Analytics"), ("heap.io", "Heap", "Analytics"), ("plausible.io", "Plausible", "Analytics"),
130
+ ("stripe.com", "Stripe", "Payments"), ("stripe.network", "Stripe", "Payments"), ("paypal.com", "PayPal", "Payments"),
131
+ ("paypalobjects.com", "PayPal", "Payments"), ("braintreegateway.com", "Braintree", "Payments"), ("adyen.com", "Adyen", "Payments"),
132
+ ("razorpay.com", "Razorpay", "Payments"), ("checkout.com", "Checkout.com", "Payments"),
133
+ ("intercom.io", "Intercom", "Support"), ("intercomcdn.com", "Intercom", "Support"), ("zendesk.com", "Zendesk", "Support"),
134
+ ("zdassets.com", "Zendesk", "Support"), ("crisp.chat", "Crisp", "Support"), ("drift.com", "Drift", "Support"),
135
+ ("tawk.to", "Tawk.to", "Support"), ("hubspot.com", "HubSpot", "Marketing"), ("hs-scripts.com", "HubSpot", "Marketing"),
136
+ ("sentry.io", "Sentry", "Monitoring"), ("sentry-cdn.com", "Sentry", "Monitoring"), ("datadoghq.com", "Datadog", "Monitoring"),
137
+ ("newrelic.com", "New Relic", "Monitoring"), ("nr-data.net", "New Relic", "Monitoring"), ("bugsnag.com", "Bugsnag", "Monitoring"),
138
+ ("rollbar.com", "Rollbar", "Monitoring"), ("logrocket.com", "LogRocket", "Monitoring"),
139
+ ("auth0.com", "Auth0", "Identity"), ("okta.com", "Okta", "Identity"), ("amazoncognito.com", "AWS Cognito", "Identity"),
140
+ ("firebaseapp.com", "Firebase", "Identity"), ("firebaseio.com", "Firebase", "Identity"), ("clerk.com", "Clerk", "Identity"),
141
+ ("hcaptcha.com", "hCaptcha", "Bot protection"), ("challenges.cloudflare.com", "Cloudflare Turnstile", "Bot protection"),
142
+ ("fonts.googleapis.com", "Google Fonts", "Assets"), ("fonts.gstatic.com", "Google Fonts", "Assets"),
143
+ ("use.fontawesome.com", "Font Awesome", "Assets"), ("kit.fontawesome.com", "Font Awesome", "Assets"),
144
+ ("cdnjs.cloudflare.com", "cdnjs", "Assets"), ("cdn.jsdelivr.net", "jsDelivr", "Assets"), ("unpkg.com", "unpkg", "Assets"),
145
+ ("ajax.googleapis.com", "Google Hosted Libraries", "Assets"), ("cloudinary.com", "Cloudinary", "Assets"), ("imgix.net", "imgix", "Assets"),
146
+ ("youtube.com", "YouTube", "Media"), ("ytimg.com", "YouTube", "Media"), ("vimeo.com", "Vimeo", "Media"),
147
+ ("maps.googleapis.com", "Google Maps", "Maps"), ("mapbox.com", "Mapbox", "Maps"),
148
+ ("algolia.net", "Algolia", "Search"), ("algolianet.com", "Algolia", "Search"),
149
+ ("cookiebot.com", "Cookiebot", "Consent"), ("onetrust.com", "OneTrust", "Consent"), ("cookielaw.org", "OneTrust", "Consent"),
150
+ ("optimizely.com", "Optimizely", "Experiments"), ("launchdarkly.com", "LaunchDarkly", "Experiments"),
151
+ ("azureedge.net", "Azure CDN", "Edge & CDN"), ("akamaihd.net", "Akamai", "Edge & CDN"), ("fastly.net", "Fastly", "Edge & CDN"),
152
+ ("b-cdn.net", "Bunny CDN", "Edge & CDN"), ("cloudfront.net", "Amazon CloudFront", "Edge & CDN"),
153
+ ]
154
+ SERVICE_KIND = {"reCAPTCHA": "Bot protection"}
155
+ _RECAPTCHA = re.compile(r"google\.com/recaptcha|gstatic\.com/recaptcha|grecaptcha", re.I)
156
+
157
+ _HEAD = [(h, re.compile(rx, re.I), n, c) for h, rx, n, c in _HEADER_SIGNS]
158
+ _COOK = [(re.compile(rx, re.I), n, c) for rx, n, c in _COOKIE_SIGNS]
159
+ _BODY = [(re.compile(rx, re.I), n, c) for rx, n, c in _BODY_SIGNS]
160
+ _PATH = [(re.compile(rx, re.I), n, c) for rx, n, c in _PATH_SIGNS]
161
+ _SCAN_CAP = 400_000
162
+
163
+
164
+ def detect(headers: dict[str, str], cookie_names: list[str], body: str, path: str,
165
+ is_markup: bool) -> list[tuple[str, str, str, str]]:
166
+ """Technologies one response shows: (name, category, how, version). Deterministic, deduplicated."""
167
+ found: dict[tuple[str, str], tuple[str, str]] = {}
168
+
169
+ def add(name, cat, how, ver=""):
170
+ k = (name, cat)
171
+ if k not in found or (ver and not found[k][1]):
172
+ found[k] = (how, ver or (found[k][1] if k in found else ""))
173
+
174
+ for h, rx, name, cat in _HEAD:
175
+ v = headers.get(h)
176
+ if v:
177
+ m = rx.search(v)
178
+ if m:
179
+ add(name, cat, "header:" + h, (m.group(1) if m.groups() and m.group(1) else "")[:20])
180
+ for ck in cookie_names or []:
181
+ for rx, name, cat in _COOK:
182
+ if rx.search(ck):
183
+ add(name, cat, "cookie")
184
+ for rx, name, cat in _PATH:
185
+ if rx.search(path or ""):
186
+ add(name, cat, "path")
187
+ if is_markup and body:
188
+ text = body[:_SCAN_CAP]
189
+ for rx, name, cat in _BODY:
190
+ m = rx.search(text)
191
+ if m:
192
+ add(name, cat, "page", (m.group(1) if m.groups() and m.group(1) else "")[:20])
193
+ g = _GENERATOR.search(text)
194
+ if g:
195
+ gen = g.group(1).strip()[:60]
196
+ nm = re.match(r"([A-Za-z][\w .+-]*?)(?:\s+([\d][\w.]*))?$", gen)
197
+ name, ver = (nm.group(1).strip(), nm.group(2) or "") if nm else (gen, "")
198
+ low = name.lower()
199
+ if low.startswith("wordpress"):
200
+ name = "WordPress"
201
+ add(name, "CMS & platform", "meta generator", ver)
202
+ if _RECAPTCHA.search(text):
203
+ add("reCAPTCHA", "Services", "page")
204
+ return sorted((n, c, h, v) for (n, c), (h, v) in found.items())
205
+
206
+
207
+ def vendors_for(hosts: list[str]) -> list[tuple[str, str, str]]:
208
+ """(vendor, kind, host) for hosts that belong to a known third-party service."""
209
+ out, seen = [], set()
210
+ for host in hosts:
211
+ h = (host or "").lower()
212
+ for suffix, vendor, kind in _VENDORS:
213
+ if h == suffix or h.endswith("." + suffix):
214
+ if (vendor, h) not in seen:
215
+ seen.add((vendor, h))
216
+ out.append((vendor, kind, h))
217
+ break
218
+ return out
@@ -0,0 +1,16 @@
1
+ # Fonts embedded in the report
2
+
3
+ The report embeds these fonts (Latin subset, variable weight) so it renders the same offline.
4
+ Inter and JetBrains Mono are licensed under the SIL Open Font License 1.1 (https://openfontlicense.org).
5
+
6
+ | Font | Copyright |
7
+ | --- | --- |
8
+ | Inter | The Inter Project Authors (https://github.com/rsms/inter) |
9
+ | JetBrains Mono | The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono) |
10
+
11
+ Files come from the Fontsource packages `@fontsource-variable/inter` and
12
+ `@fontsource-variable/jetbrains-mono`.
13
+
14
+ `nippo-*.woff2` are subsets of Nippo by the Indian Type Foundry (Fontshare, ITF Free Font License),
15
+ the same subsets the fa1c0n profile artwork embeds: printable ASCII and `· – — ’ …`. Inter covers
16
+ any other glyph.
Binary file
Binary file
Binary file
Binary file
Binary file