Skip to content

A redirect to http is not https - #114

Merged
bravemaster3 merged 1 commit into
mainfrom
fix/a-redirect-to-http-is-not-https
Sep 11, 2026
Merged

bravemaster3 merged 1 commit into
mainfrom
fix/a-redirect-to-http-is-not-https

Conversation

@bravemaster3

Copy link
Copy Markdown
Owner

The mixed-content guard shipped in v1.6.2 followed redirects and then asked only whether the answer
was a 200 with bytes in it. The reported URL passes that while ending on plain http, so the
guard called it secure and would have stored an address that still cannot draw.

Measured against the real service:

http://www.google.cn/maps/vt?lyrs=s@189&gl=cn...    302 -> http://www.google.com/...
https://www.google.cn/maps/vt?lyrs=s@189&gl=cn...   302 -> http://www.google.com/...
https://www.google.com/maps/vt?lyrs=s@189&gl=cn...  200   image/jpeg  13667 bytes
https://mt1.google.com/vt/lyrs=s&...                200   image/jpeg  13667 bytes

Both schemes redirect, and both redirect to http. A request that begins secure and finishes
insecure is blocked by a browser exactly as an http URL typed in directly is, so
_answers_securely now requires every hop of the chain to be https, not just the answer at the
end of it. Demonstrated on the old code:

old check (200 + bytes, redirects followed): True   but it ended at http://www.google.com/...

…and then it finds the address that works

Refusing would have been correct but useless. The redirect changes only the host — same path,
same query — and that host serves https, byte for byte the same tiles. So _redirected_origin
follows a pure change of host, and the source is stored at
https://www.google.com/maps/vt?lyrs=s@189&gl=cn&x={x}&y={y}&z={z}.

A redirect that changes the path or the query is not followed: a consent wall, a login page or
a per-tile CDN URL is not a template, and rewriting a source to one would store an address that
works for tile 0/0/0 and for nothing else.

Verified against the live service, not only against fakes

input result
the reported Google satellite template https://www.google.com/maps/vt?…&x={x}&y={y}&z={z}
http://tile.openstreetmap.org/{z}/{x}/{y}.png itself, on https
an address already on https not probed at all
a host that does not exist refused, with the reason

75 checks in api/tests/test_external_kinds.py (was 70), including the exact shape of Google's
answer, an https→https CDN hop that must still pass, and the two redirects that must not be
followed.

Existing rows are not rewritten — the resolution happens when a source is added. A source
already stored with the http address has to be deleted and added again.

The mixed-content guard shipped in v1.6.2 followed redirects and then asked
only whether the answer was a 200 with bytes in it. The reported URL passes
that while ending on plain http, so the guard called it secure and would have
stored an address that still cannot draw.

Measured against the real service:

  http://www.google.cn/maps/vt?lyrs=s@189...  302 -> http://www.google.com/...
  https://www.google.cn/maps/vt?lyrs=s@189... 302 -> http://www.google.com/...
  https://www.google.com/maps/vt?lyrs=s@189... 200  image/jpeg  13667 bytes

Both schemes redirect, and both redirect to http. A request that begins secure
and finishes insecure is blocked by a browser exactly as an http URL typed in
directly is, so `_answers_securely` now requires EVERY hop of the chain to be
https rather than just the answer at the end of it.

That alone would refuse the URL. But the redirect changes only the HOST — same
path, same query — and the host it names does serve https, byte for byte the
same tiles. So `_redirected_origin` follows a pure change of host and the
source is stored at https://www.google.com/maps/vt?..., which draws. A redirect
that changes the path or the query is NOT followed: a consent wall or a
per-tile CDN URL is not a template, and rewriting a source to one would store
an address that works for tile 0/0/0 and for nothing else.

Verified against the live service, not only against fakes: the template
resolves to the google.com address, an ordinary http host resolves to itself on
https, an https address is never probed, and a host that does not exist
resolves to nothing. 75 checks in test_external_kinds.py, including the exact
shape of Google's answer and the two redirects that must not be followed.

Signed-off-by: Koffi Dodji Noumonvi <noumonvikoffidodji@hotmail.fr>
@bravemaster3
bravemaster3 merged commit e8cba25 into main Sep 11, 2026
10 checks passed
@bravemaster3
bravemaster3 deleted the fix/a-redirect-to-http-is-not-https branch September 11, 2026 18:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant