I'm creating my first API in PHP for a demo, so it's not going to be used in real world. As a part of my demo I need user registration and authorization. As this is a demo I don't need much security but I don't want just to pass the users credentials in the request url either.
I like the solution suggested in the answer to this question Building Secure Public API with PHP/MYSQL. But it's unclear how we should pass the password to the server when the user is registering for the first time and what we should store on the server (e.g. the password itself?)
Also if anyone could just suggest anything else, I'd appreciate it. I'm completely new to this and a little confused after having read a lot of articles on the topic for the last few days.
Related
I'm developing one android application and I'm creating a php based webservice to retrieve the information from the database.
The thing is that I really don't know how to secure this service.
For example, if my android application needs to retrieve some information from the server it will call http://mywebservice.com/service.php, and it will send several POST parameters as the user and password to login, or something like, for example, one user id to retrieve his data.
Of course, anybody with the knowledge enough will be able to retrieve that data too. And this is what I don't want to happen.
Anybody who know the parameters to send to my server will be able to retrieve information from it.
How can I secure this?
I've been reading about OAuth, OAuth2, two legged and three legged implementations of it, https..
But at the moment, I really don't know how to secure this.
I want that the webservice only answer to my application and not to anybody else.
PS: Even there is something like http://myservice.com/get_information.php that you send an id and you can retrieve a lot of information. Of course, I control that in my application, only logged and authorized people can do that calling, but it's a problem anyway. What's the best way to do this kind of things?
Some concepts to secure a webservice(might be forgetting some notions):
Protocols: HTTPS in the current case so data are not transfered in a clear format.
The Sessions: A session has a lifetime, a unique identifier(session token/id/whatever) and contains an error code. When a user will call your webservice, a session will be created and its token answered back. At every call of the webservice you'll test if the session is still alive. You can add complexity to the expected inputs, outputs and exchanges. The error_code will be used for logging(errors can come from an attack or a bug of your webservice).
Data Encryption: Use asymetric functions like password_hash() or crypt() for authentication issues. Use symetric algorithms like AES 128(10 rounds) or 256 (14 rounds) for sensitive data you'll need to retrieve.
Testing inputs: If you find yourself inserting given arguments in a query, try to prevent SQL injection. Some bad-minded people can also try to send arguments which would make your webservice fail.
Go for standards: As Çagatay said, try to implement for example oAuth2 because standard is most of the time much better than what we'll build :S
Hope it helps.
edit: The REST security sheet is good also.
Always use SSL to prevent some man-in-the-middle attack. Otherwise someone that sniffs the connection (in case of connecting via public wi-fi or company networks it's a huge risk) can see the username and password.
Do not send username and password on each request, instead implement oAuth2, your client in this case will have to send the username and password only once and then for the other requests you'll have to send only the auth key. Good documentation for implementing a oauth server: http://www.sitepoint.com/creating-a-php-oauth-server/
Look at this document: https://www.owasp.org/index.php/REST_Security_Cheat_Sheet
I ended using OAuth. More especifically this library https://bshaffer.github.io/oauth2-server-php-docs/
If you follow the instructions it's really easy to use and it works very well. I think it's a really good way to start working with OAuth.
im not sure of which way to take with a REST API im currently developing using CakePHP, i haven't implemented authentication and until now that im almost done with it i'm reading about it,
but i'm not sure of what should i do, this API would be exposed so that a webpage and a mobile app can consume it, but i dont think Basic auth or Digest auth (which come as default options in CakePHP) are the option,
i only know that i need it to check username and password from the database, and grant permission according to an ACL that is already set up, i was reading something about HMAC but dont understand it completely, should i make an authentication method on my own that does something like check a token? is this article correct? : http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/
and if so, how do i implement those principles to the CakePHP auth method? is there a plugin for this auth method using HMAC?
should i use OAuth 2.0? does it make sense to use OAuth 2.0 for a username & password login? am i too lost? if im not so lost, could you please describe how to implement OAuth with username and password in cakephp?
someone, please, anyone surfing this interweb forum, HELP ME. if you could provide examples or workflows, anything, everything will be greatly appreciated.
How much security do you need? As an API is usually accessed from a client app which has the keys, it's usually OK to send the credentials along with every (https) request (as POST parameters, so they'll be encrypted). At least, this is by far the easiest solution: You just check the credentials with every request, without any sessions, tokens and the like. If the credentials are valid, you check whether that now authenticated 'user' is authorized to access the requested resource(s).
Remember that more advanced authentication/authorization methods quickly become complex in development and management. If you don't have any experience in implementing such systems, it's rather likely you're obsoleting the possible security gain with implementation bugs/issues.
I have written the registration page in my CodeIgniter application. Everything works fine, and it's using the PHPass library for password hashing.
Now, I want to write the login part of the system, and was wondering how exactly I'd go about doing this with CodeIgniter. I'm mostly confused about the correct (and best practice) way of doing it. Do I just accept the users login credentials, determine if they're correct and if so, set up a session for that user? Do they need a cookie? Does that cookie need to be encrypted? Do I need to track the user in my database (CodeIgniter can do this for me) and watch for IP address changes or hostname changes?
There are many many auth libraries but since you are a beginner I strongly believe that it's better to make something on your own (unless you are on a very strict time frame). Because, as my colleague once told me, without making a mistake you won't understand why better solution is actually better.
Back to your actual question.
Do I just accept the users login credentials, determine if they're correct and if so, set up a session for that user?
Well, yes. There is no other reasonable way to do it, is there? :)
Do they need a cookie?
Session ID is stored automatically in a cookie. You can store other options in a cookie, but have in mind that cookies can be stolen (so it's NOT a good idea to save username/cookie). Plus people use more than one device (e.g. tablet and desktop) more and more so be sensible about using cookies.
Does that cookie need to be encrypted?
I believe I answered that already.
You should probably start here with this: http://codeigniter.com/wiki/Category:Libraries::Authentication and http://codeigniter.com/wiki/Category:Libraries::Authorization
From CI Wiki: Authentication is different from Authorization.
Authentication answers the question “is this user who they claim to
be?” Authorization answers the question “given this user, are they
authorized to perform this action?”
Why don't you use one of the many CI auth libraries?
How should I choose an authentication library for CodeIgniter?
You can just have a look at the CI wiki for all the particular details you are after:
http://codeigniter.com/wiki/auth
I decided to refresh my site today with a pair of upgrades. One of them is referring availability. So, as I method of referrer recognition, I am going to use special URL with referrer ID in it (if there is some other but better method, feel free to let me know about it). After I implemented the basics of that availability, I made a decision to make the system more secure. With that, I mean hiding the referrer's ID. Now, I am here, looking for suggestion on how can I make it secure (hidden or encrypted), but still be able to decrypt it on the server-side. Don't suggest me to use Base64 encryption, it's too simple and everyone can decrypt it these days.
I could try making my own system of encryption, what do you think?
It depends on what you want to pass.
First of all don't pass info that is not supposed to be publicly passed.
Second, you could create a token, save that in the DB next to the user, and authenticate on that token.
That token could be something that is valid only for a few hours... you make the choice, what works best for you.
I'm currently building an API for a very busy internet website. Its being written in PHP with MySQL. Now this is my first API that i'm writing that allows people to access their account remotely. Once the API is online, developers will be able to write their own tools from it.
Now I have the API working, but I'm not sure if its entirely safe.
An example URL that would work is: http://domain.com/api.php?api_option=list&api_user_name=USERNAME&api_user_password=PASSWORD
USERNAME: would be the users actual username
PASSWORD: would be the MD5 encoded string of their actual password.
If the details match, a result is returned, if not, and error.
All external $_GET inputs get the mysql_real_escape_string() treatment.
I wanted to keep things simple, but I'm not sure if this way is a SAFE way of having a public API that taps directly into users accounts data.
Ideas and suggestions are much appreciated.
Please, for the love of the Internet, DO NOT DO THIS. I implore you to put the time into implementing OAuth for your API. Please. Please please please.
Take a look at this: http://toys.lerdorf.com/archives/55-Writing-an-OAuth-Provider-Service.html
Do not use a password for API clearance, even if it is encoded, especially if it is encoded in MD5. Furthermore I would not use the users username as well. Let the user generate a key. You are giving someone the ability to know 50% of what they need to know to access a user's account, and MD5 has a lot of sites that you can reverse it and find a password match. A key is certainly the best way to go so a developer could regenerate it further down the road for security purposes. Always think of security.
How about signing requests using HMAC_SHA1 and the user's password? For example, your URL: http://domain.com/api.php?api_option=list&api_user_name=USERNAME&api_user_password=PASSWORD
Add the timestamp and/or a random string (nonce) and build a normalized base_string:
$base_string = "api_option=list&api_user_name=USERNAME×tamp=1296875073&nonce=hgg65JHFj";
$signature = hmac_sha1($base_string, PASSWORD);
then the new URL would be:
http://domain.com/api.php?api_option=list&api_user_name=USERNAME×tamp=1296875073&nonce=hgg65JHFj&signature=kfvyhgfytgyr6576yfgu
What your server does is to get all the options, excluding the signature, then generate the signature using the same method and compare it to the signature sent by the client, which should be the same.
first of all,
You don't need to send the user's login credentials using the GET method.
You probably want to do that using the POST method so it can be hidden from the url.
then in your api backend, You can get it like this
$username = $_POST['username'];
$password = $_POST['password'];
Still though, what you've done so far is not any guarantee that you API is safe .
In order to provide a much more safer method, You probably want to assign AUTHENTICATION TOKEN to each user .
PS: dont know if this helps anyone lol