AI Blinder Blinder, a new open-source local HTTPS reverse proxy written in Go, strips target identity — domains, brands, organization names, emails and IP addresses — from HTTP and WebSocket traffic so AI-assisted security scanners evaluate application behavior instead of forming opinions based on who the target is. The tool presents the target to the downstream AI as an anonymous locally hosted application at https://127.0.0.1:8099 while preserving behavioral signals such as error messages, reflected input, status codes and security controls, with options including --preserve-content for identity-only scrubbing and --extra-origin for multi-origin routing. The project's author frames Blinder as an early position that testing should be separated from context, and invites better implementations and contributions. A local reverse proxy for content-blind security scanning. Go · Local HTTPS · HTTP & WebSocket · Tor / SOCKS5 The reasoning the-reasoning / How it works how-blinder-works / Quick start quick-start / Certificates certificates / Tor tor / CAPTCHA captcha / Evidence evidence / Development development Security testing is a behavioral discipline. What an application does -- how it handles input, what controls it enforces, what it reflects back, how it fails -- is what matters. Identity should be irrelevant to that analysis. AI-assisted security tools don't work that way. They see the target -- its domain, its brand, its organization -- and they form opinions. They soften findings for well-known services. They refuse to probe based on who the target is. They decline to test paths they associate with a particular vendor. The AI is making decisions that belong to the operator, and it's making them based on context rather than behavior. This is the wrong axis. The operator authorizes the scope. The tool evaluates behavior. Those are different responsibilities and they shouldn't collapse into one. But today, every AI-assisted tool has the target's full identity wired into every decision it makes -- what to test, how hard to push, whether to report. Blinder is a starting point: a practical tool, but also a position that testing should be separated from context. This is an early attempt to get the idea out there. If the approach resonates, we'd welcome better implementations, contributions, or just the conversation about where the line should be. Stripping identity doesn't mean stripping content. That's where most naive approaches break. Vulnerabilities are observable as changes in response content -- error messages, reflected input, data the session shouldn't reach, computed results that reveal server-side evaluation. If a proxy stripped this content, it would hide the evidence the tester is looking for. The requirement is surgical: remove identity while preserving behavioral signals . A page that belongs to no one but behaves exactly as the original does -- including when it behaves badly. Blinder is a local HTTPS reverse proxy that sits between the AI scanner or browser and the target. It rewrites identity -- domains, brands, organization names, emails, IP addresses -- while preserving the application's functional behavior: its errors, its reflections, its security controls, its status codes, its content structure. To the downstream AI, the target is an anonymous locally hosted application at https://127.0.0.1:8099 . No brand to recognize. No domain to form an opinion about. The AI tests what the application does , not who it is . This is content-blind scanning: the operator controls who the target is; the AI focuses on what it does. Replacement content is part of correctness: neutral filler for display, reversible values for application data, and preserved diagnostics and control behavior. Generated removal notices don't belong in pages. | Content scrubbing | Display text replaced with neutral prose filler; interactive elements buttons, labels, form controls and diagnostic content error messages, stack traces, reflected markup preserved. Identity tokens, domain references and cookie values rewritten across HTTP bodies, headers and WebSocket text. --preserve-content keeps original display text for identity-only scrubbing. | | Resource integrity | Original SRI verified per reference and recomputed for rewritten resources, with corresponding CSP hashes translated. Versioned references bind the served bytes; external resource integrity is preserved. | | Response cache | Separate upstream/downstream cache validators. 304 revalidation merges security-policy headers. Vary-aware eviction. | | Session handling | Reversible cookie names with per-value scrubbing. Multi-origin routing via --extra-origin with deterministic alias hostnames, Host-header routing and CORS origin translation. | | CAPTCHA relay | Operator-facing challenge queue and separate provider origins. Tor-routed resources keep provider cookies, CSP and CORS separate from the target and operator. | | Private routing | Upstream HTTP and WebSocket through Tor SOCKS5 with remote hostname resolution. Tor failures are hard errors, never silent fallbacks. | | Local HTTPS | Local CA with 90-day lifetime and automatic renewal; session leaf certificates are signed on the fly. Trust the CA once -- adding origins or changing aliases never requires re-trusting. Ephemeral mode available. | | Evidence | Pre-scrub HAR with journal-based persistence, request manifest with per-request scrub/leak counts, domain mappings and scrub report. Paired response comparisons https://github.com/Splinters-io/blinder/blob/main/docs/response-deltas.md check byte-size fidelity and whether content/status changes survive masking. Signal-preservation checks record verified behavior and remaining defects. | See supported behavior and delivery gates https://github.com/Splinters-io/blinder/blob/main/docs/capabilities.md for implementation status and known limitations. Build with Go 1.26+ . The binary has no external runtime dependency. git clone https://github.com/Splinters-io/blinder.git cd blinder make build ./blinder --preflight Follow the OS-specific certificate advice, then start a session: capture dir=$ mktemp -d ./blinder --target https://your-authorized-target.example \ --identity YourOrganisation \ --har "$capture dir/session.har" \ --output "$capture dir/output" Point your browser or scanner at https://127.0.0.1:8099 . Add multiple identity tokens with repeated --identity flags. Stop with Ctrl-C to save the session evidence. Use --config -c to load defaults from a YAML file. CLI flags override the file. blinder.yaml listen: "127.0.0.1:9443" target: "https://example.com" alias: "target-001.local" identity: - "ExampleCorp" - "example.com" output: "/tmp/blinder-output" captcha config: "captcha.yaml" no verify tls: true tor: enabled: false addr: "127.0.0.1:9050" har: path: "/tmp/session.har" max body: 10485760 ./blinder -c blinder.yaml override the listen port from the file: ./blinder -c blinder.yaml --listen 127.0.0.1:7777 Blinder generates a local CA Certificate Authority on first run and uses it to sign session-specific leaf certificates. Trust the CA once; all current and future endpoints -- including extra origins added later -- are automatically trusted without re-running setup. | Platform | Setup | |---|---| | macOS | Run the printed --trust-cert command, review the CA fingerprint and approve user Keychain trust. One-time setup. | | Ubuntu / Linux | Use the printed curl --cacert command or install the CA certificate in your browser/scanner's trust store. | Use --cert-dir DIR for a chosen CA store. The CA persists for 90 days with automatic renewal; --ephemeral-cert generates a temporary self-signed leaf with no CA. Preflight exit 2 means platform trust needs setup; a client using its own CA file can still connect successfully. Adding extra origins, changing the alias or reconfiguring CAPTCHA providers generates a new leaf certificate signed by the same CA -- no re-trusting required. Preflight reports trust for the listen host, primary alias, configured extra-origin aliases and, when CAPTCHA is configured, the operator and a concrete challenge hostname. With --tor , preflight also includes the configured provider aliases. The CA store also holds a private version-signing.key for resource-reference ownership, independent of certificate renewal. Keep it across restarts so expired references remain recognisable. --ephemeral-cert keeps TLS temporary; resource-reference ownership still persists in the default store. Certificate setup, OS guidance and renewal https://github.com/Splinters-io/blinder/blob/main/docs/testing.md local-certificate-trust Start your Tor service and wait for bootstrap, then select its SOCKS endpoint: ./blinder --target http://your-service.onion \ --tor --tor-addr 127.0.0.1:9050 \ --identity YourOrganisation Clearnet targets can use the same route. Target TLS verification stays enabled. Tor failures return an error without falling back to a direct target connection. Tor setup and live acceptance checklist https://github.com/Splinters-io/blinder/blob/main/docs/testing.md live-tor-uat When the target returns a CAPTCHA challenge, Blinder queues it for the operator. Configure providers via --captcha-config : version: 1 captcha: providers: - hcaptcha Open the browser login URL printed at startup: https://blinder-operator.localhost: