A simple method to secure a simple read-only API - php

I have built a simple read-only API for our database, so that users can retrieve data from our database.
For example, the URL "http://xxxxx/getAllProfiles" will return a JSON result containing all profiles stored in the database.
The API is read-only, it is only implemented with some 'select' SQL queries. Thus the user cannot modify any of the data in the database via the API.
My company worries the API will be exploited by some random bots online, and has been asking me to build a security mechanism for this API. (It is worried if there is no key or something that prevents anyone from accessing the URL, our server would be visited too much. It is a small server.)
What would be the simplest secure mechanism that I can implement, using PHP? (We are also using Slim for the API, Amazon EC2 server with Ubuntu and Apache running on it, if this helps.) Preferably it can be implemented without the use of any database on server or client side.
If there's anything not clear, please let me know, I'll clarify.
Thanks.
Add:
Thanks for the comments.
Is there a way to NOT use a database? Like a smart way to generate a key or something... I'm thinking I'll provide a page so that user can input the domain, and an algorithm will convert this domain to a key. Then, for each request, the user should include this key. The server will grab the domain from the request header and use the same algorithm to calculate again. If the two calculated key matches, the request is accepted. I think this, at a minimum level, ensures that at the beginning there must be someone to input the domain and get the key, thus filtering some random bots out?
I am not sure if this is secure (at all)? But it sounds to me like it can filter out something.

I posted this question when I know very little about web development.
There are many ways to secure a REST API, e.g. JWT, Cookie, Basic Auth, etc.

Related

RESTful API Authentication & Security

I am developing an Android and iOS application that will use a RESTful API that I developed on a separate server. The applications will simply poke at the endpoints to update data within the database and to retrieve information when needed. My problem is not doing that, the architecture of the API is already setup I just need to think about the most secure way to implement it.
I have an API Key system that requires any uses of the API to be paired with the requests which will prevent anyone without the key from accessing the API. This works well, but I am worried about people who are more determined to break through the system. Specifically on the Android side, applications can be decompiled and (some) of the code can be viewed. I am pretty sure that strings can be viewed so I am worried that if someone decompiles the application they will get ahold of the API Key and be able to access the API.
I am looking for suggestions to make the API more secure. I have already considered pairing another unique value with the API Key when updating information but I am not sure if this will work that well either.
Any suggestions are very appreciated it.
You are right about being worried that your application can be decompiled. Code and strings are stored in the clear. In fact this is rather trivial to do.
I've heard that someone looked at two applications: one contained email service password and username in clear text, very useful for spammers. Another had its "random" number algorithm exposed allowing hackers to generate today's "random" number and ride for free using public transport facilities.
You can raise the bar by:
Obfuscating your code with tools. Some tools will offer capability to encrypt strings.
Manually encrypt sensitive strings in your application using new encryption key per new install, split your encryption key and hide it in several different places, e.g. part in code, part in a database, part in OS and apply ACL to external locations
Use transport security (e.g TLS) to reduce risk of man-in-the-middle attacks
Use API rate limiter on the server side
Introduce geo location services to see if same API key is used from different locations at the same time

How can I make sure only my phonegapp ajax posts will be executed by php

I am trying some stuff out with phonegap and I had a question concerning the security that I cant figure out.
So lets say I want to add something in a db. I let phonegap do an ajax post to a php file on a server with the vars and this php file will insert it in the db.
But anyone who would know where this php file is located and knows the data it wants can do an ajax post and insert data right?
I was reading about giving the php api a token. But I also was reading it is very easy to decompile a phonegap apk so it wouldnt be hard to get this token right?
So how can I make sure the php file on the server only accepts posts made from my phonegap app?
You can't. There is no way to guarantee they only come from your application. You can however ensure any calls come from a specific known user of your application.
You have an untrusted client with which it is impossible to embed a secret within without compromising the secret. You can make it harder, such as encrypting your JS and packaging it encrypted, then relying on Apple's DRM to secure your key, but for someone vaguely determined that will not stop them. Your AJAX end point exists and as the insecure client needs to communicate with it somehow there will always be a way to discover the client's secret.
However, typically this isn't an issue. What you can do, is exchange a secret with the client that is tied to a single user so that any calls to your API are on behalf of that user, and that user only (presuming that secret is kept secure - they don't lose their device etc). You can then use this secret to either encrypt or sign your outgoing AJAX call. This ensures someone can only affect their own account (e.g. only update their own account, only upload content tied to their account etc), and can't make arbitrary calls on behalf of other users.
This is enough for many types of application - though you haven't provided any detail about what your AJAX call does. No one is going to deliberately leak their own "personal" secret (though if theft is a concern, or you have higher security requirements then you could implement 2FA or more).
Personally, if this was anything non trivial, I wouldn't advise rolling your own system anyway. Security is difficult to get right, and there are many existing authentication systems out there (e.g. OAuth2) which have been tried and robustly tested in the wild.

How to secure a php based webservice

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.

How do I authenticate users with a site API?

I want to build an API for users to build applications that easily interact with a site, and I was wondering what the best way to authenticate users would be.
Taking a look at other API's a lot of them have the user send the username and password as a GET parameter over a HTTPS connection. Is this the best way to go about it? Or are there other methods that I should look into or consider?
I've seen OAuth been tossed around and it looks like a good solution, but just for a simple API is it overkill?
You can use API key's. Generate a unique hash tied to an account upon request. Then check that the key is a valid key. As long as the API doesn't have any major security issues with someone using someone else's key then Authorization isn't needed. If there is a problem with someone using someone else's key then Authentication would be justified.
This is usually achieved with cookies.
The client sends their username and password with a POST request to your API (do not use GET, that's insecure). If the credentials are acceptable, then generate a random, unique session key, store it on your side and send it in a cookie back to the client (see setcookie()).
When the client now makes further requests, they send the session key cookie with the request. Check $_COOKIE for the session key if it matches a stored key on your side; if yes, that means the user authenticated.
Take note that this minimal example is vulnerable to brute-force attacks trying to guess valid session keys. You need to log invalid keys that clients send in their cookies and block their IP address for some period of time to prevent this.
Username / password in a GET isn't a great way to do this because you're potentially exposing the whole user account for hijacking even if the API has more limited functionality than logging into the site. So it's good practice to separate concerns between Web-site login and API access.
I'm not sure which case you're in but:
If the users are business customers of somekind who are embedding some type of widget or code in another website then it's probably best to use an API key which is scoped to the referrer domain (much like Google Maps does).
If they are end-users who won't know anything about the API but are going to be using Apps built by third parties then oAuth is likely to be your best bet, otherwise your users might literally be giving their usernames/passwords to unknown third parties. It's more complex but likely to be worth it in the long run.
To get a bunch of this stuff out of the box you can use something like 3scale (http://www.3scale.net) and it'll handle most of it for you (disclaimer, I work there so adjust for bias!) or there are open source libraries for oAuth in most languages (in PHP Zend-OAuth component might do the job for you).

simple authorisation in web api

I want to make nice and clean api; I'm making site and I want to offer the ability to mobile apps use web API of my site.
I don't want to use oAuth, becouse the mobile and embedded applications that are facing the biggest hurdle, as they may not be able to bring up and/or control the web browser. Also its a little complicate.
I know, that HTTP basic authorisation is not safe, but it's so simple... I want to use it in my api.
I have somee users logins and their passwords (md5-encoded) in mysql base, but how to use those data in this HTTP basic authorisation?
Generate a random unique string for each user in your database and make that string available to the end users. When they access the api ask them to enter that unique string that you supplied--this is their 'key'. Each time a users app accesses the api they pass the key which links directly to a unique account and that is how you authorize them. It is essentially user name and password all in one.
While the above example is generic you should also take things like security into account--for example, when possible, pass the device ID from the mobile along and use that during authentication, or use their current password hash during their API key generation so if they change their password the key will stop working and they have to get a new one--this way they can control access if their key is lost.
It doesn't have to be complicated, it just has to be safe. =)
The PHP manual has an example
Jus google your question "PHP HTTP basic" and here you are
http://php.net/manual/en/features.http-auth.php
it is as simple as sending a few HTTP headers.
Also note that digest authorization considered to be more safe but less compatible with clients.

Categories