Skip to content

Instantly share code, notes, and snippets.

@karolk
Created March 9, 2012 19:52
Show Gist options
  • Save karolk/2008324 to your computer and use it in GitHub Desktop.
Save karolk/2008324 to your computer and use it in GitHub Desktop.
rpc in JavaScript
/*
Call certain JS functions in a controlled way by passing the name in the URL.
This can be likened to XSS but done in a controlled way
#Possible use case
Let's assume there is a social networking site having a feature 'invite me for lunch'.
Unfortunately the feature is not very well visible in the GUI. Assuming there is a JS
function inviteForLunch(ISODate) defined on the page people could create links on their
blogs:
http://socialnetwork.com/profiles/Foo/#/inviteForLunch(01-01-2011)
This has been done before, examples you commonly see look like this:
http://socialnetwork.com/profiles/Foo/?inviteForLunch=1&date=01-01-2011
Although the message popup is implemented on the client side, the server has to
concern themselves with
- parsing additional params, do they exist, are they safe to use
- if inviteForLunch is truthy then add additional value for the page stash to trigger
showing the message box
- if the data param is defined sanitise it, because it will be left on the page with JS
and HTML, so has to cleaned so that XSS is not caused
so typically I can see such values added to the page code like this:
var showLunchInvitation = true
var dateSanitised = '01-01-2011'
showLunchInvitation && inviteForLunch(dateSanitised)
But if we think about it, why make this round trip? Why should the backend be concerned
with running a JS function, that is defined by us, so we know it's safe to run?
#How to use
functions that can be called have to be singled out by putting them
in a right object (called remote)
Example: #hash/test/bar=1&foo=2
will call `remote['test']({"bar":1, "foo":2})`
see source:
http://dl.dropbox.com/u/362779/js/rpc.html#hash/callable/a=3&b=2
*/
'use strict';
var remote = {
callable: function(args) {
alert(args.a>args.b);
}
}
function notAvailable() {
alert('You cannot execute this function by messing with the URL')
alert('If you can, I am happy to buy you coffee/beer and learn')
}
if (location.hash) {
var chunks = location.hash.substr(1).split('/'),
functionName,
argStr,
namedArgs = {},
tempArr;
functionName = chunks[1];
if ( !functionName || !remote.hasOwnProperty(functionName) ) {
return false;
}
argStr = chunks[2];
if ( !argStr ) {
return false;
}
tempArr = argStr.split('&');
for (var i=0; i<tempArr.length; i++) {
var arr = tempArr[i].split('=');
namedArgs[arr[0]] = arr[1];
}
remote[functionName](namedArgs);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment