Back to Feed
article 3m read

Browser checker vetted the address it was asked for, then ignored where it landed

The hidden browser window in my coding app checked the address I asked for against its allowlist and never the one a redirect dropped it on, so it could click, screenshot and certify a page nobody approved. Now the same check runs on the landing address before anything touches the page, though the outside page still gets fetched first.

Article DepthPractice

Flow

Pick one spot for the second check, earliest to latest

  1. 1Option: right after the load

    Nothing is typed, clicked, captured or saved for the wrong page. This is where mine sits.

  2. 2Option: after the clicks and typing

    My text may already be sitting in another site's forms.

  3. 3Option: after the screenshot

    A picture of the wrong page already exists, even if it gets thrown out.

  4. 4Option: no second check

    The saved proof describes a page nobody allowed.

Where it ended up never got looked at by the browser checker, only the address I gave it.

The checker is part of my desktop coding app. It opens the app I'm building in a hidden browser window, can click and type a little, takes a screenshot, and saves all of it as proof the page works. Since the window can reach the internet, it has a list of allowed places: my own machine, plus anything a project adds on purpose.

It only checked the address I asked for.

Why the landing spot matters

Browsers follow redirects by themselves. If a page on my machine says "go over there", the window goes, and the load finishes like nothing moved. A dev server sending you to an outside login page would do it. So would a proxy pointed at the wrong place.

After that, every step works on the wrong page. Typing goes into its forms. The screenshot shows it. The saved proof calls it my app. I don't know of a real run where this happened; the only redirect it has seen is a fake one in a test.

Checking twice with the same rule

After the load, the checker now looks at the final address too.

It vets the address the window reports and refuses if that fails.

If that fails, it returns a plain refusal with both addresses and a reason. No proof gets saved. The second check sits before any typing, clicking, screenshot or saving, since each of those does harm on the wrong page. Both checks share one function, so they can't drift apart. And the window gets asked for its address once, with that checked answer passed along, instead of being asked again later.

One part I don't like: if the window gives no address, mine falls back to the one I asked for, so the check passes. That case should be a refusal.

Testing it without a browser

The test uses a fake window that switches to an outside site while loading. It expects a refusal, no proof, the landing address in the result, and no screenshot taken. That last check is the one that catches someone moving the guard below the capture.

It still visits the page

By the time the check runs, the window has already loaded the outside page. So this stops my tool from using that page or vouching for it, but not from visiting it. Stopping the visit would take a hook that cancels a bad redirect before the browser follows it, and nothing in this change does that.

Keep reading

Pick up a connected idea or branch into a nearby one.

5 paths forward