Created
March 9, 2012 19:52
-
-
Save karolk/2008324 to your computer and use it in GitHub Desktop.
rpc in JavaScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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