How do I secure an API by only allowing trusted domains? - actionscript-3

Question
How do I secure an API by only allowing trusted domains?
Details
I am building a REST API. I need a way to distribute API Keys but only allow them to work from the domain they are registered with.
The main issue is my API Key needs to be embedded in a Flash File which can easily be decompiled to steal the API Key. If Flash makes this impossible I can use Javascript instead.
I have heard a lot of people say use $_SERVER['HTTP_REFERER']. But that is easily spoofed.
How do I build an API that makes sure a request is coming from an allowed domain?
How do I create an API key that is tied to a domain?
How do I secure an API by only allowing trusted domains?
Related Stackoverflow Questions:
These questions are related but didn't quite answer my question. Figured I would just put them here for future reference.
Google API Key and Domain Check
How does Google Maps secure their API Key? How to make something similar?

JavaScript won't help you here - the problem is that the key is being stored on the client, which means that it is not secure. You can make it a bit more difficult for an attacker certainly (e.g. like you say checking the referrer), but at the end of the day all the server can verify is that the key is correct, and since the key can easily be stolen that's not very helpful.
The way this can be secured is by having the private keys run on the servers of whoever you are giving them to instead of in the client. Depending on your needs, this may not be feasible.
One possibility to make it a bit harder for attackers is to use the site-locking technique to only allow the SWF to call the API if it is on an appropriate domain. See http://blog.boogatech.com/as3_tutorial_site-locking_your_flash_project/ for an example. Please note however, that this is client security - the goal with sitelocking is usually just to stop people from playing your game on other sites (and even then it can't stop the most dedicated of attackers). In your case you are dealing with server security - the server doesn't know about the SWF, all it knows is the arguments it is being fed, so an attacker can just bypass the SWF and the client security and call the API from somewhere else.
I'd advise you to think about what attack and attackers you are trying to prevent (why do you have to tie API keys to a domain?). This will help you plan your security attempts better. For instance, if you are not running an ultra-critical API, you can decide that putting in a couple of things to make it harder for attackers to access the API is acceptable, with the knowledge that you can't stop an extremely dedicated attacker.

Related

AES128 with HLS Streaming

I am newbie in using Streaming Server. we are evaluating EvoStream Media Server to stream HLS stream with AES128 encryption.
I have few queries on AES 128. I have search through google but no luck
When doing HLS with VOD(Video on Demand) , Evostream creates chunks of segments along with m3u8 index file that contains all information including key and IV vectors.
#EXT-X-KEY:METHOD=AES-128,URI="2015-06-25T11-20-18.key",IV=0x0360f11b211ef025d7f72c41d58e0a2d
My question if when i play this file in html5 media player and debug it using F12, i can easily get the key and IV used to encrypt the file. Then what is kind of security AES provide if anyone can get those key and IV vector to decrypt the data.
Please any one have some knowledge over it, please share ...
The key seems to be in yet another file:
URI="2015-06-25T11-20-18.key"
2015-06-25T11-20-18.key is only a reference to the key, not the key itself.
So you need to control access to the file and only make it available to persons that are allowed to play the video.
The answer to your question is that HLS with AES-128 provides transport security making it difficult for someone to capture your content in a man-in-the-middle scenario. It doesn't provide DRM.
You are supposed to change the keys every 3-4 hours and the IV every 50 Mb of data and serve the keys over HTTPS and not plain HTTP.
See Serving Key Files Securely Over HTTPS on the Apple Developer site.
The first thing, that you have to keep in mind when dealing with content protection, is the fact that there is no perfect solution. There is no solution to guarantee you that only the audiences that you intended will be able to watch the video. All the protection schemes make it harder for the others to steal it but not impossible. Here are some of your options:
AES-128 encryption - you have to take special care to protect the key. Once the key "leaks" then anyone will be able to decode the video with some effort. The advantage is that's this method is simple and supported by the multitude of players.
SAMPLE-AES encryption - again you have to take care of the key. But even if it "leaks" one would need a specialized software to decode the video as it's not trivial. The disadvantage is that not all players support this method.
use DRM - DRM solutions are very expensive and require effort for integration and specialized players. But they provide the most protection.
There is no silver bullet. It depends on you needs and the level of protection you need. Don't forget that after all even the most advanced encryption scheme is not protected against simple things like screen capturing for example.
In normal case or a general use case
1. You can continue to use AES-128 as the encryption mechanism
2. Use HTTPS to provide the transport security.
3. Use token/cookie to authorize the user
(The cookie/token should be sent to the key server and the key server validates it before delivering the key)
Above 3 steps provide you the content protection, transport protection and to authorize users.
To answer your second question,
Authorized users with right tokens will be able to download the contents and keys to decrypt it. (There are plenty of tools to do it) you need a custom client to avoid that and html5 supported browsers cannot stop that.

rest api for 3rd party customers (AAA)

I am currently working on a REST/JSON API that has to provide some services through remote websites. I do not know the end-customers of these websites and they would/should not have an account on the API server. The only accounts existent on the API server would be the accounts identifying the websites. Since this is all RESTful and therefore all communication would be between end-user browser (through javascript/JSON) and my REST API service, how can I make sure that the system won't be abused by 3rd parties interested in increasing the middleman's bill? (where the middleman is the owner of the website reselling my services). What authentication methods would you recommend that would work and would prevent users from just taking the js code from the website and call it 1000000 times just to bankrupt the website owner? I was thinking of using the HTTP_REFERER , and translate that to IP address (to find out which server is hosting the code, and authenticate based on this IP), but I presume the HTTP_REFERER can easily be spoofed. I'm not looking for my customer's end customers to register on the API server, this would defeat the purpose of this API.
Some ideas please?
Thanks,
Dan
This might not be an option for you, but what I've done before in this case is to make a proxy on top of the REST calls. The website calls its own internal service and then that service calls your REST calls. The advantage is that, like you said, no one can hit your REST calls directly or try to spoof calls.
Failing that, you could implement an authentication scheme like HMAC (http://en.wikipedia.org/wiki/Hash-based_message_authentication_code). I've seen a lot of APIs use this.
Using HMAC-SHA1 for API authentication - how to store the client password securely?
Here is what Java code might look like to authenticate: http://support.ooyala.com/developers/documentation/api/signature_java.html
Either way I think you'll have to do some work server side. Otherwise people might be able to reverse engineer the API if everything is purely client side.

Security: Achievement and score API in AS3

Over the years I've become an uber-nerd when it comes to flash game development. Now I'm thinking about looking into using my skills for helping other game-developers out there.
I want to develop an API in AS3 which will allow the developer to do (as a start) the following:
Display a dialogue which lets the user log into their "account" (hosted on my site).
Send a score/value to the website and attribute it to the logged in user.
Unlock an achievement (achievements will be set up by the developer in the web interface - which is where they will also get a key of some type to use with their API.
Display high scores, other players profiles in-game, etc (show basically any stats in-game).
All easy enough to develop straight off the bat. However; where it becomes frustrating is security. I'm not expecting an indestructible solution that I'm fully aware isn't possible, but what would be the most defensive way to approach this?
Here are the issues that I can think up on the spot:
The big one - people stealing the API key via man-in-the-middle attack.
Highscore injection, false achievement unlocks.
Decompiling the SWF and stealing the API key.
Using the API key to create a dummy flash application and send random data like highscores.
Altering the API itself so you don't need to be logged in, etc.
One thought I've had was converting my API to a component so there's no access to the code (unless you decompile). The problem here is it's just not friendly to the developers, though it would allow me to create my own graphics for the UI (rather than coding many, many sprites).
Private/public keys won't work unless there is very good protection against decompiling.
I'm beginning to wonder if this idea is a dead end.
Any advice on securing this (or parts of it) would be great.
Look at this thread first if you haven't done so already: What is the best way to stop people hacking the PHP-based highscore table of a Flash game
Against man-in-the-middle HTTPS seems the only option. It may have its vulnerabilities, but it's way better than any home-made solution. The problem that you'll need actual certificate from authorized center, because ActiveX-based Flash plugin will not trust self-signed certificate.
Should not be possible without decompilation
SecureSWF with reasonably high settings (code execution path obfuscation and encrypted strings) should beat most decompilers. Sure, SWF can be examined with hex editor, but this will require very determined hacker.
Should not be possible without decompilation
API should be on server and any API function would require user context (loaded by HTTPS)
Also add encryption to flash shared objects\cookies. I had successfully altered some savegames using simple hex editor, because they were just objects in AMF format. Encryption will depend on SWF decompilation, but since we are using SecureSWF... Or move savegames on server.
client side is never secure enough, so i'd suggest to take all the logic to the server, reducing client to just UI.
If it's impossible due to network timeouts - send scores/achievements only with the log of pairs "user_action - game_state" and verify it on the server.

How to implement a single sign-on authentication server?

I want to implement a discrete remote authentication server that handles login for many sites. Somewhat similar to OpenID.
Basically, I have site-1 and site-2 and they're both reliant on the same user database, which is on a separate auth-site. So, auth-site handles user authentication for them, and during this process, makes information on the authenticating user available to the requesting system.
Each site can be on a completely separate domain name, on completely separate machines.
This is all via HTTP(S), there can be no direct database access.
There's one last quirk: once an user has logged in to site-1, when accessing any other site reliant on auth-site, the site must treat the user as already authenticated.
This whole business must be entirely fuss-free to the end-user. It should work like a simple everyday login form.
As a concrete example, say we're talking about stackoverflow.com and serverfault.com, and they both authenticate via authentic-overflow-server-stack.com. Again, once logged in to either site, I can go to the other and do my business without logging in again.
What I'd like to know are the general interaction mechanism between the sites behind this scenario.
In my particular setup, I'm using Rails, but I'm not looking for code[1], just general best practice and guidance, so feel free to answer in pseudo-code or any generally readable language. OTOH, bear in mind that I'll have decent MVC, REST, and meta-programming in my toolkit.
[1]: unless you happen to know an existing tiny neat free MIT/BSD-licensed app/plugin/generator that handles this.
It sounds like (especially with the emphasis on fuss-free), you want something like what the Wikimedia Foundation is doing. Basically, you log on to en.wikipedia.org, then that server communicates with other servers (e.g. en.wikinews.org) and gets authentication tokens. Finally, those tokens are embedded into images, e.g. http://en.wikinews.org/wiki/Special:AutoLogin?token=xxxxxxxxxxxxxxx , and when your browser visits that url (img src) it gets a authentication cookie for Wikinews. Of course, the source code is available for your reivew at http://www.mediawiki.org/wiki/Extension:CentralAuth .
OpenID is also a good choice, but it does require that the user "consciously" visit two domains. An example of one entity with two domains doing this is Canonical. E.g., if you go to https://help.ubuntu.com/community/UserPreferences they will redirect you to Launchpad (https://login.launchpad.net/+openid) for authentication.
Note that Wikipedia is doing this over http, but you can do it all https to ensure the img src tokens aren't intercepted.
Looks like CAS is good enough for me, and has ruby implementations, along with dozens of other lesser languages, e.g. one that rhymes with femoral bone rage.
http://code.google.com/p/rubycas-server/
http://code.google.com/p/rubycas-client/
It sounds like you want to actually use the OpenID protocol itself. There's no reason you can't restrict the authentication provider to only your own server, and do some shortcuts that make the authentication process transparent. Also, the OpenID protocol supports what you describe about logging into one implies logging in to all services.

How to prevent ActionScript code decompilaton

Is there a reliable way of preventing my actionscript code (as2 or as3) from being copied (e.g. if there's some IP in it)?
I know there are tools that can decompile flash code so it's easily reverse-engineered and I've also seen a few tools that claim to be able to obfuscate actionscript code in such a way that it's not steal-able, but I wonder how reliable they are...
Do you know? Thanks!
It is by definition imposible to prevent it.
The reason is simple, the code needs to run on the client, so the client needs to be able to read it.
The best you can do is to make so hard (time demanding) to do that it's not profitble.
Flash has a built in feature to protect againt decompiling with a password. I'm not sure exactly how it works, I guess some form of encryption.
You can try and spil sensetive data up and join it at runtime, og encrypt it and get the descryption key from the server.
But in the end there's nothing you can really do. Unless you wan't the users to input the encryption key (password or a file).
There is no build in encryption in Flash but there is a couple of free librarys like crypto lib http://code.google.com/p/as3crypto/.
I've found no reliable and sustainable way to obfuscate the code. If there's a way to obfuscate the code, I'd bet that:
it would affect the performance of your code
it would be just a matter of time before someone makes/finds a decompiler for that obfuscation method
I wouldn't consider a good practice to rely on the security of your client code. Even if the code couldn't be decompiled, the swf is run on the client and communicates with the Internet via a network connection the user has access to. The packets can be sniffed and all the data that's being transfered can be easily analyzed.
I think you should find a way to develop a secure application, even considering that the client knows everything you do. You should try to use server-side constraints and filter all inputs before using them. Also, requesting all the sensitive data from a server-side script, instead of embedding it in your AS code could be a good start.