I have hit a snag while moving from cookie to token based authentication in my Ember/Angular/Backbone applications.
The snag is that request headers can not be set on img tags.
Some have suggested appending the token params to the end of the request thus littering server logs with auth tokens.
What (if any) is the proper way to access protected inline assets using token based auth?
Important Caveat: I am not a security expert (but I dabble)
In the past I've used Amazon S3 and their token based security for assets. These allows you to generate private and even temporary URLs for asset access. You could also implement a similar mechanism on your own server but keep in mind you will now be hosting and serving the assets yourself so keep that in mind for things like bandwidth use, caching, etc.
This post seems to have a pretty detailed tutorial on protecting images using AngularJS and Amazon.
If you don't want to go the Amazon route you'll need to implement some sort of token/security scheme yourself and there are a number of approaches you could take. It will largely depend on the level of security you want.
You could load the image data programatically without URL. It should be possible to use CSS and base64 data URIs to accomplish this. You could make an AJAX request for the data and populate the data URI. While this would be absolutely secure it would also be potentially inefficient.
You could use cookies to control access. As these will be sent by the browser when fetching images.
You can use a custom implementation of secure, tokenized URLs like https://host/secure_images/{tokenized_access_url}.jpg
. Just as S3 does. You can even make this token expire after a time.
Depending on your needs you may find some of these techniques hurt your ability to take advantage of caching. This is why using S3/Cloudfront may be the best choice in terms of security and efficiency.
The thing you should also ask is if these assets need to be protected against the URL being leaked. For many situations, simply keeping the asset url private (use a randomly generated value somewhere) and only showing it to the users with access, is a sufficient solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With