I am thinking about the architecture of a phonegap game app which, as lots of ditributed game app, will act as a client of a server. It will need username-password authentification. I plan to use AJAX to communicate with my server. However, I have a couple of questions concerning security. Here they are:
How can I make sure the request is made from my game and not by anyone else ? For example, how to avoid that somebody can send a POST request to the script on the server called by my game ?
How can I secure data transfer ? Is data transfer using a https (SSL) url sufficient ?
What is the best idea to implement user authentication ? Generate a token to use in communication ? Something else ?
Thank you !
1) How can I make sure the request is made from my game and not by anyone else ? For example, how to avoid that somebody can send a POST
request to the script on the server called by my game ?
Unfortunately, you can't. Because you have no control over the client code once it leaves your hands, there is no way to ensure that no one else is making requests using the login credentials of your users (assuming there are some). You can ensure that certain users are accessing your server by requiring them to authenticate. As long as they don't compromise their credentials then you can be sure. If authentication is not an option, see this question for some ideas about making it harder (but not impossible) for someone to imitate your client.
2) How can I secure data transfer ? Is data transfer using a https (SSL) url sufficient ?
Yes. Use HTTPS/SSL/TLS. This provides both confidentiality and integrity through encryption.
3) What is the best idea to implement user authentication ? Generate a token to use in communication ? Something else ?
A token is a good choice. See this question for some information about token implementation. This is for a RESTful service but basic approach is the same.
Related
How would I go about deploying a web app intended for only a single user (myself)? I feel like making a login that only accepts 1 user is the wrong method and also easy to hack? Would it be a good idea to make it only accessible from a certain IP? Please advise! Thank you. Backend will be using nodejs.
If I were you, I would program the back-end the proper way. This involves generalizing the entire implementation so that any hypothetical user with the correct password could use your login system. You could still authorize and authenticate the application so that when anybody else tries to log in, you automatically decline their request. If you are concerned about security, ensure that you are using SSL, basic encryption, hash passwords and, most importantly, do not use your own authorization library. It is far more secure if you use OAuth instead of using an IP, for example. Last, but definitely not least, make it as hard as you can for hackers to steal your data in the client side. This way, you also learn a lot of things that might come in handy in the near future.
I'm developing both server and client side of a web application and it is almost finish. Now, it is time to secure it.
I read lots of articles and Q-A sites to understand the principles of the concept. But there are still question marks on my mind.
There is a similar question here:
How do I secure REST API calls?
They suggested to use token-based security system, which is very common and practical way. Also services like Firebase, Auth0 are providing this security system.
And this is about "how and where to store token": https://auth0.com/docs/security/store-tokens
If so, how can token protect server from fake-calls while we are storing it in the browsers local storage?
Explaining it with an example in order to be clear:
My client-side code has a form with options. One of the option can be selected via drop down option and there are only "1,2,3,4" in those options. So that, client can never send a form with "5" value to the server. But what if someone use a API tool (for example postman) to send a form with a value of 5? Attacker still can add a token to that request. First login to system as normal user. Than open the developer console of the browser, copy your token and paste to the header of your fake-request.
Not allowing the cross origin calls may solve the problem. But I am not sure if this means server and client should run on the same domain (or host)?
Bonus from stackoverflow: Stackoverflow's use of localstorage for Authorization seems unsafe. Is this correct else how do we strengthen it?
They are also discussing the similar question from another aspect. (Not for the server security but for the user's security.)
Not related but in case of need: front-end is developed with Angular 5, server is developed with Java and Spring Framework.
I have written an app with Phonegap which can be used by multible users. The app itself have to communicate with the same server.
So there are many users connection to the same server, however there is a problem, the security between the clients and the server, is atm "plain text".
I believe its called Cross-Origin Resource Sharing (CORS).
I am not sure how to make the connection between all those clients and the server secure.
What i want to achieve is
Make the data encrypted, so that no one can easily sniff the data.
My idea so far is
Use ex. sha1/md5 or a selfwritten encryption algoritm, with some SALT added and maybe an extra key. Implement that encryption algoritm on both the clients and the server, and encrypt/decrypt on the fly.
I have already added a PHP line to get it to work, but that dosent make it secure:
header('Access-Control-Allow-Origin: *');
I would like some advise on my thoughts, would my idea work, or is something else required?
thanks in advance.
Don't reinvent the wheel :) Simply use HTTPS to encrypt all your HTTP data.
Let's say I have 2 servers (server and authenticator), and I have a client. My end goal here is to be able to identify the client on server. My solution was to come up with a token/secret system like OAuth: client has a token and secret. It passes it to server. Server passes it to authenticator. If valid, server allows the request.
Obviously, this is nonoptimal just for the number of requests being made. The reason authenticator and server are separated is because this is for a decentralised service-- any number of servers may be used, and it's impractical to ask client libraries to register on each server.
So, the question remains, what's the best/correct way to do this? The goal is to create a system that is decentralised, but can still have clients identify themselves in a relatively secure fashion to the server.
Disclaimer: I'm not a security expert so I could be off-base here and in actual implementation there seems to be a number of security issues that would need to be ironed out.
In the broadest sense, could you have the client supply credentials to the authenticator and then upon verification the authenticator supplies the client and the server both with matching security tokens and then the client and server can communicate directly?
Just curious about there a reason you don't want to implement OAuth and run your own OAuth server.
Additional reference: http://groups.google.com/group/37signals-api/msg/aeb0c8bf67a224cc
Turns out the solution was to define my problem a bit better. As I'm only trying to create a way to block applications, I only need to store their name and key when they request the server. Then, as long as they're not blocked and the key matches the one in the datastore, they'll be identified. So I'm not trying to authenticate so much as identify. Thanks for the input!
My API (a desktop application) communicates with my web app using basic HTTP authentication over SSL (Basically I'm just using https instead of http in the requests). My API has implemented logic that makes sure that users don't send incorrect information, but the problem I have is that someone could bypass the API and use curl to potentially post incorrect data (obtaining credentials is trivial since signing up on my web app is free).
I have thought about the following options:
Duplicate the API's logic in the web app so that even if users try to cheat the system using curl or some other tool they are presented with the same conditions.
Implement a further authentication check to make sure only my API can communicate with my web app. (Perhaps SSL client certificates?).
Encrypt the data (Base 64?)
I know I'm being a little paranoid about users spoofing my web app with curl-like tools but I'd rather be safe than sorry. Duplicating the logic is really painful and I would rather not do that. I don't know much about SSL client certificates, can I use them in conjunction with basic HTTP authentication? Will they make my requests take longer to process? What other options do I have?
Thanks in advance.
SSL protects you from the man-in-the-middle attacks, but not from attacks originated on the client side of the SSL. A client certificate built into your client API would allow you to identify that data was crafted by the client side API, but will not help you figuring out if client side manually modified the data just before it got encrypted. Technically ssavy user on the client end can always find a way to modify data by debugging through your client side API. The best you can do is to put roadblocks to your client side API, to make it harder to decipher it. Validation on the server side is indeed the way to go.
Consider refactoring your validation code so that it can be used on both sides.
You must validate the data on the server side. You can throw nasty errors back across the connection if the server-side validation fails — that's OK, they're not supposed to be tripped — but if you don't, you are totally vulnerable. (Think about it this way: it's the server's logic that you totally control, therefore it is the server's logic that has to make the definitive decisions about the validity of communications.)
Using client certificates won't really protect you much additionally from users who have permission to use the API in the first place; if nothing else, they can take apart the code to extract the client certificate (and it has to be readable to your client code to be usable at all). Nor will adding extra encryption; it makes things much more difficult for you (more things to go wrong) without adding much safety over that already provided by that SSL connection. (The scenario where adding encryption helps is when the messages sent over HTTPS have to go via untrusted proxies.)
Base-64 is not encryption. It's just a way of encoding bytes as easier-to-handle characters.
I would agree in general with sinelaw's comment that such validations are usually better on the server side to avoid exactly the kind of issue you're running into (supporting multiple client types). That said, you may just not be in a position to move the logic, in which case you need to do something.
To me, your options are:
Client-side certificates, as you suggest -- you're basically authenticating that the client is who (or what, in your case) you expect it to be. I have worked with these before and mutual authentication configuration can be confusing. I would not worry about the performance, as I think the first step is getting the behavior your want (correctness first). Anyway, in general, while this option is feasible, it can be exasperating to set up, depending on your web container.
Custom HTTP header in your desktop app, checking for its existence/value on the server side, or just leveraging of the existing User-Agent header. Since you're encrypting the traffic, one should not be able to easily see the HTTP header you're sending, so you can set its name and value to whatever you want. Checking for that on the server side is akin to assuring you that the client sending the request is almost certainly using your desktop app.
I would personally go the custom header route. It may not be 100% perfect, but if you're interested in doing the simplest possible thing to mitigate the most risk, it strikes me as the best route. It's not a great option if you don't use HTTPS (because then anyone can see the header if they flip on a sniffer), but given that you do use HTTPS, it should work fine.
BTW, I think you may be confusing a few things -- HTTPS is going to give you encryption, but it doesn't necessarily involve (client) authentication. Those are two different things, although they are often bundled together. I'm assuming you're using HTTPS with authentication of the actual user (basic auth or whatever).