Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
| import uuid | |
| import hashlib | |
| import hmac | |
| import secrets | |
| import base64 | |
| import subprocess | |
| from typing import * | |
| import os | |
| import sys | |
| import re | |
| import json | |
| import time | |
| import urllib3 | |
| import requests | |
| import socket | |
| import logging | |
| import threading | |
| import concurrent.futures | |
| import ipaddress | |
| import ssl | |
| from urllib.parse import urlparse, urljoin, urlencode, quote | |
| from collections import defaultdict | |
| from bs4 import BeautifulSoup | |
| from datetime import datetime, timezone | |
| AUTH_STATES = [ | |
| "anonymous", | |
| "authenticated_user", | |
| "authenticated_admin", | |
| "authenticated_other_user", | |
| ] | |
| class DifferentialAnalyzer: | |
| def __init__(self): | |
| self._responses: dict[str, list[dict]] = {} | |
| self._entropy: dict[str, float] = {} | |
| def record(self, label: str, body: str, status: int, elapsed: float, headers: dict | None = None): | |
| self._responses.setdefault(label, []) | |
| self._responses[label].append({ | |
| "body": body, | |
| "status": status, | |
| "elapsed": elapsed, | |
| "headers": headers or {}, | |
| "length": len(body), | |
| "words": len(body.split()), | |
| "lines": body.count("\n"), | |
| }) | |
| def get(self, label: str) -> list[dict]: | |
| return self._responses.get(label, []) | |
| def compare(self, label_a: str, label_b: str) -> dict: | |
| ra = self._responses.get(label_a, []) | |
| rb = self._responses.get(label_b, []) | |
| if not ra or not rb: | |
| return {"different": False, "reason": "insufficient data"} | |
| a = ra[-1] | |
| b = rb[-1] | |
| diffs = [] | |
| score = 0.0 | |
| if a["status"] != b["status"]: | |
| diffs.append(f"Status: {a['status']} vs {b['status']}") | |
| score += 2.0 | |
| length_ratio = abs(a["length"] - b["length"]) / max(a["length"], b["length"], 1) | |
| if length_ratio > 0.1: | |
| diffs.append(f"Length: {a['length']} vs {b['length']} ({length_ratio*100:.0f}% diff)") | |
| score += length_ratio * 3 | |
| timing_diff = abs(a["elapsed"] - b["elapsed"]) | |
| if timing_diff > 1.0: | |
| diffs.append(f"Timing: {a['elapsed']:.2f}s vs {b['elapsed']:.2f}s") | |
| score += min(timing_diff, 5.0) | |
| word_ratio = abs(a["words"] - b["words"]) / max(a["words"], b["words"], 1) | |
| if word_ratio > 0.1: | |
| diffs.append(f"Words: {a['words']} vs {b['words']} ({word_ratio*100:.0f}% diff)") | |
| score += word_ratio * 2 | |
| html_stripped_a = re.sub(r'<[^>]+>', '', a["body"]) | |
| html_stripped_b = re.sub(r'<[^>]+>', '', b["body"]) | |
| text_ratio = abs(len(html_stripped_a) - len(html_stripped_b)) / max(len(html_stripped_a), len(html_stripped_b), 1) | |
| if text_ratio > 0.15: | |
| diffs.append(f"Text content: {len(html_stripped_a)} vs {len(html_stripped_b)} chars") | |
| score += text_ratio * 2 | |
| return {"different": score > 1.0, "score": round(score, 2), "differences": diffs} | |
| def compare_all(self, label: str) -> list[dict]: | |
| results = [] | |
| responses = self._responses.get(label, []) | |
| if len(responses) < 3: | |
| return results | |
| baseline = responses[0] | |
| for i in range(1, len(responses)): | |
| diff = self._compare_pair(baseline, responses[i]) | |
| diff["index"] = i | |
| results.append(diff) | |
| return results | |
| def _compare_pair(self, a: dict, b: dict) -> dict: | |
| diffs = [] | |
| score = 0.0 | |
| if a["status"] != b["status"]: | |
| diffs.append(f"Status: {a['status']} vs {b['status']}") | |
| score += 2.0 | |
| length_diff = abs(a["length"] - b["length"]) | |
| if length_diff > 100: | |
| diffs.append(f"Length diff: {length_diff}") | |
| score += min(length_diff / 1000, 5.0) | |
| return {"different": score > 1.0, "score": round(score, 2), "differences": diffs} | |
| def summary(self) -> dict: | |
| result = {} | |
| for label in self._responses: | |
| result[label] = { | |
| "count": len(self._responses[label]), | |
| "avg_length": sum(r["length"] for r in self._responses[label]) / max(len(self._responses[label]), 1), | |
| "avg_elapsed": sum(r["elapsed"] for r in self._responses[label]) / max(len(self._responses[label]), 1), | |
| } | |
| return result | |
| class ParameterMutationTester: | |
| def __init__(self, request_fn: Callable): | |
| self._request_fn = request_fn | |
| def test(self, base_url: str, base_params: dict, mutations: list[dict]) -> list[dict]: | |
| results = [] | |
| baseline_body, baseline_status = self._request_fn(base_url, base_params) | |
| baseline_length = len(baseline_body or "") | |
| for mutation in mutations: | |
| test_params = dict(base_params) | |
| test_params.update(mutation.get("params", {})) | |
| body, status = self._request_fn(base_url, test_params) | |
| length = len(body or "") if body else 0 | |
| diff = abs(length - baseline_length) / max(baseline_length, 1) | |
| results.append({ | |
| "mutation": mutation.get("name", "unknown"), | |
| "status": status, | |
| "length_diff_pct": round(diff * 100, 1), | |
| "anomalous": diff > 0.2 or status != baseline_status, | |
| }) | |
| return results | |