Protecting against Cross site scripting - javascript

I have a simple jsp that has 3 inputs (name, id and email) and a form submit. From doing some reading ,it looks like my input values should be encoded.How can I do this? Can anyone provide an example
For eg
<td><input id="email" name="email" value=""/></td>
<td><input id="fullname" name="fullname" value=""/></td>
<td><input id="userId" name="userId" value=""/></td>
<input type ="submit" value ="Get User" />
How should the email, fullname and uerId be encoded?
Also I have seen example as follows:
String safeOutput = ESAPI.encoder().encodeForHTML( Comment)
Should the encoding be done both to the HTML and to the java code?
I would appreciate some tips,as I am confused about this.
Thanks

Basically if someone puts any HTML in any of your parameters and you then display those on your site, their HTML will be parsed by the browser. They could use this to screw up your formatting, i.e. leave a B tag unclosed, or they could put in a script tag pointing to a script on another site.
The two most basic ways to protect against it are:
Check for < or > in any user input data, and reject the data if it contains either of them.
Nullify any HTML entered by the user by replacing all < and > with < and > or [ and ].
Those will work if you want to disallow all HTML. But if you want to allow the user to input some HTML, like safe tags (B, I, EM, STRONG), then you need a library that removes all HTML tags not on a whitelist.

You should ideally be using some security frame works like HDIV (HTTP Data Integrity Validator). We use it for
a large eCommerce application and just got our security review
successful.
Some great features
Java based
Supports frame-works like - struts/spring-mvc/jsf/servlets etc
In-built filters/interceptors for handling injections/XSS/CSRF attacks etc
Extract from HDIV site
HDIV is an open-source framework that eliminates or mitigates web
security risks by design for some of the most used JVM web frameworks

It is practically impossible to prevent people entering fragments of HTML in general text fields, because you might want to allow them to enter "special" characters, such as & < and >. So instead of trying to prevent or remove HTML, it might be better to ensure that when it is displayed, it is done so in a safe manner. The JSP c:out action does that. Instead of writing
<p>You said: ${userMessage}</p>
write
<p>You said: <c:out value="${userMessage}"/></p>

Related

Nodejs and Mongodb.Which characters should I allow for users's comments?

I made a form site with nodejs.But i dont know -Which characters(from textarea) should i allow for users's comments?For exapmle / " ' () {} . , ; : ! ?(punctuation marks) i want to allow this characters.These characters are a problem for security?I use mongodb for database.Like stackoverflow comment area.We can add all characters in our comments and they saved.
<form action="/comment" method="post" enctype="" id="myForm" onsubmit="myFunction()">
<textarea></textarea>
</form>
What you need to do is allow everthing but save it and process it securely. More specifically protect from SQL Injection and etc.
From Michael Pratt's answer
The node-mysql library automatically performs escaping when used as
you are already doing. See
https://github.com/felixge/node-mysql#escaping-query-values
While there is various attacks possible text inputed into an input/textarea will be handled as normal text characters although you can make sure any user input added is escaped otherwise and in the most part will not have impact on your security.
You might take precautions like ensuring your site handles encrypted traffic to mitigate against the most common types of attacks.

Make Chrome not to ask for 'http://' in input

I have an HTML form submitting via AJAX. So, one of the fields is:
<input type="url">
And by default, Chrome asks for the value of this field to be in the following format:
http://example.com
As I use bootstrap, I have the following input field visible: watch this screenshot.
I want user to enter the URL without the HTTP/HTTPS prefix, but in that case Chrome argues that it is not a valid URL.
What may the solution be? How could I make the browser think that the URL string does not need http prefix?
P.S. I use type="url" in order to make it easier to enter page addresses from Android/iOS devices.
EDITED:
There isn't to many options in this case. You essentially have two choices. Don't use type="url", which you already said you need to use. Or don't validate it using this method:
<input type="url" name="someUrl" novalidate="novalidate">
If you absolutely need to validate it, you could write a custom validation script. or use something like JQuery Validate.
This isn't a problem with the browser. It's the validation of the HTML5 input type. There are two solutions that you can implement. You can use
<input type="url" novalidate="novalidate" />
The second option is to use JavaScript to add the http:// to the field onsubmit if it isn't there. I've been trying to make it work with the type="URL" onsubmit, but the HTML5 validation kicks in before the JavaScript. Your best option, if you want to keep it that type will be a script executed by onkeyup: http://jsfiddle.net/gLN6X/1/ (posted at https://stackoverflow.com/a/17947355/3869056)
If you can do away with the type for one that doesn't have a default validation, you can use something like this: http://jsfiddle.net/u958xwr5/1/
<html>
<head>
<script type="text/javascript" src="//code.jquery.com/jquery-1.9.1.js"></script>
<script>
$(document).ready(function() {
$('#urlForm').submit(function() {
var url = $('#address');
if(url.val().match(/^http:\/\//) == null) {
url.val("http://" + url.val());
}
});
});
</script>
</head>
<body>
<form id="urlForm">
<input id="address" type="text" />
<button type="submit">Submit</button>
</form>
</body>
</html>
The JSFiddle has a little extra to show that after the correction has been made, it'll be submitting the correct information.
By definition, <input type="url"> represents a control for editing a single absolute URL. An absolute URL contains a protocol part; it is not an omissible “prefix”. Whether a browser has a way of prefixing user input with a default protocol part like http:// is a different issue, and at the discretion of the browser vendor.
Some people might consider using a prefilled part as in <input type="url" value="http://">, but this has several problems. It means setting an initial value that is invalid, which is confusing. It also makes it more difficult to the user to use the natural method of copy and paste.
The conclusion is that if you want a URL as input from the user, you should expect them to provide a full absolute URL.
if you don't want the browser validation (it can vary between browsers) you can add the following novalidate attribute
<input type="url" name="someUrl" novalidate="novalidate">
According to the OP, the issue was solved by using the HTML5 pattern attribute with the appropriate regular expression on the <input>, like so:
<input type="url" pattern="^[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(/\S*)?$">
I'd like to add that this is not necessarily the best solution. It's hard to find the exact regular expression that will work for everyone, every time. If you have to use such explicit validation, I suggest you to listen to users' feedback, and alter the regular expression if necessary.
Personally, I don't do much validation on the URL inputs, that way the user will have the freedom of using any domain not just the good ol' example.com. Also, URLs can also be in the form of an IP address, like http://127.0.0.1/ or not have a dot in them, like http://localhost/. I just find it easier to allow whatever the user enters into the text box, obviously escaping the value as needed if it's being stored in a database.
As a closing word, I'd like to point out the fact that you shouldn't rely on the competence of the users. Why? Well, despite that http:// being in front of that input, lazy people (including me) will probably just paste the URL they CtrlC'd from the browser's address bar, and forget about removing that protocol from the beginning, hoping that the site would automatically do it for their own convenience. You should also take this into account when creating the input's validation, because it might throw off some people who just pasted a valid URL into your input, and it tells them that it's wrong.

jQuery Prepend Security

Here is a rookie question, if I have a textarea that doesn't submit anywhere...
<form onsubmit="return false;">
<textarea name="new_title_text" id="new_title_text"></textarea>
</form>
and I use jQuery to prepend the value of the textarea to a div...
var textValue = $('#new_title_text').val()
$('#myDiv').prepend('<div>' + textValue + '</div>');
Are there any security vulnerabilities with this? Can someone somehow inject JavaScript and preform XSS, CSRF or any other type of attack? I understand that once I submit the value to my server then it needs to be checked, but is there anything that can happen before submission?
Thanks in advanced!
Basically you can't trust any validation done client side as people can (pretty easily) bypass JavaScript validation.
Do your proper validation and sanitation on your server and leave the client side validation simply for the user experience and to not "bother" your server with clearly invalid data - such as empty fields where a value is required.
Unless you are letting your users submit some PHP code or JavaSctipt code to be executed elsewhere on your site you should be safe. Always remember NOT to trust any data coming in from users. Treat all incoming data as a potential threat and sanitize anything you deal with if you plan to use it later.
Can someone somehow inject JavaScript and preform XSS, CSRF or any other type of attack
Yes. You are injecting text into an HTML string without HTML-escaping, so any metacharacters in that string (< or &) will fail and may be vulnerable to injection attacks (eg <script>...).
The question is who is that someone? From your current code it doesn't appear possible for an external party to pre-fill the textarea, so it would have to be the user attacking themselves (not really a vulnerability).
So you either need to HTML-escape the string going into HTML, or, better, use DOM-style access methods like .text() and .attr() to set text content and attributes without using crude string markup generation. Or the creation shorthand:
$('#myDiv').prepend(
$('<div>', {text: $('#new_title_text').val()})
);
The basic idea is that yes, it's unsafe to use prepend with untrusted data. However the exploitability does depend on the scenario. If an attacker can craft a url that causes that script to run with an untrusted value, you definitely have an XSS problem. If however a user can only trigger this himself by entering unsafe data and clicking the button, it's more safe, but not quite. This is often called self-xss and is sometimes exploited together with clickjacking etc.
For more info on unsafe jquery functions see: http://erlend.oftedal.no/blog/?blogid=127

Is this vulnerable to dom-based xss?

I have a disagreement with a security auditor, whether a snippet of html/js is vulnerable to XSS or not.
In short this is it:
<html>
<form name="myform" action="page.php" method="post" onsubmit="return validate()">
<input name="field" type="text" size="50" />
<input type="submit" value="Submit" />
</form>
<script>
function validate()
{
var str=document.myform.field.value;
alert("Error in " + str);
return false
}
</script>
</html>
So, my auditor says that this can be vulnerable to DOM-based XSS, but has not yet given me an example.
I personally think that it is not, since because of the + inside alert, str is a string so it's not executed. For example if someone provides "document.cookie" in the form and hits submit, then the alert box is going to print "Error in document.cookie" (and not the actual cookie).
The only way this could be a potential threat is if you are including scripts that are not under your control from an untrustworthy source.
The malicious script could overwrite alert to be another function. For example, it could send the data passed to alert to its own servers.
The malicious script could overwrite the value of document.myform.field with an object containing a value property. The alert could be thus made to display a message that looked like a different error message, such as:
Error in authentication. Please go to www.phisherman.com and enter your user name and password.
If you are linking to scripts from untrustworthy sources, you have much greater security concerns than the above.
If you are linking to no such untrustworthy scripts, then no, this is not vulnerable to DOM-based XSS. form.field.value contains a string. It is not evaluated as script, escape characters have no effect, the string contained in the textbox will be displayed in the alert window. Nothing a user enters in that field could be used to harm your servers or corrupt your data based on the code you've posted.
I'd say that if your auditor is concerned with "DOM-based XSS" where-in a user might cause harm to your servers by manipulating the DOM, your auditor does not know much about DOM and browser-based JavaScript. A user can crack open a JavaScript console and execute all manner of scripts, including XMLHttpRequests to your server that can be made to look like they came from your own script. Precautions need to be made on the server for those types of attacks. Worrying about the security risks to the DOM or UI from user input in form fields is silly.
There is definitely no XSS problem with that.
What your "validate()" function does is:
Via the DOM API, copy a reference to a property of a DOM node (the "value" property of the <input> element) to a JavaScript variable.
Perform a JavaScript string concatenation operation. At that point, it absolutely does not matter what the string of characters is.
Pass the result string to the window.alert(). The "alert()" function always treats its argument strictly as a string. The only "special" character is newline, and all that does is cause text to wrap to a new line.
In particular, note that:
window.alert("<script>var u_r_so_hacked = true;</script>");
will show the "" tags just like that, angle brackets and all.

Is it possible to create a searchbox for my site using javascript?

I'd like to create a search box on the home page of my site that would be able to search the entire site. I know it's a very general question but I'd be very happy with just a general conceptual answer is there anyway to do this?
You can't really do this using Javascript. You'll have to use some sort of server-side language that has access to your database. Alternately, you can use something like Google Custom Search Engine to provide searching capabilities.
Once you start wanting users to be able to search your site, it implies that your site is larger than just a few simple HTML pages. Have you thought about using something like Drupal, Joomla!, Wikimedia, or some other CMS? Most of those have search capability built in (one way or another).
People are going to tell you no. They're mostly right that his probably isn't the best way to do this.
But depending on your site, it may be technically incorrect to say this can't be done with JavaScript. If all the documents you want to be searchable have a unique URL that's used throughout the site, and if their graph is connected, I think you could write a spider in JavaScript that begins indexing all these pages as soon as a user hits your site. It'd do what any other spider did: look for links on the current page, request the documents behind them (using XMLHTTPRequest or a frame or popup window of some kind), process the document and index keywords based on some scheme, and store the results (possibly in a a cookie).
Of course, duplicating all this work for each visitor doesn't make a lot of sense, which is why the other people telling you no are mostly right. But it's theoretically possible.
This is would involve much more than just Javascript and depends on a number of different variables. Often, sites are built on a MySQL (or similar) database. If this is true in your case you may want to use some PHP to get into it and search through each record. Here's an example using PHP and MySQL.
For the form, something like this will work:
HTML
<form action="?" method="get">
<input type="text" id="search" name="search" />
<input type="submit" name="submit" id="submit" value="Search" />
</form>
Then you'll need to use some PHP, assuming you want to search the title and body of one table of blog posts:
$search_terms = mysql_real_escape_string($_GET['search']);
$resc = mysql_query("SELECT * FROM blog_posts WHERE title LIKE '%".$search_terms."%' OR body LIKE '%".$search_terms."%'");
$posts = mysql_fetch_assoc($resc);
now $posts is an array containing all of your posts which match the search terms in their title or body.
NOTE: In order to search for text type MySQL fields you will need to make the field a FULLTEXT index.
Check this link out for more info: http://devzone.zend.com/article/1304
This is a VERY SIMPLE solution, but it will get you on the right track.

Categories