If I wanted to achieve the same result, that is to serve assets of others from my own domain, I'd just create a custom endpoint like /api/user-avatar/:userId and an action proxies the actual image from google, maybe keep a cached copy for some time to not have to redownload the image on every request.
This seems problematic to me. Beyond just caching issues, did you ever get permission from users to store their personal data? They gave google permission, but not you.
Public data can be personal data and anyone doing the same as TFA is making itself a liable processor. But, aren't you a processor by using OAuth in the first place? Yes but with what TFA is doing you have a greater liability surface.
I don't live in Europe, I will never travel to Europe, I don't plan to ever do business with Europe. I don't care if Europe sentences me to be shot into the sun for GDPR violations, it's not like I'm going to be extradited for it.
And I'm not aware of any law anywhere here that says I can't download a public photo. The use case is clearly valid and benign, the photo is public, there's no way a judge would go for that no matter how you twist the law.
Yes, quite the opposite. It did remind me of the old days though, when you could do the opposite and "hotlink" pictures from most websites and save yourself bandwidth costs!
I think the point is that they’re avoiding whitelisting Google and Github domains which is necessary to preprocess images from and use urls to images to their domain in an Image tag. That allows malicious users to send urls such urls to his _next image preprocess endpoint and get “free compute”. (Not sure why someone would do that other than to just screw with somebody).
He’s using BetterAuth hooks to fetch those images and upload to his trusted url to avoid such a scenario.
The components work by requesting the image URL from your own server/API, at a route like `/_next/image`. The actual image URL that's passed as a prop to the component is passed to that API endpoint as a URL parameter.
So, the endpoint is essentially a proxy that does additional image processing, like compression and width/height resizing (again, a URL parameter that the Image component or any other client can change based on the device / screen size in use).
This means that without a domain whitelist, theoretically any image URL can be passed to the endpoint, which will then be processed and cached by your infra.
This has been used in the wild, e.g. racking up charges on someone else's Vercel bill by requesting a bunch of images through this endpoint.
Thanks for the explanation - I was deeply confused by this article's premise. I've never worked with Next.js or Astro, so I didn't have the background.
Imagine your app uses that Image tag to process image for some specific resolution/quality - just any processing done on your server for any imagw resource loaded via this tag.
Not sure how exactly it works, never used the framework, but i assume that when the frontend app detects this image tag it makes a server call to orocess it and rerurn optimized version.
Now, if someone were to insert such tag onto the frontend of your app and put in source of their own image, your server would do the processing of their image.
I have absolutely no idea in what universe would this be a practical attack of benefiting anyone at all
Edit: oh i see the coment by samtheprogram. I would think that the framework would use some form of csrf, this is a really weird implementation
Note to the developer: you may want to consider simplifying the CSS you're using to display the "clever" dot in the background of your page. On my computer, opening viewing your site in Firefox, scrolling the page has a nearly 2000ms delay caused by whatever is going on. This is improved but not fixed by disabling the `.bg-dot::before` background CSS property.
If I wanted to achieve the same result, that is to serve assets of others from my own domain, I'd just create a custom endpoint like /api/user-avatar/:userId and an action proxies the actual image from google, maybe keep a cached copy for some time to not have to redownload the image on every request.
Especially since, if you were doing this on CloudFlare—which you can with OpenNext—it's incredibly simple to work with CloudFlare's caches in Workers. For example: https://developers.cloudflare.com/workers/examples/cache-usi...
Plus there's their Images service which could come in handy to transform them a bit, too, if you wanted.
This. Only needs a couple lines of nginx config.
Nice, but doesn't automatically update when the Google avatar changes. Cache invalidation strikes again.
This seems problematic to me. Beyond just caching issues, did you ever get permission from users to store their personal data? They gave google permission, but not you.
The users are going through an OAuth flow and creating an account. Presumably they are agreeing to a ToS as part of that.
It even says in the OAuth flow that the company is requesting your profile image.
It's a public photo. What's wrong with downloading it?
Folks, read yourself some GDPR for the greater good. Even just https://gdpr-info.eu/art-4-gdpr/
Public data can be personal data and anyone doing the same as TFA is making itself a liable processor. But, aren't you a processor by using OAuth in the first place? Yes but with what TFA is doing you have a greater liability surface.
(IANAL but I cite GDPR because the broad concepts apply to data privacy laws in other jurisdictions. See also: https://en.wikipedia.org/wiki/Brussels_effect)
I don't live in Europe, I will never travel to Europe, I don't plan to ever do business with Europe. I don't care if Europe sentences me to be shot into the sun for GDPR violations, it's not like I'm going to be extradited for it.
And I'm not aware of any law anywhere here that says I can't download a public photo. The use case is clearly valid and benign, the photo is public, there's no way a judge would go for that no matter how you twist the law.
I really didn't get what the post was about. I'm getting old or? And I thought I was clever because I work with distributed databases...
The post seems to be written by a developer that has never heard of caching and thinks they have invented some illicit solution by implementing it.
It makes very little sense - They don't want to ask users to trust Google's domain despite... integrating the user's google account? What?
And in what way is this stealing? Caching a publicly available asset? Sounds like you are saving Google bandwidth/money.
Yes, quite the opposite. It did remind me of the old days though, when you could do the opposite and "hotlink" pictures from most websites and save yourself bandwidth costs!
I think the point is that they’re avoiding whitelisting Google and Github domains which is necessary to preprocess images from and use urls to images to their domain in an Image tag. That allows malicious users to send urls such urls to his _next image preprocess endpoint and get “free compute”. (Not sure why someone would do that other than to just screw with somebody).
He’s using BetterAuth hooks to fetch those images and upload to his trusted url to avoid such a scenario.
That does make sense, but I'm not sure why it was worth sharing.
The post assumes the reader is familiar with where things are happening and who is involved. Guess I'm not part of the target audience.
Loading an img tag doesn't involve trusting a domain. Especially using crossorigin and refererpolicy attributes.
> But there’s a catch: anyone can abuse your app to optimize their own images, which costs you compute.
Could anyone explain this?
The components work by requesting the image URL from your own server/API, at a route like `/_next/image`. The actual image URL that's passed as a prop to the component is passed to that API endpoint as a URL parameter.
So, the endpoint is essentially a proxy that does additional image processing, like compression and width/height resizing (again, a URL parameter that the Image component or any other client can change based on the device / screen size in use).
This means that without a domain whitelist, theoretically any image URL can be passed to the endpoint, which will then be processed and cached by your infra.
This has been used in the wild, e.g. racking up charges on someone else's Vercel bill by requesting a bunch of images through this endpoint.
Thanks for the explanation - I was deeply confused by this article's premise. I've never worked with Next.js or Astro, so I didn't have the background.
Imagine your app uses that Image tag to process image for some specific resolution/quality - just any processing done on your server for any imagw resource loaded via this tag.
Not sure how exactly it works, never used the framework, but i assume that when the frontend app detects this image tag it makes a server call to orocess it and rerurn optimized version.
Now, if someone were to insert such tag onto the frontend of your app and put in source of their own image, your server would do the processing of their image.
I have absolutely no idea in what universe would this be a practical attack of benefiting anyone at all
Edit: oh i see the coment by samtheprogram. I would think that the framework would use some form of csrf, this is a really weird implementation
Isn't this just passthrough caching with some persistence?
Please post again when you get the cease and desist letter!
Note to the developer: you may want to consider simplifying the CSS you're using to display the "clever" dot in the background of your page. On my computer, opening viewing your site in Firefox, scrolling the page has a nearly 2000ms delay caused by whatever is going on. This is improved but not fixed by disabling the `.bg-dot::before` background CSS property.
Irony: Claim you're stealing from Google, then post it on a .dev domain, of which Google is the operator.
They sold .dev to Squarespace a couple years ago.
Interesting. No mention of that on Wikipedia.
<Furiously typing GDPR data request..>
[flagged]