Day 41 of #100DaysOfCode
Missed a day due to lack of electricity๐คฆ
but we keep pushing regardless.
Today I created the details pane for each residence, then I added a search feature which allows you to search based on name, location and pricing.
still consistent
on to day 42
A lot of people have asked how the browser side of my AI bug bounty system works.
It is probably the part people struggle with most because giving a model browser access is easy. Giving it browser access that can survive real signup flows, CAPTCHA, anti-bot systems, authenticated testing, multiple accounts, and concurrent hunts is a completely different problem.
I currently run 100 persistent headed Chrome profiles on the same server as the rest of the research system.
They are not disposable Playwright sessions and they are not clean profiles created for every target. Each one has its own Chrome user directory and keeps its cookies, local storage, history, consent state, challenge cookies, saved sessions, and anything else the browser normally accumulates.
That means a profile becomes more useful over time.
If it has already passed a Cloudflare challenge, accepted a consent banner, signed into Google, or built normal browsing history, that state is still there when it starts again. Four profiles also have their own Google accounts signed in for targets where normal registration is blocked and social login is the only realistic path.
Every profile has a fixed Webshare IP.
The pool is currently split into 50 US profiles, 20 UK, 10 Australia, 10 Germany, and 10 Singapore. When a target needs a specific country, the system leases a free profile from that range. If geography does not matter, it selects a free profile from the full pool.
The same profile returns through the same IP rather than changing exit every request. That matters because the target is not looking at the IP in isolation. It sees the IP, country, timezone, cookies, account history, challenge state, and browser storage together. Keeping an old session while rotating through a different country every few minutes creates more problems than it solves.
Chrome also starts with a timezone that matches the profile's exit country. This is done at process level, so Date and Intl behave natively. I am not patching the timezone in JavaScript after the page loads.
I do not assume a proxy is good because the provider sold it as residential.
All 100 assignments are checked against the live provider inventory. Traffic is sent through every assigned proxy to confirm the actual exit IP and country with Cloudflare. The IPs are also checked through ip-api, ProxyCheck, and Scamalytics so I can compare geography, proxy flags, hosting flags, blacklist data, and fraud risk.
Those services disagree more often than people probably expect. A live Australian exit can be routed correctly while one older database still reports another country. One provider can call an IP residential while another calls it business or hosting. The audit records those disagreements and tracks changes over time. It does not automatically replace an IP because one service returned a bad-looking label.
Each browser is fully headed.
When a profile starts, it gets its own isolated 1920x1080 virtual display, its own small window manager, and its own noVNC connection. The 100 browsers do not share one desktop, so one profile cannot steal focus, resize another browser, or put a window over another hunt.
Most of the time the AI drives Chrome through CDP. Each profile has a known CDP port, so the research phases can attach to the existing tab, navigate, inspect the DOM, fill forms, upload files, execute JavaScript, read console output, extract cookies, and capture screenshots.
But because it is headed Chrome, I can open the exact same profile from my dashboard at any time.
If a login needs MFA, a consent manager is stuck inside a cross-origin iframe, a CAPTCHA does not solve, or something on the page needs human judgment, the system surfaces the profile that needs attention. I open it through noVNC, complete that step, and close the viewer.
The browser itself never moved. The same account, IP, cookies, tab, traffic, and authenticated state remain available to the AI when it continues.
Every profile also has NoPECHA installed for reCAPTCHA, hCaptcha, Turnstile, Cloudflare challenges, and Geetest.
Running the extension across 100 persistent profiles created its own reliability problem. An extension can be installed but missing its API key, missing its stored settings, disabled in the profile, or waiting for Chrome to download its code.
Before a profile starts, the lifecycle manager checks the extension files, settings database, preferences, API configuration, and toolbar state against a known working copy. If anything drifted, it repairs the profile while Chrome is stopped. The automation also knows the solver may be clicking inside a challenge, so it waits for the challenge to clear instead of sending CDP input at the same time and breaking it.
Normal browser traffic goes through a separate mitmproxy instance for each profile.
The route is Chrome, then the profile's MITM, then its fixed Webshare proxy, then the target. Each browser writes to its own flow file, so traffic from two hunts is never mixed together.
This is what makes the browser useful for more than navigating pages.
The AI can register an account, perform one normal action, and capture the exact requests the real product generated. That includes OAuth redirects, token refreshes, GraphQL operations, multipart uploads, presigned storage requests, CSRF headers, service-worker traffic, and APIs that were never obvious from static recon.
Once a valid request exists, the system decides whether it still needs the browser.
Most API testing is faster through curl or a script using the browser's authenticated state. IDOR matrices, parameter tampering, injection, race conditions, and mass assignment do not need a UI click for every payload.
If a request depends on rotating browser state, a service worker, SPA middleware, or page context, it can be executed inside the existing tab through CDP instead.
There is also a no-MITM mode.
Some anti-bot systems fingerprint TLS at the edge. Akamai is a good example. Chrome can look normal in JavaScript, but once mitmproxy terminates TLS, the target sees a different network fingerprint and refuses to validate the browser session.
For those targets I switch that profile to a small authentication-forwarding tunnel. Chrome still uses the same fixed Webshare IP, but its TLS passes through without being decrypted. I lose traffic capture for that session, but the target sees native Chrome TLS and the login flow works.
This is why CAPTCHA, JavaScript fingerprinting, TLS fingerprinting, and IP reputation cannot all be treated as the same browser problem. Each layer has a different fix.
Profiles are leased to an exact platform, target, research cycle, and role. Two agents are never allowed to drive the same profile because tabs share cookies, storage, account state, and the same MITM file. Sharing a browser would create fast progress that nobody could trust.
When a profile starts, the lifecycle manager archives its previous live capture, checks the exit configuration, fixes stale ports from crashed processes, clears only Chrome's crash-restore markers, verifies the CAPTCHA extension, starts the display, MITM, Chrome, and runtime support, waits for CDP, then records who owns it.
When it stops, Chrome closes but the user directory remains. The profile keeps the state that made it useful. Inactive profiles are also included in an encrypted daily backup because recreating Chrome is easy. Recreating months of browser state and authenticated sessions is not.
That is the browser stack.
The model gets CDP access, but CDP is only one part of it. The useful system is persistent identity, fixed and measured egress, headed Chrome, isolated displays, CAPTCHA handling, traffic capture, native-TLS fallback, human takeover, ownership, and recovery working together.
Without those layers, AI spends half the run fighting the environment and then reports the environment failure as target behavior.
And yes this is a massive read
#BugBounty #CyberSecurity #TogetherWeHitHarder
๐ฏ Advanced Bug Bounty Tip: Don't just fuzz parametersโfuzz the request structure.
Most testers mutate values. Fewer mutate the format.
Try sending the same input as:
โข JSON โ XML
โข JSON โ form-data
โข Nested arrays/objects where a scalar is expected
โข Different "Content-Type" headers
Different parsers = different behavior.
This is where you may uncover:
โข Mass assignment
โข Type confusion
โข Authentication/authorization bypasses
โข Validation inconsistencies
๐ก Bonus: Test duplicate parameters.
id=1&id=2
Some components use the first value, others the last. That parser mismatch can become a powerful primitive for IDOR, request smuggling, or access control bypass.
Think beyond payloads. Test parser assumptions.
#BugBounty #AppSec #InfoSec #WebSecurity #CyberSecurity
10 Years of XSS Bypass
I spent a decade popping alert boxes in places filters said were impossible. Every WAF, every custom filter, every regex written by someone who underestimated what an attacker would try.
This is not a payload list. It is the methodology behind every bypass I found. The thinking process that filters cannot patch because it lives in the researcher, not the payload.
30+ techniques. 10 documented Easy Wins against real filters. The same systematic approach I used against CloudFlare, Akamai, Imperva, and Fortinet.
WAFs get updated. Public bypasses get patched. The methodology does not.
The Brute Art of Bypass.
A security researcher just spent days auditing INEC's election infrastructure ahead of 2027.
The findings should concern every Nigerian.
The API serving 400 elections across all 36 states responds with HTTP 200 and no authentication. No token. No rate limit. Full internal schema exposed including MongoDB ObjectIDs and model structure. Anyone can query it.
The official S3 buckets where result documents are supposed to live return NoSuchBucket. They do not exist. Nobody owns them. That means anyone with an AWS account can register those exact bucket names today and serve fake EC8A result forms directly through INEC's official portal on election night. The bucket names are in the code. They are unregistered. The window is open right now.
The admin portal's device security is a User-Agent header check. Change your browser string and you are in. That is not security. That is a sign on a door that says authorised personnel only.
Login forms have no CSRF tokens. Session cookies have no SameSite flags. One phished admin account gives full voter register access with no 2FA standing between an attacker and the ability to add, delete, or bulk import voters.
The BVAS server handling biometric data for over 90 million citizens serves a TLS certificate belonging to an unrelated domain. The main site's TLS certificate expires in days.
Then there is the compliance problem.
The Nigeria Data Protection Act 2023 prohibits transferring citizen data abroad without approved mechanisms. BVAS biometric data sits on DigitalOcean in New Jersey. Voter identities on Google Cloud in Kansas City. The voter registration API on AWS in London. Six of eight core systems are offshore. No published Data Protection Impact Assessment exists. No approved transfer framework.
90 million Nigerians' fingerprints and facial data are sitting on foreign cloud infrastructure in violation of Nigerian law with no documented legal basis for being there.
0xrobotbick states this research was entirely passive and read-only. Nothing was modified or exploited. A full report with logs and timestamps is ready for INEC and the NDPC.
17 days before public disclosure if nothing is fixed.
INEC already confirmed a voter data access incident in June 2026. DSS is already investigating insider threats. The infrastructure problems 0xrobotbick found are not isolated findings. They sit inside a system that has already demonstrated it cannot protect the data it holds.
2027 is not far away.