Hi all,
So I’m building a site for a startup idea. I’m trying to eke out the best performance on the lowest possible budget. Just found out about Cloudflare the other day and have been playing with it. So far so good! What they offer for free is pretty darn generous and awesome. Anyway, on to the issue:
I have an API endpoint which hits an external API and returns data to the frontend. Since this endpoint is used for validation of entries on a form, it needs to be public with no authentication. At the same time, I want it to only be used by legitimate entities (i.e. users filling out my form on the frontend). I put this endpoint up as a Google Cloud Function (GCF). This works pretty well, but as it’s an HTTP trigger, it leaves it wide open to anybody with the URL.
My idea was I can create a CNAME record for api.mysite.com -> https://url-of-actual-google-cloud-function.com/http and use firewall rules in Google to only allow requests from Cloudflare IP’s. I thought I could set it up so Cloudflare would transparently proxy the POST requests for api.mysite.com to my actual API endpoint and return results to the user. I have the CNAME record set up (api.mysite.com points to the GCF url without the trailing /http), but it’s not working quite right. Here’s what happens:
When I “orange cloud” it:
- https://api.mysite.com -> 404 from Google
- https://api.mysite.com/http -> 404 from Google
- http://api.mysite.com -> redirects to https://api.mysite.com -> 404 from Google
- http://api.mysite.com/http -> hits my endpoint, but browser url shows the redirect, hence leaking the url I wanted to hide. It would also break my idea of firewalling b/c requests would come directly from the client.
When I “gray cloud” it:
- https://api.mysite.com -> I get a Firefox security warning saying cert is invalid. Digging into that, I see it’s hit Google and is saying the wildcard cert is not valid. If I add a security exception, it 404’s from Google
- https://api.mysite.com/http -> security warning -> add exception -> 404 from Google
- http://api.mysite.com -> redirects to https://api.mysite.com -> 404 from Google
- http://api.mysite.com/http -> as before, hits my endpoint, but browser url shows the redirect
Is there something I’m doing wrong, or is the idea wrong even in theory? Is there a better way to do this? I have CORS enabled and configured to only allow mysite.com, but there’s nothing preventing someone using CURL or Postman and setting the origin header to mysite.com, so that seems like a bad strategy.
I’ve also thought of using an api key, but that’s only secure until people discover it in the frontend. I’ve also thought about a time-limited api key that would be stored in redis and checked for every request. This seems like it would work, but I wanted to know if there were commonly accepted ways of doing this first. Redis would also add processing time for each request, which is not ideal.
Thanks for reading. Would appreciate any feedback.