Appropriate method to execute JavaScript from user input? - javascript

I need to build a web application that allow user to input javascript code and the code is then dynamically executed and somehow show the result at the same page. The flow would be something like this:
In the webpage, there area a series of textarea, and under each of these textareas, there is a result div element (or whatever element span, p, doesn't matter). User will input javascript code inside the textareas. He should be able to enter whatever javascript code he want, but at the end he will call a custom function like
my_application_output(some_variables_computed_from_previous_code_execution)
and then something will be displayed on the result div. A simple example will be:
if he input the following text in the textarea:
var a = 0;
a++;
my_application_output(a);
and then execute the code, the result div element below the textarea will have a inner html content of "1"
I don't have much idea how to get started, like what technologies or system architecture should I go for. so would like to ask for some pointers here. I have thought about two options (not sure whether they are good enough)
Use JavaScript eval() function. so I just execute the code from the textarea directly on the client side.
Implement a backend service using an engine like V8. So I do a ajax call to backend with the code content, and then the codes are executed from backend, and result is returned. I then put the result in the result div accordingly.
Personally, I'd like to go for 1) because eval() seems to be a easier solution. However, I'm not sure whether there is any limitation about this function or whether it can achieve what I want to do. Otherwise, if I have to go for the second option. Anyone can propose an architecture for that?

Not only is option 1 easier, it is also the safer choice.
Why? Everyone who has Firebug installed in Firefox (or just has the Chrome Dev tools open) already has what you're asking for, though perhaps in not as noob-friendly a fashion. The code they write is sandboxed to the browser they're using and nothing more.
With option 2, you're going to execute arbitrary untrusted code on the server. Suppose they realize that you're using Node.js (the most likely choice here) and then run a fork-bomb on your server:
require('child_process').exec(':(){:|:&};:', function() { console.log('This will never run') });
Let alone something more nefarious.
Remember that REPL stands for Read-Eval-Print-Loop, and is what dynamic languages since Lisp have used to help programmers understand their languages. Eval is perfectly fine if the only person a newbie can hurt is themselves.

Related

Re-creating a websites javascript function to be used as a stand alone alternative in tampermonkey

I'm looking for a way to do something that may or may not be possible.
On the site http://hitbox.tv/ there is a javascript function I believe that turns text into images.
For example, using:
emotify.emoticons("",{
"emote": ["http://example.com/emote.png", "channel"],
});
in a tampermonkey script or entering it directly into the chrome console would allow all occurrences of "emote" in the chat to be turned into that image.
If I type "emotify" into the chrome console, I'm given:
function (e,f){return f=f||function(h,j,g){return j=(j+", "+g).replace(/"/g,""").replace(/</g,"<"),'<img src="'+h+'" title="'+j+'" alt="" class="smiley"/>'},e.replace(b,function(j,g,m){var k=0,h=m,l=c[m];if(!l){for(;k<d.length&&!d[k].regexp.test(m);)k++;h=d[k].name,l=c[h]}return l?g+f(l[0],l[1],h,m):j})}
and if I type in "emotify.emoticons" I am given:
function (){var k,m,h,o,l=Array.prototype.slice.call(arguments),n="string"==typeof l[0]?l.shift():"",f="boolean"==typeof l[0]?l.shift():!1,g=l[0],j=[];if(g){f&&(c={},d=[]);for(k in g)c[k]=g[k],c[k][0]=n+c[k][0];for(k in c){if(c[k].length>2){for(m=c[k].slice(2).concat(k),h=m.length;h--;)m[h]=m[h].replace(/(\W)/g,"\\$1");o=m.join("|"),d.push({name:k,regexp:new RegExp("^"+o+"$")})}else o=k.replace(/(\W)/g,"\\$1");j.push(o)}b=new RegExp("(^|\\s)("+j.join("|")+")(?=(?:$|\\s))","g")}return c}
So what I'm wondering is, is there a way to use this code in a tampermonkey script somehow so that in the future, if the code is removed from the website, I could still use the emotify.emoticons function to create standalone emotes?
I really hope this makes sense. If you need any more information, fell free to ask. Any help is greatly appreciated!
-Tom
I might be wrong, but my inclination is that no, you can't - because the full behavior for this code is probably actually executed server-side, not in the web browser.
The images would have to get passed to the server to get circulated to the other people in the chatbox anyway
The function you list just returns a function, which does some (somewhat cryptic!) string operations, and little else, indicating the heavy lifting is done elsewhere.
The reason why you can run it using tampermonkey currently is because the function is defined on hitbox.tv. Defining it in tampermonkey probably won't help, because if hitbox removed it, they would also remove everything that uses it, rendering it useless.
You can do more investigation if you feel like it; http://www.hitbox.tv/dist/hitbox-ui.min.js is the link to their (minified) javascript file that runs the website. Running it through http://jsbeautifier.org/ yields a ~55,000 line long file, however, so unless you know what other variable words to search for, it's going to be impractical to comb through by hand.

Define custom function in Firebug

I am a chronic user of Firebug, and I frequently need to log various stuff so that I can see what I am doing. The console.log function is a lot to type. Even if I assign it to a single letter variable like q = console.log, I have to do it every time I fire up Firebug. Is there any way to do it such that q always refer to console.log (unless, of course, I override it in my session)?
To answer your question, the functionality doesn't currently exist, however I have found the firebug developers to be very responsive in the past. Why don't you put in a feature request on their forum, or better yet, code it up yourself, and ask them to add it?
Depending on your IDE, simply setup a code snippet (I use Flash Develop, so Tools -> Code Snippets).
I believe this to be a better way than setting up redirect scripts and what not, because it stops the Firebug namespace from being polluted, and makes it easier/more consistent to debug if your debugging breaks down.
The screenshot shows me using Flash Develop, hitting Ctrl+B, then hit enter. The pipe (|) in the snippet indicates where the cursor will be placed to start typing after inserting the snippet.

Programatically retrieve count of javascript errors on page

I'd like to write a test case (using Selenium, but not the point of this question) to validate that my web application has no script errors\warnings or unhanded exceptions at certain points in time (like after initializing a major library).
This information can easily be seen in the debug consoles of most browsers. Is it possible to execute a javascript statement to get this information programatically?
It's okay if it's different for each browser, I can deal with that.
not so far read about your issue (as far as I understood your problem) here
The idea be the following:
I found, however, that I was often getting JavaScript errors when the page first loaded (because I was working on the JS and was introducing errors), so I was looking for a quick way to add an assert to my test to check whether any JS errors occurred. After some Googling I came to the conclusion that there is nothing built into Selenium to support this, but there are a number of hacks that can be used to accomplish it. I'm going to describe one of them here. Let me state again, for the record, that this is pretty hacky. I'd love to hear from others who may have better solutions.
I simply add a script to my page that will catch any JS errors by intercepting the window.onerror event:
<script type="text/javascript">
window.onerror=function(msg){
$("body").attr("JSError",msg);
}
</script>
This will cause an attribute called JSError with a value corresponding to the JavaScript error message to be added to the body tag of my document if a JavaScript error occurs. Note that I'm using jQuery to do this, so this specific example won't work if jQuery fails to load. Then, in my Selenium test, I just use the command assertElementNotPresent with a target of //body[#JSError]. Now, if any JavaScript errors occur on the page my test will fail and I'll know I have to address them first. If, for some strange reason, I want to check for a particular JavaScript error, I could use the assertElementPresent command with a target of //body[#JSError='the error message'].
Hope this fresh idea helps you :)
try {
//code
} catch(exception) {
//send ajax request: exception.message, exception.stack, etc.
}
More info - MDN Documentation

inspect javascript calls for gmail's buttons

i'm working on a greasemonkey script for gmail in which it'd be very useful to know what function call is made when the "send" button is clicked. (i was unable to find this using firebug, but am relatively new to javascript debugging.) it seems that one should be able to detect this, i just don't know what tool(s) to use.
thanks very much for any help.
p.s. ultimately the goal here is to be able to extract a unique message i.d. for outgoing gmail messages, which i figured would be present in this javascript call -- so if there's an alternate way to do this, that would work just as well.
Gmail's Javascript code is obfuscated to avoid this type of inspection (and also to reduce code size). It is very unlikely you'll be able to make heads or tails of it even if you manage to get Firebug to breakpoint in the code properly.
I don't think that the message id would be in the message created (in fact all the headers would be absent). My guess is that they are entered on the server side by Google before dispatching the message.
All objects in JavaScript has got a toString() method. If you can find the button then you can find it's associated events. You can then toString() those events in the FireBug console--but as levik wrote; all of the code if obfuscated, so you might just end up toString()'ing gibberish.
Here's a little pseudo-code to get you started:
document.getElementById("...").onclick.toString()
Update
It seems like it's not possible to access events added with attachEvent() and addEventListener() if you have no control over the code you want to debug.
As a sidenote, one would assume that the unique id gets assigned in the server, not in the javascript...

Not allowing javascript function call from the address bar

I was working with a online game website. There are some event which call a javascript function and the function have some action with callback.
something like this,
<input type="button" onclick="changeSomething"/>
function changeSomething() {
/// some call back, which changes something
}
now anybody who knows this can call this changeSomething from the address bar of the browser, which I do not want.
Very unlikely that somebody will do it, but I want to allow it.
Is there anyway to prevent situation like this ?
Thanks.
P.S. I tried, but still not sure whether I explained it well enought. Please let me know if you are not getting something.
You will never be able to get 100% protected from any technique you try. It's a losing game.
Having said that one way to get closer to your goal is to remove the onclick attribute altogether, and bind your click handler (ie "changeSomething") via javascript:
html:
<input id="foo" type="button" />
js:
addEvent(document.getElementById("foo"), 'click', function() {
/// some call back, which changes something
})
The callback becomes anonymous then (eg there is no "changeSomething" function anymore). These evil users can't call it directly if they don't know its name!
There are still ways around this technique too, but we won't mention those lest we give the evil doers ideas :)
(BTW addEvent is just a sample library function for adding event handlers. I'm sure you have access to one. If not here you go.)
I dont think that there is anything you can do about this. The client can run whatever they want within their own browser. The only thing to do is validate everything on the server side. This is an important concept in all web programming. Client side code can be freely modified and should be treated as an additional check to speed things up rather than a security method.
You have to handle this on whatever back-end you've got accepting the request. Assuming you only give the user the option to doSomething() upon certain conditions, you probably have this information in the database (or whatever).
Don't worry about the JavaScript being called (no way around it), and do the same check you did on the front-end on the back-end. This way you can simply forget about securing your front-end, since you can't anyway... yet you still prevent malicious users from doSomethinging when they aren't supposed to.
Let me know if you need further clarification of what I mean, but I'll need more details about what your app architecture is like.
Any "solution" will be as efficient as disabling right-click in Web page... For the latter problem, I found at least a dozen of workarounds, including viewing the page in Opera!
If you disable this, one will workaround with Firebug, Greasemonkey, or even some proxy modifying HTML on the fly, not to mention using a local copy of the page, etc.
You can check the source of the click by passing an ID:
<input id="good' type="button" onclick="changeSomething(this.id)"/>
function changeSomething(myId) {
if(myId!='good') {
return;
}
//......code
}
Revised to:
<input id="good' type="button" onclick="changeSomething(this)"/>
function changeSomething(myId) {
if(myId.id!='good') {
return;
}
//......code
}

Categories