Sunday, November 2, 2014

Using Proxy to bypass same origin policy for cross domain site in web dev prototyping

Same origin policy is a clever feature that prevents attackers from getting your user information by injecting cross site script into your website. This policy is just great for production website, but it is often a pain for prototyper that has to deal with this policy during development. This article discussed some of the common methods to deal with same origin policy during development and how to make the life of a prototyper, like you and me, easier.

Browser Settings
One way to deal with it is to change browser settings. Note that changing the browser's setting is different for each browser vendor. For example, to turn off same origin policy in Firefox, open the about config as below and change it to false.
about:config -> security.fileuri.strict_origin_policy -> false
 It is a bit different in Chromium as the browser need to be started with command line.
chromium-browser --disable-web-security
So, same origin policy can be switched off in these browsers. But for me, I won't do that because I will forget to switch it ON later on. The good thing is, changing the browser setting is not the only method to bypass same origin policy.

Reverse Proxy
Look up "reverse proxy" in wiki or google it. Reverse proxy is not only an elegant way to deal with same origin policy, it is also can be used in production environment. Well, most of the popular web servers such as NginX, Apache Web Server or IIS support reverse proxy (for IIS it is rewrite). There are tons of tutorial to configure it. The problem with reverse proxy is that it requires web server configuration. If you have a system administrator to help you with it, great! Most often, good prototyper will not want to trouble others (I am referring to myself).

Proxy Script
Personally, I love to use proxy script. Proxy script is a simple script that works like a router. It routes all your webpage API call to the endpoint and return the result as if you are calling the API endpoint directly. Here is a bit of details on how to use it. First, you install a proxy script to your development web server. Then, for every API call from your webpage, use the proxy script in your url. Since the proxy script can have the same origin as your webpage, because both are hosted on the same web server, the browser treat it like you are calling from the same origin. Therefore, the browser will not block the call. The catch is, you will need to remove the script and remove it from your code after you use it. 

Here are some of the PHP proxy script I wrote and used for my prototyping needs:

HTTP header or Cross Origin Resource Sharing (CORS)
You might asked, can my web services be configured to bypass same origin policy without the user/browser doing anything? Your answer is

Access-Control-Allow-Origin

You can set it in your web services' response HTTP header to allow certain/all origin accessed to your web services. Planning your website CORS takes effort and a lot of consideration to prevent any cross site script attack from happening. This is just too much work for a prototyper like me.

In conclusion, same origin policy do annoy prototyper like me a bit, but it is a great security feature. There are plenty of ways to bypass the same origin policy or to configure how same origin policy works, some of them are discussed in this article. A prototyper always looks for the easiest way to bypass same origin policy (if there is a need at all) during development and also the easiest way to make it production ready. Therefore, it is efficient to choose the options that will work without much reconfiguration during your production. 

Monday, December 3, 2012

Allowing cross domain persistence sync to backend database


PersistenceJS comes with client-server example for syncing to backend database. But, when a project complexity reaches a certain level, cross-domain persistence store access might be required. There are many ways to tweak the script for allowing cross-domain access. I was looking for a simple and elegant way to handle this issue, and I found non-other than tweaking the http-header. Tweaking the http-header is a common way to bypass same domain policy.

The purpose of this article is demonstrate the steps to tweak Nodejs web server to support cross domain request so that persistence client hosted on different domain can perform a database sync on the Nodejs web server.

The Server-Side - Setting the http-header
Below is a sample app.js based on todo-app (see my earlier post :). The example below shows the server-side scripting that is required to allow cross-domain access for persistence. The changes are highlighted in YELLOW.

var strVcap = process.env.VCAP_SERVICES || '{"mysql-5.1":[{"name":"mysql-d70a3","label":"mysql-5.1","plan":"free","tags":["mysql","mysql-5.1","relational"],"credentials":{"name":"todoappdb","hostname":"localhost","host":"localhost","port":3306,"user":"root","username":"root","password":"MyNewPass"}}]}';
var jsonVcap = JSON.parse(strVcap);

//persistence declaration
var persistence = require('persistencejs/lib/persistence').persistence;
var persistenceStore = require('persistencejs/lib/persistence.store.mysql');
var persistenceSync = require('persistencejs/lib/persistence.sync.server');

persistenceStore.config(persistence, jsonVcap["mysql-5.1"][0].credentials.host, jsonVcap["mysql-5.1"][0].credentials.port, jsonVcap["mysql-5.1"][0].credentials.name, jsonVcap["mysql-5.1"][0].credentials.username, jsonVcap["mysql-5.1"][0].credentials.password);
persistenceSync.config(persistence);

//init sync
var Todo = persistence.define('todo', {
content: 'TEXT',
done: 'BOOL'
});
Todo.enableSync(); //this create table with sync attribute

//nodejs module declaration
var express = require("express");
var app = express();

//init express
app.use(express.static(__dirname));
app.use(express.bodyParser());
app.use(function(req, res, next) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
var end = res.end;

req.conn = persistenceStore.getSession();
req.conn.schemaSync();
res.end = function() {
req.conn.close();
end.apply(res, arguments);
};
req.conn.transaction(function(tx) {
req.tx = tx;
next();
});
});

app.get('/todoUpdates',  function(req, res) {
console.log(" - get /todoUpdates - " + req.params.uid);
persistenceSync.pushUpdates(req.conn, req.tx, Todo, req.query.since, function(updates) {
res.send(updates);
    });
});

app.post('/todoUpdates',  function(req, res) {
console.log(" - post /todoUpdates - " + req.params.uid);
persistenceSync.receiveUpdates(req.conn, req.tx, Todo, req.body, function(result) {
res.send(result);
});
});

app.get('/markAllDone', function(req, res) {
    Todo.all(req.conn).list(req.tx, function(todo) {
        todo.forEach(function(todo) {
            todo.done = true;
          });
        req.conn.flush(req.tx, function() {
            res.send({status: 'ok'});
                });
      });
});

app.get('/markAllUndone', function(req, res) {
    Todo.all(req.conn).list(req.tx, function(todo) {
        todo.forEach(function(todo) {
            todo.done = false;
          });
        req.conn.flush(req.tx, function() {
            res.send({status: 'ok'});
          });
      });
});

app.listen(process.env.VCAP_APP_PORT || 3303);
console.log('-- Server running at http://127.0.0.1:3303/ --');

The Client-Side - Pointing to the allowed server
Below is a sample persistence client configured to sync to the crossed domain server. The example below shows the client-side script changes required to set to a cross domain server (as highlighted in YELLOW).

Todo.enableSync('http://localhost:3303/todoUpdates');

In Conclusion
By allowing cross domain access to a persistence data store, constraint on web-platform to use only the data store within the same site is eliminated. Thus, all your other web application will be able to use the data store in the web server. This will impact on your web application design (example, single page application or web-portal). On the other hand, there will be needs to properly secure the web server from unwanted attacks.

The example of this tutorial can be downloaded here



Monday, September 10, 2012

How to setup PersistenceJS database sync using NodeJS and MySQL

Today, Javascript is capable of access to back-end database, thanks to ORM (Object-Relational-Mapper). Day by day, ORM frameworks are mushrooming on the net. I was looking for a framework that build database seamlessly, pure and simple, and I found a Javascript ORM framework called PersistenceJS.  PersistenceJS has the front-end and back-end library that make it easy to implement ORM.

The purpose of this tutorial is to setup a database synchronization for your PersistenceJS client-side web application. I use todo example (by Jacob) for this experiment, and the backend is powered by MySQl, NodeJS and persistencejs sync plugin. In short, here are the prequisites:


Stack on the back-end side:
For front-end library:

First, building app.js for NodeJS (server-side scripting)

Declare & Init PersistenceJS (refer to persistencejs example)

//persistence declaration
var persistence = require('persistencejs/lib/persistence').persistence;
var persistenceStore = require('persistencejs/lib/persistence.store.mysql');
var persistenceSync = require('persistencejs/lib/persistence.sync.server');

persistenceStore.config(persistence, "localhost", 3306, "todoappdb", "root", "yourpassword");
persistenceSync.config(persistence); 

//init sync
var session = persistenceStore.getSession();
var Todo = persistence.define('todo', {
content: 'TEXT',
done: 'BOOL'
});
Todo.enableSync(); //this create table with sync attribute
session.schemaSync(); //generate the table

Declare & Init Express


//nodejs module declaration
var express = require("express");
var app = express();

//init express
app.use(express.static(__dirname));
app.use(express.bodyParser());
app.get('/todoUpdates',  function(req, res) {
console.log(" - get /todoUpdates - ");
//var session = persistenceStore.getSession();
session.transaction(function(tx){
persistenceSync.pushUpdates(session, tx, Todo, req.query.since, function(updates) {
res.send(updates);
    });
});
});
app.post('/todoUpdates',  function(req, res) {
    console.log(" - post /todoUpdates - ");
//var session = persistenceStore.getSession();
session.transaction(function(tx){
persistenceSync.receiveUpdates(session, tx, Todo, req.body, function(result) {
res.send(result);
});
});
});

app.listen(3000);

A little change on the client-side, editing services.js from jacob todo example.


Add this line of code after you define your Todo object.

Todo.enableSync('/todoUpdates'); //this will create the table with sync attributes


In the persistence.flush() function, just call the todo.syncall function (to update the back-end).


persistence.flush(function(){
Todo.syncAll(
function(){alert('Your Callback Code');},
function(){alert("Your Sync Complete Code");},
function(){alert("Your Error Handling Code");}
);
});


Finally, start nodejs (e.g. "node app.js" in your command prompt) and navigate to 
http://localhost:3002/todo.html

The example of this tutorial can be found here 

http://azee01.ap01.aws.af.cm/todo.html

Download link here
https://github.com/anthonyzee/todo-example-sync