How to securely connect to a web api from a AngularJS site - php

Being relatively new to web development, at least using client side technologies such as the AngularJS framework, I need to resolve a few queries before I can start my latest project.
I am writing an application using the AngularJS which reads/writes/updates data in a database. With javascript being client side I have chosen to write a PHP REST API to do the database queries, resulting in a secure username and password and a single database layer.
My question is, given my REST API, I will be using AJAX from javascript (which is client side) to invoke methods. How do I stop other sites from writing a script to invoke the REST API as well? Putting an authentication token in the javascript code isn't very secure, someone can just copy it.
Is a REST API the best approach for this problem? I am not adverse to learning new technologies or practices so please, any thoughts on better design patterns or methods of implementation are greatly appreciated. Unfortunately, due to my limited domain knowledge in this area, I have been unfruitful in my Google Searches as I'm not confident of the terms under which I should be searching.
Many thanks.

Since your Angular application is living in the browser, your REST API will need to be publicly accessible from any random visitor's browser. You thereby have a public API, out of necessity. You can't restrict it; either visitors can see the data or they can't.
Essentially this is not significantly different from a traditional webpage though. In a server-side generated page, you output your data packaged as HTML and deliver it to anyone who asks. In a REST-API/Angular app, you deliver the data packaged as JSON to anyone who asks. Either way the data is equally public, though maybe the REST API is a little easier to "abuse" than scraping the HTML would be. It may be useful to deliberate employing some user behaviour tracking and throttling, if you want to avoid someone outright sucking all of your database dry; this applies equally to JSON based REST APIs as it does to regular web pages.
If you're also exposing read/write APIs this way, you're of course wide open to abuse.
The only way to make an API non-public is to require password authentication. If the users of your site must be logged in, then you can restrict the API to anyone with a valid session. This doesn't help much in the grant scheme of things if anyone can simply register an account on your site, but it needs more deliberation and provides slightly more manageability than a completely open API.
Admin-only APIs of course must be protected in this way, requiring an account which only you have the credentials to.

Related

Symfony2 RESTful API + AngularJS

I've been working on an e-commerce project built on Symfony2 (for the backend) and AngularJS for the frontend. Currently the Symfony part is used only as an API, which has three different user levels (guest, customer & admin). Different actions that can be done within the system (like add/remove data) are secured by:
Symfony2 firewall with user roles/access control
JMS security extra (#PreAuthorize expressions)
For the parts that are secure everything works as intended and I'm very happy with the way things work.
Problem:
There are parts of the API which are public (like retrieving product information, categories, etc.). I'm retrieving such data in Angular with Ajax calls to my API that returns the data in JSON format. One example would be:
/api/product/get-all/?page=1&count=10&sorting[id]=asc
The problem is that anyone could look at the requests in browser and copy the path and have access to all the data (such as all the products) and could just download a JSON of all the information. Although this data is "public", I don't want to give others such an easy way of "stealing" my data.
Ideas & possible solutions:
I was looking at the JWT (Json Web Token) standard to try and secure the public calls to my API and implement it in such a way that I generate a token for "real" users that are on the website, and such limit direct access to public API links.
What do you think? Would this be a possible solution?
I was also reading in some other question on StackOverflow that I could check the HTTP_X_REQUESTED_WITH header from the request, but we all know this can be easily spoofed by an attacker.
Finally, I read a similar approach to "solution" 1) here : http://engineering.talis.com/articles/elegant-api-auth-angular-js/ but I'm not entirely sure that this fits my purpose.
Additional notes:
I don't want to make this bullet-proof, but I also don't want to give people the option to click 2 buttons and get all my data. I know that eventually all the information can be "stolen" (e.g.: by using a web scraper ), but "securing" the system in such a way that people would have to make a bit of an effort is what I have in mind.
I can't really re-model my API too much at this stage, but any ideas would be appreciated
Thanks for taking the time to read my question and I'm looking forward for any feedback.
You can limit the abuse of your system in a number of ways, including:
Limit the total number of requests that API will return before requiring CAPTCHA or some other validation method. This can be limited by IP, browser fingerprint, authentication token, etc.
Make it difficult for abuser to guess IDs of products, categories, etc. by using GUIDs or other randomly generated IDs.
Use API management proxy such as Azure API Management for more enterprise level management of the APIs (http://justazure.com/azure-api-management-part-one-introduction/)
You could try something like:
To access the site anonymous users first need to fill in the captcha to get temporary token.
Add referrer check on.
Limit amount of data anonymous users can view. For instance, first 50 products.
This way everyone who wants to steal your data first need to get anonymous temporary token by filling in the captcha and change referrer.
Try with DunglasAngularCsrfBundle

Hot to use the Basic Auth for REST systems with client in browser? [duplicate]

Being relatively new to web development, at least using client side technologies such as the AngularJS framework, I need to resolve a few queries before I can start my latest project.
I am writing an application using the AngularJS which reads/writes/updates data in a database. With javascript being client side I have chosen to write a PHP REST API to do the database queries, resulting in a secure username and password and a single database layer.
My question is, given my REST API, I will be using AJAX from javascript (which is client side) to invoke methods. How do I stop other sites from writing a script to invoke the REST API as well? Putting an authentication token in the javascript code isn't very secure, someone can just copy it.
Is a REST API the best approach for this problem? I am not adverse to learning new technologies or practices so please, any thoughts on better design patterns or methods of implementation are greatly appreciated. Unfortunately, due to my limited domain knowledge in this area, I have been unfruitful in my Google Searches as I'm not confident of the terms under which I should be searching.
Many thanks.
Since your Angular application is living in the browser, your REST API will need to be publicly accessible from any random visitor's browser. You thereby have a public API, out of necessity. You can't restrict it; either visitors can see the data or they can't.
Essentially this is not significantly different from a traditional webpage though. In a server-side generated page, you output your data packaged as HTML and deliver it to anyone who asks. In a REST-API/Angular app, you deliver the data packaged as JSON to anyone who asks. Either way the data is equally public, though maybe the REST API is a little easier to "abuse" than scraping the HTML would be. It may be useful to deliberate employing some user behaviour tracking and throttling, if you want to avoid someone outright sucking all of your database dry; this applies equally to JSON based REST APIs as it does to regular web pages.
If you're also exposing read/write APIs this way, you're of course wide open to abuse.
The only way to make an API non-public is to require password authentication. If the users of your site must be logged in, then you can restrict the API to anyone with a valid session. This doesn't help much in the grant scheme of things if anyone can simply register an account on your site, but it needs more deliberation and provides slightly more manageability than a completely open API.
Admin-only APIs of course must be protected in this way, requiring an account which only you have the credentials to.

Access database securely from iOS App

I chose MySQL after looking between MySQL and SQLite for accessing because my iPhone app needs to pull information from an online database that is already in MySQL.
I believe the traditional way of accessing information would be: To have a php file on the server that does the accessing for you.
The iPhone app would call this php file and it would return the results.
iOS app will call http://somewebsite.com/index.php?id=234 and the website would print out the username of id=234.
Now, how secure is this process?... I would obviously use prepared statements and https. But what if someone found the URL for this website? How do I protect myself against misuse (someone could generate a list of all my users)? Is this the standard way to have your iPhone app connect and get info from a database?
Edit: Furthermore, lets say I needed to create an app login page... I have a MySQL database with username and password (hashed obviously). Would it be safe to use $_GET variables to see if they are authenticated. Like for example: https://somewebsite.com/checkauth.php?username=test&password=C3LyiJvTCQ14Q and have the php print out yes or no. Picture examples below:
I would assume the above method would not be safe to do... but I need to be enlightened.
Also, I'd prefer to stay away from calling the database within the app using third party API, not supported by Apple.
The best way to go about this would to setup an API to interact with the database on the server and your iPhone app just queries the API and returns the data in a machine readable format such as JSON, see http://en.wikipedia.org/wiki/JSON and http://json.org/. So for user login the server would return maybe something like:
{
"result": false,
"error": "Invalid username or password"
}
This would be generated by PHP with the following code:
echo json_encode(array(
"result" => false,
"error" => "Invalid username or password"
));
Also note that, you should use HTTP response codes in conjunction with this, eg 401 for unauthorised.
JSON can use boolean and other data structures within its format. Nearly all major languages have support/libraries for it.
The benefits of this is that it allows you to build other applications using the same API such as an android version or an actual website.
This SO question is a good starting point on the security of mobile applications:
Creating an API for mobile applications - Authentication and Authorization
The main points are make sure to use HTTPS. When sending over user credentials you could return a user token (api key) that can be used for future requests and stored within the iPhone app for future access.
Eg: https://iphoneapp.com/notifications.json?key=98fy92473r92hAAIYEFG397qbqwiuUEAF
Your key should be sent in a HTTP header or in the POST so it is not recorded in logs etc...
Note: This is just a random string typed on the keyboard.
This method allows you to delete/regenerate the key if it gets compromised. You can also set rate limiting on the keys and various other parameters.
Another huge benefit is by building an API that your own app uses means that it will be maintained to a high standard and other third party companies can also use the API (if you allow them).
Edit: Furthermore, lets say I needed to create an app login page... I
have a MySQL database with username and password (hashed obviously).
Would it be safe to use $_GET variables to see if they are
authenticated. Like for example:
https://somewebsite.com/checkauth.php?username=test&password=C3LyiJvTCQ14Q
You should send that sensitive data using POST instead, but any service has to login at some point. Using HTTPS should help the most as it prevents eavesdropping. After the first authentication you can return the token and reap the benefits mentioned above.
As for the user login as along as your PHP conforms to good practices you should have no issues. See http://www.phptherightway.com/ it will help a lot if you have questions.
Definitely research OAuth and utilize that if you can/want to.
This is just a starting point and is NOT meant to be used word for word, further reading and googling is required.
If you're looking for an alternative to a "build an API from scratch" approach we've used a web based service called Kumulos available at kumulos.com for a quick and easy solution.
This service allows a developer to connect to a MySQL database and build the data model and APIs via a web page then deploy a native library to your platform. I believe you can also import an existing data model as well.
Once the data model is built on the web page you can then build APIs and specify input and output parameters. The APIs are modeled based on the type of SQL operation you are performing such as SELECT, UPDATE, INSERT, DELETE.
In your case you would want to model a login/authentication UI which accepts the username and (hashed) password, validates the data against the Users table and return the authentication results.
Once your APIs are modeled via the web page you can then "deploy" your configuration and generate native libraries for iOS, Android, PHP, and others.
The generated Obj C library gets dropped into your project and you make and respond to APIs using objective c calls and delegates.
Kumulos includes some other features as well like data export, API call metering, and what they call KScript. This is essentially the ability to wrap your call in javascript at the server (also configured via the web page) to greatly expand the flexibility and capability of the API call functionality you can build.
We've had a couple of questions or support issues over the past few months and their support has been top notch. Their backbone is on Rackspace. We've got about 8 or 10 production apps running APIs through them at the moment and are quite satisfied not having to hire an API developer :)
Many mobile applications use APIs to get and store information in servers. Figuring out some of these endpoints is not complicated, and having unsecured endpoints returning sensitive information is a dangerous thing to do.
The first level of protection of your API could be to create an "API key" that identifies the application. This key is stored it in the server and checked on every request. Request with no API key should return a HTTP 401 (Unauthorized) status code.
API keys are okay, but insufficient when some calls can only be performed by certain users. For example a user needs to update his information, only the owner of the information should be able to perform this call, and not another user. For this you can pass authentication information that identifies the user to perform the update action.
I do not recommend using username/password on every request, instead have the user authenticate once, and let the server send back authentication tokens that can be used by the application to perform future authenticated calls. Take a look at OAuth2 as a potential Authorization Framework. Also check out OAuth 2.0 - The Good, the Bad & the Ugly.
I suggest using BShaffer OAuth2 Server in PHP. Also see Best Practices for securing a REST API / web service for alternatives.
From your question it sounds like there is an existing subsystem, I recommend creating a simple interface that makes the subsystem easier to use, and reusable across multiple clients instead of modifying the subsystem to accommodate an API. This is commonly known as a Facade Design Pattern.
Many PHP Frameworks have packages to implement custom RESTlike APIs. Symfony has FOSRestBundle, FuelPHP has a REST controller out of the box and CodeIgniter has a REST server.
To summarize:
Create a simple interface to access information from the existing system (a REST API).
Protect your private information using a proper authentication mechanism (maybe OAuth2).
Use existing libraries and/or frameworks to speedup development.
Your code will be reusable across multiple applications and platforms as a result!
if you want to access database from IOS Application and save data into database you have to use middleware solutio.
which is Webservice
Create Web Server In Microsoft ASP dot Net And Access That WebService in IOS Application With that you can communicate between two different OS.
return from Webservice is XMLdoucment which can be further parse with xml purser.

Securing flash and php (AMF) communication

I am currently building a Flex 4 web app using PHP as my backend. I am using AMF to let the backend and flex application talk to each other.
How can I protect my AMF endpoint? Users can just decompile my flex application, find the URI to my endpoint and call methods. I need to ensure that all calls to the endpoint is done from within my application.
I would like to prevent somethig like this from happening: http://musicmachinery.com/2009/04/15/inside-the-precision-hack/
What are the best ways to achieve that?
Thanks :)
URLs aren't important. They're very easy to find out from any web application, and yet you still need it to have public access to them. There are a few things to do, first, if you're interested in the data security itself, you'll probably want to have your server running over https instead of http. If data security isn't crucial however (and it often isn't), you just need to have a quick and dirty authentication system.
I'm sure you can find many articles online or even frameworks made for authentication for php. In the past when I needed a very simple authentication, I would have my client send over a username and SHA1 password to an open authentication function on php, which would then create, store and return a session ID. That session ID would then be the first parameter of all the other php functions. Those functions would check the DB to see if the session ID is there or still valid (15 minute timestamp from the last time it was used) and if it is, go ahead with the function.
This is just a very simplistic way of doing things and will be good for a lot of small websites. If you need more security, send all of this over https to prevent sniffers to get the session id sent over the wire. After that, you're going into enterprise security which is probably overkill for what you want to do and will cost you an arm, a leg and your left testicle :P

How to capture session information from PHP in ASP?

I'm working in a website that is going to work like a landing point, providing a specialized service for many other websites. Users log-in to different sites and those sites have links to my website.
Now, I want to create my website using asp .net, and also I want to be able to use SSO (Single Sign-On) so the users doesn't have to authenticate again when they land on my site.
The problem is that most of the websites that are going to use the services of my site are in php, when users login on these sites, all the authentication process is handled and also a lot of data is fetched into the Session variable; what I want to do is to be able to capture all the data in the session variable coming from the php page, in my asp site.
I don't know if this is possible, maybe this can be done in another way
So far, the only thing I've been able to do in the asp is, ask for a parameter in the url and using that parameter query the database to get all the data that was already in the session in php.
So if any of you know a way to do this.
Thanks
My company does this extensively. Our app passes information from our software to other systems such as CRM's, appointment schedulers, data aggregators, etc. In cases where systems are radically different and access is not explicitly given, the best solution we've found is to use cURL and negotiate a data interchange via API. Setups with people of varying technical abilities can be challenging (we've actually provided code for several systems we wanted to communicate with) but in the end it's efficient and secure.
Unlike many UI guys, I'm a fan of OpenID for single login. However, that doesn't pass all the data you likely want to interchange between the sites.
You could either use a database as a session store point accessible by all pages. this makes it pretty easy to access session data by either php or asp.
I think this would be the mos performant way.
If you don'T want to give the other php sites any access to your databases you also could create a special page not for vewing in asp and tell the php sites to drop the session contents via curl there and in that sie then save the session stuff in your database.
It's not clear from your question whether you are hosting both ASP and PHP websites on one server or if your ASP site will be used with other third-party sites.
If you run and manage the ASP and PHP sites on one machine, then storing session information in the database will be the way to go and isn't too difficult. You'll need to make sure that the session data you store in the database can be read by both PHP and ASP--I'd pick something simple like JSON. A url parameter would be a bad way to get at this data, as it makes user information available to anyone who could guess a user id.
It's not so simple, however, if you want to provide SSO capabilities with third party sites. In this case, you'll have to implement an authentication API that the third party sites can call to log their user into your site when they initially authenticate the user on their own.

Categories