Javascript - Sanitize Malicious code from file (string) - javascript

I have a data javascript file, which is being dynamically added to website via some custom code.
This file comes from a third party vendor, who could potentially add malicious code in the file
Before this file is added to the website, I would like to parse through it, and look for malicious code, such as redirects or alerts, that inherently get executed upon a files inclusion in the project/website.
For example, my js file could look like this :
alert ('i am malicious');
var IAmGoodData =
[
{ Name :'test', Type:'Test2 },
{ Name :'test1', Type:'Test21' },
{ Name :'test2', Type:'Test22' }
]
I load this file into a object via a XMLHttpRequest call, and when this call returns, I can use the variable (which is my file text) and search it for words:
var client = new XMLHttpRequest();
client.open('GET', 'folder/fileName.js');
client.onreadystatechange = function()
{
ScanText(client.responseText);
}
client.send();
function ScanText(text)
{
alert(text);
var index = text.search('alert'); //Here i can search for keywords
}
The last line would return index of 0, as the word alert is found at index 0 in the file.
Questions:
Is there a more efficient way to search for keywords in the file?
What specific keywords should i be searching for to prevent malicious code being run? ie redirects, popups, sounds etc.....

Instead of having them include var IAmGoodData =, make them simply provide JSON (which is basically what the rest of the file is, or seems to be). Then you parse it as JSON, using JSON.parse(). If it fails, they either didn't follow the JSON format well, or have external code, and in either case you would ignore the response.
For example, you'd expect data from the external file like:
[
{ Name :'test', Type:'Test2' },
{ Name :'test1', Type:'Test21' },
{ Name :'test2', Type:'Test22' }
]
which needs to be properly serialized as JSON (double quotes instead of single quotes, and double quotes around the keys). In your code, you'd use:
var json;
try {
json = JSON.parse(client.responseText);
catch (ex) {
// Invalid JSON
}
if (json) {
// Do something with the response
}
Then you could loop over json and access the Name and Type properties of each.
Random Note:
In your client.onreadystatechange callback, make sure you check client.readyState === 4 && client.status === 200, to know that the request was successful and is done.

This is extremely difficult to do. There are no intrinsically malicious keywords or functions in JavaScript, there are malicious applications. You could be getting false positives for "malicious" activity and prevent a legitimate code with a real purpose from being executed. And at the same time, anyone with a little bit of imagination could bypass any "preventive" method you may implement.
I'd suggest you look for a different approach. This is one of those problems (like CAPTCHA) in which it's trivial for a human to solve while for a machine is practically impossible to do so. You could try having a moderator or some human evaluator to interpret the code and accept it.

You should have them provide valid JSON rather than arbitrary Javascript.
You can then call JSON.parse() to read their data without any risk of code execution.
In short, data is not code, and should not be able to contain code.

You shouldn't. The user should be allowed to type whatever they want, and it's your job to display it.
It all depends on where it is being put, of course:
Database: mysql_real_escape_string or equivalent for whatever engine you're using.
HTML: htmlspecialchars in PHP, createTextNode or .replace(/</g,"<") in JavaScript
JavaScript: json_encode in PHP, JSON.stringify in JavaScript.
At the end of the day, just don't be Yahoo

Related

How to access the same JSON file from both javascript and python?

NOTE: This is not for web programming. We use javascript to interface with low level hardware, hence let's not go with jQuery APIs etc.
I have a javascript file that performs a sequence of actions on a device, and I have a python file that will be invoked later to validate these actions. There is a set of hardware information hard-coded in both javascript file and python file. I want to avoid this duplication of information by putting these info into a JSON file so both can access it.
// Javascript
var hardware_info = JSON.parse(load('hardware.json'));
// load() is probably not standard javascript API, but it basically copies that code into the existing script.
Already failed by this step because 'hardware.json' is not using javascript syntax...
I already validated the json using jshint/jslint, hardware.json looks like this:
{
"hardware1": {
"ID": "xxx"
},
"hardware2": {
"ID": "yyy"
}
}
The following Python works well for accessing the json, there is not much to it:
with open('hardware.json', 'r') as f:
data = json.load(f)
It looks like load() executes the specified file, not read it and return the contents. If this is your only option to read another file, then I suggest you use JSONP instead of JSON.
JSONP works by adding a callback around the data. Instead of:
{"key": "value"}
the file contains a function call with the data being passed in:
callback({"key": "value"});
This is meant to be executed by a JavaScript engine, causing it to execute the callback. load() would execute your file, and the callback function would be called as a result, passing in the data.
When used on the web, you'd call a JSONP service and pass in the name of the callback the service should add, but when just sharing a configuration file between a JS engine and Python, you'd hardcode that callback name.
In Python, you'd have to strip off the callback text before loading it as JSON data. That could be as easy as just removing the first N and last M characters:
with open('hardware.json', 'r') as f:
jsonp_data = f.read()
# remove first 9 and last 3 characters to remove JSONP callback
data = json.loads(jsonp_data[9:-3])
A little more sophisticated technique could use newlines:
callback(
{"key": "value"}
);
to make it easier to remove the first and last line in Python. Or you could use jsonp_data.partition('(')[-1].jsonp.rpartition(')')[0] to take everything between the first ( and the last ) character in the string. Etc.

Store very small amount of data with javascript

I have one of those websites that basically gives you a yes or no response to a question posed by the url. An example being http://isnatesilverawitch.com.
My site is more of an in-joke and the answer changes frequently. What I would like to be able to do is store a short one or two word string and be able to change it without editing the source on my site if that is possible using only javascript. I don't want to set up an entire database just to hold a single string.
Is there a way to write to a file without too much trouble, or possibly a web service designed to retrieve and change a single string that I could use to power such a site? I know it's a strange question, but the people in my office will definitely get a kick out of it. I am even considering building a mobile app to manipulate the answer on the fly.
ADDITIONAL:
To be clear I just want to change the value of a single string but I can't just use a random answer. Without being specific, think of it as a site that states if the doctor is IN or OUT, but I don't want it to spit out a random answer, it needs to say IN when he is IN and OUT when he is out. I will change this value manually, but I would like to make the process simple and something I can do on a mobile device. I can't really edit source (nor do I want to) from a phone.
If I understand correctly you want a simple text file that you change a simple string value in and have it appear someplace on your site.
var string = "loading;"
$.get('filename.txt',function(result){
string = result;
// use string
})
Since you don't want to have server-side code or a database, one option is to have javascript retrieve values from a Google Spreadsheet. Tabletop (http://builtbybalance.com/Tabletop/) is one library designed to let you do this. You simply make a public Google Spreadsheet and enable "Publish to web", which gives you a public URL. Here's a simplified version of the code you'd then use on your site:
function init() {
Tabletop.init( { url: your_public_spreadshseet_url,
callback: function (data) {
console.log(data);
},
simpleSheet: true } )
}
Two ideas for you:
1) Using only JavaScript, generate the value randomly (or perhaps based on a schedule, which you can hard code ahead of time once and the script will take care of the changes over time).
2) Using Javascript and a server-side script, you can change the value on the fly.
Use JavaScript to make an AJAX request to a text file that contains the value. Shanimal's answer gives you the code to achieve that.
To change the value on the fly you'll need another server-side script that writes the value to some sort of data store (your text file in this case). I'm not sure what server-side scripting (e.g. PHP, Perl, ASP, Python) runtime you have on your web server, but I could help you out with the code for PHP where you could change the value by pointing to http://yoursite.com/changeValue.php?Probably in a browser. The PHP script would simply write Probably to the text file.
Though javascript solution is possible it is discouraged. PHP is designed to do such things like changing pieces of sites randomly. Assuming you know that, I will jump to javascript solution.
Because you want to store word variation in a text file, you will need to download this file using AJAX or store it in .js file using array or string.
Then you will want to change the words. Using AJAX will make it possible to change the words while page is loaded (so they may, but do not have to, change in front of viewers eyes).
Changing page HTML
Possible way of changing (words are in array):
wordlist.js
var status = "IN"; //Edit IN to OUT whenever you want
index.html
<script src="wordlist.js"></script>
<div>Doctor is <span id="changing">IN</span></div>
<script>
function changeWord(s) { //Change to anything
document.getElementById("changing").innerHTML = s;
}
changeWord(status); //Get the status defined in wordlist.js
</script>
Reloading from server
If you want to change answer dynamically and have the change effect visible on all open pages, you will need AJAX or you will have to make browser reload the word list, as following:
Reloading script
function reloadWords() {
var script = document.createElement("script"); //Create <script>
script.type="text/javascript";
script.src = "wordlist.js"; //Set the path
script.onload = function() {changeWord(status)}; //Change answer after loading
document.getElementsByTagName("head")[0].appendChild(script); //Append to <head> so it loads as script. Can be appended anywhere, but I like to use <head>
}
Using AJAX
Here we assume use of text file. Simplest solution I guess. With AJAX it looks much like this:
http = ActiveXObject==null?(new XMLHttpRequest()):(new ActiveXObject("Microsoft.XMLHTTP"));
http.onloadend = function() {
document.getElementById("changing").innerHTML = this.responseText; //Set the new response, "IN" or "OUT"
}
http.open("GET", "words.txt")
http.send();
Performance of AJAX call may be improved using long-poling. I will not introduce this feature more here, unless someone is interested.

Is there any XSS threat while having JSON encoded in the URL?

In order to have an URL friendly application I'm storing it's context has a JSON in URL, which gives something like :
http://mysite.dev/myapppage/target#?context={%22attr1%22%3A{%22target_id-0%22%3A{%22value%22%3A%223%22%2C%22label%22%3A%22Hello%22}}}
Which encode a basic context :
{
"attr1":
{
"target_id-0":
{
"value": "3",
"label": "Hello"
}
}
}
I'm serializing my object with :
JSON.stringify(context)
I'm deserializing it with :
var hashParamsElements = window.location.toString().split('?');
hashParamsElements.shift(); // we just skip the first part of the url
var hashParams = $.deparam(hashParamsElements.join('?'));
var contextString = hashParams.context;
var context = JSON.parse(contextString);
The context is only stored to read variables, there's no evaluated code in it. Can someone tell me whether or not it's XSS safe ?
If there's a threat : how can I avoid it ?
A threat of this kind comes from using different methods of decoding JSON, namely eval and new Function. These execute JS code directly and therefore allow non-persistent XSS attacks by putting code in the url (and linking to it).
JSON.parse does not have this issue and is safe against these kind of attacks.
See also (json.org).
Does label end up getting inserted into the DOM somewhere? (IE, $('#something').html(context.attr1.target_id-0.label))
Then I could put <script>...</script> in a label and there's your XSS.
I dont see any threat in it. Its completely safe. JSON.parse does not allow any function to run.
Also, why using ? . If you want to give a feel of 'real' url, use hashbang instead.

Coding for client side from code behind in asp.net

I frequently write client side code in the code-behind section of my asp.net applications. I think its about time to get a refresher on how to write client side code on server side page.
I need to refresh mysel fwith the "double quotes" and "single quotes". Not sure what that is called, but can anyone point me to the correct resource where I can learn about the quotes and double quotes.
Writing javascript code, intended to be run on the client, on the server is to put it simply: bad, wrong, to be avoided.
You should prefer to write your javascript functions in separate js files and only invoke them from the server. The benefit of this is that you will no longer have to worry about single, double and triple quotes, your js will be cached, minified, gzipped, served from a CDN, optimized, ... The end result of mixing server side languages such as C#/VB.NET with javascript is just ugly and difficult to maintain code.
Now to the point. When you need to call some javascript function from the server and you need to pass it some arguments in order to not worry about quotes and stuff, I would recommend you to JSON serialize your server side object and pass it to the client function.
Let's take an example. Suppose that you have written a function which requires some arguments:
function foo(myModel) {
alert(myModel.Prop1 + ' | ' + myModel.Prop2);
}
and now you want to invoke this function from the server, here's how to proceed:
var model = new
{
Prop1 = #"some value that can contain ', \, "", anything you like to throw it in, etc..",
Prop2 = "some other value"
};
var json = new JavaScriptSerializer().Serialize(model);
var script = string.Format("foo({0});", json);
ClientScript.RegisterStartupScript(GetType(), "foo", script, true);
Now you no longer need to worry about any quotes and escaping. No matter what value you throw in those properties, they will be correctly serialized when invoking the javascript function.

passing value to JSP via javaScript

boolean canModify = UTIL.hasSecurity("PFTMODFY") && something;
function name() {
I need to pass a value false to something when the page loads.
}
window.onLoad = name
How can i pass a value from JavaScript to JSP on the page load
I think you mean it the other way around, have server-side code output a value that JavaScript can see at page-load time.
Sending from your server code (JSP) to your client code (JavaScript)
Just output it like you would anything else, e.g.:
<%
boolean canModify = UTIL.hasSecurity("PFTMODFY") && something;
%>
var canModify = <%=canModify%>;
// ^ ^
// | +-- server-side variable
// +-- client-side variable
When the JSP actually runs, the script code returned to the client will simply be
var canModify = false;
or
var canModify = true;
That's a boolean; if you need to output a string, you need to put the quotes around it and be careful that you escape anything within it that should be escaped inside a JavaScript literal string (like a backslash, for instance, and whatever quote character you're using).
Sending from your client code (JavaScript) to your server code (JSP)
But if you really mean you want to send a value back to the server on page load (which seems odd, but hey), you'd have to use Ajax for that. If you're going to be doing Ajax stuff, I'd recommend using a library like jQuery, Closure, Prototype, YUI, or any of several others as they can dramatically simplify the process for you. For instance, using jQuery, this client-side code sends a value back to the server:
jQuery.get("/your/page/url", {"name": "value"});
(or jQuery.post for things that make changes). Using Prototype, it'd be:
new Ajax.Request("/your/page/url", {
method: "GET", // or, of couse, "POST"
parameters: {"name": "value"}
});
All of the libs I mentioned above have similarly easy-to-use mechanisms for sending data to the server. Note that this mechanism is bound by the Same Origin Policy.
You don't need a library for this, of course — anything a library can do, you can do yourself. The features I've listed above are all wrappers for the XMLHttpRequest object (Wikipedia, MSDN, MDC). See the linked resources for examples.
Non-Ajax hack
I shouldn't have said you need to use Ajax for this, more like you want to. :-) If, for some reason, you really didn't want to use Ajax you could do it by adding something to the page with JavaScript that triggers a retrieval from the server, and then include your value as a flag in that request. For instance:
var link = document.createElement('link');
link.setAttribute('rel', 'stylesheet');
link.src = "/path/to/jsp?name=" + encodeURIComponent(value);
document.getElementsByTagName('head')[0].appendChild(link);
Your JSP would do whatever it needs to do with the query string, and then return anything that's valid in a stylesheet (/* */, for instance). Or if you don't want to use a style sheet link, use an img tag and return a transparent pixel; etc.
But I wouldn't do that. I'd use Ajax.

Categories

Resources