Hello,
This question is essentially an extension of the question at http://www.themoviedb.org/talk/505e1089760ee32de40000cf
Using the api key in javascript creates the security concern highlighted in that question. This concern is mitigated to an extent in my application as it is private and I know the people that will be accessing it personally. However, I prefer to build applications to be as robust and versatile as possible, which means that I must consider the security issue.
As with the person asking the question linked to above, my application uses asynchronous data loading and, as a result, must use javascript. In order to achieve this, I am aware of only two options;
Option 1 - Use a simple ajax api call with the api key exposed on the client side script
Option 2 - Setup an ajax request to a server-side script held on my server. Confirm that the user has a valid and open session. Relay the ajax query using a normal server-side api call and serve the json response back to the original ajax call.
Both options are simple enough. However, option 2 still presents the problem that someone could send ajax requests to my server-side script and they would, by extension, be able to use my api key. Further authentication could be introduced in addition to the session validation; such as automatically monitoring IP addresses, requiring a short-term hash key that expires at set intervals, validating the form of the query against the queries my application is designed to create, etc.
However, any authentication on an ajax request is simply obscuring the problem. It may be useful in deterring an attacker but a motivated attacker could simply decode or read through the javascript code and reverse engineer how to create a valid request. That being said, as api keys are free, deterring an attacker should not be particularly difficult as I simply have to convince them that it's better to request a key than trying to use mine.
So my question is how important do you consider api key security to be? If I proceed with option 2, regardless of whether I user additional validation, it does at least prevent them being able to steal the api key itself. In order to use it, they would still have to make requests to my server; which would allow me to monitor its usage and block any attacker's IP address.
Do you have any preference or opinion as to how I proceed?
My Kind Regards, Peter Scott
Can't find a movie or TV show? Login to create it.
Want to rate or add this item to a list?
Not a member?
Reply by amosjackson
on January 3, 2014 at 7:35 AM
Since the API is free to use, the only real problem with someone stealing your API key is that they can create an application whose requests come from yours (from API's point of view). I can't really think of a way of abusing the API (apart from perhaps trying to mount a DDoS attack) that could get you in trouble. On principle, it's good to hide your API key from users but, in this case, not doing so wouldn't be too much of a problem. If you are using the 2nd option and are worried about people making api requests, you could limit the server-side script to only make requests for certain parts of the API (e.g. search, movie/images) rather than using the client-side ajax request to spoon-feed the server-side script on which requests to make (e.g.
script.php?search=die+hard
instead ofscript.php?query=search/die+hard
orscript.php?query=movie/550/images
Reply by Travis Bell
on January 4, 2014 at 10:09 AM
In my opinion, it's all about how much you're doing with the API. For some basic film retrieval stuff do whatever is easiest. If you get into using some session and account features it might be better to put that in a server side executed script.
The only thing to remember is to properly set the users request IP and pass that through to the request your server makes. Our request rate limiting is only imposed by IP address, not API key.
Cheers.
Reply by Peter Scott
on January 5, 2014 at 8:49 PM
Thank you very much for your replies
I think you're right; without accessing account features, there's little protection required. In this case I will only be fetching film & actor information and, given the private nature of the application, the risk is negligible.
Still, it has been very useful to think through the problem thoroughly.
Thanks again.
Reply by matchlighter
on January 10, 2014 at 11:27 PM
@Travis: Sorry to reopen the thread, but what do you mean by "set the users request IP and pass that through to the request your server makes"? I'm trying to setup a Javascript side as well, forwarding it through my server to avoid exposing my api key, but if the server makes the request, wouldn't its IP be the one logged in TMDb's rate limiting?
Reply by Travis Bell
on January 11, 2014 at 10:04 AM
I need to double check with our ops team but I believe we should support the
X-Forwaded-For
header. You can read more about it here: http://en.wikipedia.org/wiki/X-Forwarded-ForReply by pnat
on September 13, 2020 at 5:21 PM
Can TMDB provide "domain-restriction" feature for the api keys we generate? This will reduce lot of support requests.
For example, key1 could be set to use "mydevdomain.org" -- if the api key is used from any other domain (e.g stolen), TMDB can just reject that request .
Google/others provide such security so a stolen key would essentially be useless. https://miro.medium.com/max/700/1*hZMO_rI-QmTJqs41e1H5dA.png
Reply by Travis Bell
on September 13, 2020 at 6:02 PM
Most users don’t have a website though, so sure, it will help those who do, but if we’re only able to secure ~5% of the requests, the overall net benefit is very small.
Reply by pnat
on September 13, 2020 at 7:26 PM
Is there a way to avoid apikey in url? eg setting some value in header?
https://stoplight.io/blog/api-keys-best-practices-to-authenticate-apis/
x-api-key The most popular choice, perhaps due to its usage by AWS API Gateway, x-api-key is a custom header convention for passing your API key.
GET / HTTP/1.1 Host: example.com X-API-KEY: abcdef12345
Reply by pnat
on September 13, 2020 at 7:35 PM
Thanks, was able to set bearer token in header https://developers.themoviedb.org/3/getting-started/authentication#bearer-token