After about 10 years dealing with S3, I feel like I maybe missed something. I have a particular case where:
https://<bucket-name>.s3.<region>.amazonaws.com/<object-key>
are
serving up objects via HTTP.I would expect that objects given public-read ACL can be freely accessed by anyone, unauthenticated with AWS, using the AWS API for GetObject. I do not expect this http access behavior, however. Even if Static website hosting were enabled, the URL would be different.
The S3 API is implemented as a series of REST API calls (along with SOAP API calls for backwards compatibility reasons). Specifically, if we go through the documentation for the GetObject call and remove each item that's not marked as required, we're left with a call like this:
GET /Key HTTP/1.1
Host: Bucket.s3.amazonaws.com
In other words, a normal HTTPS GET request that any user agent like a browser would send. The user agent will include other headers, but S3 will ignore those headers it doesn't directly support.
So, assuming an object does not require the authorization header since it has public-read ACL, then a browser will load it directly as if it's making a GetObject call, since in effect, it is.