I maintain a PHP application. A user has recently reported the following code is vulnerable to XSS.
from_name = jQuery("#from_name").val();
from_email = jQuery("#from_email").val();
subject = jQuery("#subject").val();
msg = "From: " + from_name + " (" + from_email + ")<br />";
msg = msg + "Subject: " + subject;
jQuery("#review").html(msg);
His suggestion follows.
from_name = jQuery("#from_name").val();
from_email = jQuery("#from_email").val();
subject = jQuery("#subject").val();
msg = "From: " + from_name.replace(/</g,"<").replace(/>/g,">") + " (" + from_email.replace(/</g,"<").replace(/>/g,">") + ")<br />";
msg = msg + "Subject: " + subject.replace(/</g,"<").replace(/>/g,">");
jQuery("#review").html(msg);
If it isn’t obvious, this is significantly simplified. Regardless, his solution is just to clean up potential elements with .replace(/</g,"<").replace(/>/g,">") which I don’t immediately have a problem with but seems either A) unnecessary or B) incomplete.
I’ve considered using .text instead of .html but then I can’t format my text appropriately. Unless I’m overlooking something stupid.
I can see how it might be vulnerable since the originating elements are input elements, but those input elements are filled from a database. The database was filled originally using $_POST, which is vulnerable, but I validate the data before committing it to the database, including stripping all HTML tags.
In my opinion, the only chance for XSS is literally on the page if the element is altered by the user (seems stupid) or JavaScript, either way, my review element could be temporarily compromised, but once the change is ‘saved’ my validation functions would strip out the malicious changes.
This is a long winded question, I hope my logic is reasonable.
While you may be correct that you are probably not vulnerable if you are sanitizing the input to the database. It’s always better to sanitize on the way out as well for any content that has been posted to your database. A better way to handle it would be to use $.text like the following.