View Full Version : XSS Vulnerbility fix
mat420
03-09-2011, 04:39 AM
so i added html entities to eaach of my text boxes. idk if i need it on my checkbox but dont know how so if i do, tell me please.
my issue though is, all of them XSS vulnerbility warnings went away when i did that except for the page theyre actually on "contact.php"
sorry im tired. thanks so much all.
Vulnerability description
This script is possibly vulnerable to Cross Site Scripting (XSS) attacks.
Cross site scripting (also referred to as XSS) is a vulnerability that allows an attacker to send malicious code (usually in the form of Javascript) to another user. Because a browser cannot know if the script should be trusted or not, it will execute the script in the user context allowing the attacker to access any cookies or session tokens retained by the browser.
This vulnerability affects /contact.php.
Discovered by: Scripting (XSS_in_URI.script).
The impact of this vulnerability
Malicious users may inject JavaScript, VBScript, ActiveX, HTML or Flash into a vulnerable application to fool a user in order to gather data from them. An attacker can steal the session cookie and take over the account, impersonating the user. It is also possible to modify the content of the page presented to the user.
Attack details
URI was set to "onmouseover=prompt(989931)>
The input is reflected inside a tag element between double quotes.
View HTTP headers
Request
GET /contact.php/%22onmouseover=prompt(989931)%3E HTTP/1.1
Cookie: PHPSESSID=26d2d9143c8b4920fbb91285f512c433
Host: www.drpcrepair.com
Connection: Keep-alive
Accept-Encoding: gzip,deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)
Accept: */*
Response
HTTP/1.1 200 OK
Date: Wed, 09 Mar 2011 04:29:50 GMT
Server: Apache
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Pragma: no-cache
Vary: Accept-Encoding
X-Powered-By: PHP/5.2.17
Keep-Alive: timeout=2, max=181
Connection: Keep-Alive
Content-Type: text/html
Content-Length: 16712
View HTML response
Launch the attack with HTTP Editor Retest alert(s) Mark this alert as a false positive
How to fix this vulnerability
Your script should filter metacharacters from user input.
mat420
03-09-2011, 04:42 AM
http://www.winfrastructure.net/article.aspx?BlogEntry=Is-your-website-vulnerable-to-cross-site-scripting-attacks
i found this, i think this is the fix but im not sure how to use it.
so i tried tehe ereg_replace thing again in the "mail" part of the php form (filtering all !@#$%^&*() but it still came up as vulnerable)
thanks agian :/
first off, this is not a CSS issue. what scripting language are you using? my answers will use PHP examples, but they will be similar in other languages.
what are you doing with the text?
for example, if you're displaying comments on your website, either strip_tags or htmlentities will prevent any malicious scripts from running.
If you're doing something else (like using the text to search the database), you simply need to double-check that it either 1) matches a pattern you're expecting (such as only digits 0-9 if you're expecting an id number), and/or escape the string (e.g., by using mysql_real_escape_string()) before inserting it into a query.
incidentally, don't use ereg_replace(). it's depreciated. Use preg_replace() instead (the regex and syntax is a little different).
mat420
03-09-2011, 09:01 PM
all im doing is sending the info in the text boxes to my email.
i was told tho if the site is xss vulnerable though scripts can be injected causing harm to visitors.
mat420
03-09-2011, 09:10 PM
sorry i dont know why i put this in css, if anything i guess php? no idea.
are you sending yourself plain text emails (important: <b>no html</b> in your emails)? If your input is never inserted into a database, and never used/ displayed as html, then you don't need to do anything to it.
mat420
03-10-2011, 03:45 AM
not sure if i understand the question but the users are to send me w/e msg they have for me their email name and...location ? is it? and it comes to me exactly as they type in. i dont think theres any html involved in the actual email that is received by me.
drpcrepair * c*om/contact * php if it helps any
djr33
03-10-2011, 04:17 AM
XSS attacks occur when user input becomes output, specifically when it is displayed on the website.
For example, in a comment/blog/forum script, if you allow your visitors to input anything they'd like, they can place HTML and Javascript in their comments and it will become part of the page when posted. For this reason, HTML, Javascript and other code should be removed or disabled.
However, if you are NOT actually putting this on your website (after the users submit it) then there is no danger at all.
As traq says, it might be a problem for you (and ONLY you) if they submit emails to you with HTML in them. But this is actually not a problem UNLESS you are specifically receiving these emails as HTML-encoded. If they are just plain text (as is probably the case) HTML code won't do anything-- it'll just be text.
If there is some way in which this user input is being displayed on your website (or in an HTML email or any other code-enabled medium) please let us know and we can help you work out how to disable it (make it text, not code, some way or another) so that it is not dangerous.
A technical note: XSS attacks, or cross-site scripting attacks, occur when certain Javascript is embedded in user input that is then added to the page. What it does is takes the information from the page and the user and sends it to a remote website. Basically it's like allowing users to place a spy within your pages that can potentially tell you secrets that otherwise would only be known to that user (and your server, but not OTHER users).
drpcrepair * c*om/contact * php if it helps any
that doesn't help, actually. There's no way for us to see the php code by accessing the file; you'd need to post the contents of that script (or attach it as a .txt file).
jscheuer1
03-10-2011, 01:00 PM
As djr33 says, unless it's displayed on the website, the only danger is to you in reading the emails. You can avoid that by doing just what you have done, using htmlentities on the text inputs will protect you, as would setting your email client to display only text, either is sufficient, both would be ironclad. You shouldn't need htmlentities on the output of a checkbox, but it wouldn't hurt anything.
djr33
03-10-2011, 02:18 PM
John, unless you verify that the data sent is indeed from a checkbox, there is a possibility that someone has made a duplicate form and submitted it with a text input instead of a checkbox. Or they used Javascript to set a non-binary (text) value for that input. So to be entirely secure, every input (of any type) must be either validated or escaped. One way to do this is to loop through the $_POST array, if you are blindly submitting the data to an email or website; but if you are only selecting a few items from the array they can be handled individually.
jscheuer1
03-10-2011, 08:21 PM
Is there a PHP function for that, or should a regular expression and something like preg_replace or preg_match be used?
for database insertion, mysql_real_escape_string() is all you need.
for display, it depends on the situation: if you want only plain text, you can use strip_tags(), if you want to display html tags (as text, not markup), you can use htmlentities().
If you want to allow some tags but remove others, you're best off using a custom regex via preg_replace() (or using bbcode tags instead).
djr33
03-10-2011, 11:23 PM
Like all of the options that traq listed, the question you are asking, John, must have a context.
If you are displaying it in HTML, htmlentities() is the simplest answer. That will disable all HTML and along with it Javascript, CSS, etc. Generally speaking that's what you'll use to escape a form that may be vulnerable to XSS.
But there are lots of other situations for escaping-- databases, emails, etc.
I'm partly repeating some of what you said, traq, but I hope I'm adding info, not just being redundant :)
jscheuer1
03-11-2011, 12:18 AM
If you go back to the OQ (original question), it's for email to the webmaster. So, what should be used for that? The OP is using htmlentities, and wants to know if that's sufficient. From what you two are saying, it sounds as though it's not. What would you recommend for email?
djr33
03-11-2011, 12:26 AM
What might be a vulnerability of email? What markup is active in an email program? Aside from HTML I don't know of anything that might be relevant. So htmlentities() should be fine. And if the email is not being sent (or viewed) as HTML, then you don't even need to do that-- most email programs are smart enough to ignore code unless it's specifically intended (such as through html headers for the message).
I think our posts above are suggesting alternative methods might be needed for other things with forms in general, not specific to sending as an email.
The only specific kind of email-related escaping I can think of is what might be parsed automatically such as a link. So you could attempt to "escape" all links by removing, for example, "http", and that's not something for which a default function exists in PHP.
yes, a lot of it depends on the email client.
however, IMO, if you take normal precautions and the user's email client decides to do something stupid anyway (like taking text and turning it into a block of script just because it looks like one), then it's not your problem. The user needs to get a different email client.
The number one issue here is whether or not the email is being sent as plain text or with a html mime-type. By default, email is sent as plain text. If you want php to send html emails, you need to send the mime-type along. So, in theory, if it's a plain-text email, no particular precautions need to be taken.
I don't know if any email client would automatically change the mime-type based on the content (for example, if the body of the email included html markup or something like
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
), but I can imagine it happening, and if there is such a loophole, then I'm sure, at some point, someone's exploited it by entering that very line into a text field.
Therefore, to be on the safe side, it might be prudent to use htmlentities(), regardless - changing the above example into
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
. It wouldn't hurt anything, in any case.
mat420
03-11-2011, 04:04 AM
ok let me try to remember what i wanted to say
first off thanks everyone, interesting stuff.
im using gmail.
sounds like to be safe, use htmlenities or w/e. and according to drj, to address the checkbox possibly being an issue, i cant use htmlentitites, so address it thru $_post?
## $new_string = ereg_replace("[^A-Za-z0-9]", "", $body);
mail($myaddress, 'Contact Form Submission', $new_string )
thatll solve it i guess? if so how do i change it to accept -, @, ., etc. is !@#$%^&*() safe to accept thru email?
thx so much everyone
you can use htmlentities() on a checkbox - it won't have any effect under normal circumstances, but may prevent problems if someone spoofs your form and tries to enter code using the checkbox's POST name.
BTW, the regex you show above will remove anything non-alphanumeric (including whitespace, symbols, etc.) which, I suspect, may not be what you're trying to do.
Forexampleitwouldcreatesentenceslikethis (<--note the lack of punctuation.)
If you want to simply remove all html tags (effectively killing javascript), use strip_tags().
jscheuer1
03-11-2011, 05:26 AM
I was thinking something a little more robust. Tags should be stripped or converted to entities. But I was thinking why not kill everything not on lines 2 through 7 excluding the DEL character on the ASCII chart:
http://en.wikipedia.org/wiki/File:ASCII_Code_Chart.svg
That would mean only allowing hex 20 through hex 7e (space to tilde). The only important things missing would be tabs and line breaks (\s). So something like:
$new_string = strip_tags(preg_replace("/[^\x20-\x7e\s]/", '', $body));
Notes:
I used preg instead of ereg, ereg has been deprecated.
Unless you still need the original contents of $body, there's no reason to create a new variable:
$body = strip_tags(preg_replace("/[^\x20-\x7e\s]/", '', $body));
That would turn this:
<span>Some stuff©</span>
into:
Some stuff
It occurred to me that you can use the literal characters in the regex, so I did and made a working demo:
<!DOCTYPE html>
<html>
<head>
<title>Strip Tags & Machine Code ('high' and 'low' ASCII)</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<?php
$str = "<span>Some stuff©</span>\r<div>More Stuff@stuff.com</div><script type='text/javascript'>
Some Destructive Javascript Code That Won't Run Without Script Tags
</script>";
$str = strip_tags(preg_replace("/[^ -~\s]/", '', $str));
echo "<textarea cols=50 rows=5>$str</textarea>";
?>
</body>
</html>
djr33
03-11-2011, 05:19 PM
John, the biggest problem with that would be anyone trying to send a message in a language that uses a different character set, or perhaps special punctuation characters (also names from other languages) even in English. It would be secure but overkill.
Mat, if you are the only recipient of the emails and you are using gmail, then I honestly don't see any potential problems, at all, even using raw data. Gmail protects you well enough and if you're not using HTML anyway, it should be fine. Gmail probably strips malicious JS (most of it anyway) even if you ARE using HTML. They scan every attachment for viruses before allowing you to download it, so I'd expect they'd be just as careful with the text of the message.
One warning: don't click any links in the email unless you feel that you can trust the sender; or open them on a secured computer (for example, don't use windows [which is the target of most viruses] and use a new browser session so that your cookies won't have any important information).
But realistically you're worrying way too much about this if you are not planning to automatically post the information publicly.
htmlentities() will be enough to stop any type of XSS, for any situation in which it may be relevant. No complex Regex is needed.
But again, XSS is just one type of malicious code that can be injected, but it is the only* kind of malicious code that is a problem related to HTML-- the rest is when you are using databases or doing something else-- you're not, so don't worry about it (for now).
(*Malicious HTML in general, not just XSS, but XSS is more or less the only dangerous kind-- the rest is just annoying such as something that would change the content of your page, perhaps inserting an advertisement or breaking the code so the page doesn't display properly, but not something that is truly "dangerous" like XSS that's a possible security threat. Regardless ALL HTML problems will be solved by htmlentities()-- that entirely disables the operator characters that make HTML do anything-- < > and " &. In fact, you only really need to disable < > for security. " and & just create code-instability problems and errors, but can't in themselves generate XSS or other dangerous code.)
In summary, use htmlentities() if you want to be extra careful and account for all situations including those where you would actually be using this text WITHIN HTML. If you never use it within HTML (including email, unless you're specifically sending it as HTML) then you don't even need to do that.
Getting back to the big picture, ask yourself this question: what characters make HTML work? The answer is < and >, and nothing else. You cannot write HTML (and thereby JS/CSS) without < and >, so those are the ONLY characters you need to disable. htmlentities() is one way to do that. There are other ways if you prefer.
(The only exception to that would be a very unusual case where you have incorrectly mixed character encodings so that multibyte characters, such as Chinese characters [typically 4 bytes each], are read individually, in which case one byte of the multi-byte character MIGHT be interpreted as < or >, but the circumstances for this occuring are so bizarre that you can basically ignore it. You would need to have mixed character encodings, a problem in itself, setup in exactly such a way that your checking for < and > would recognize the full multibyte characters then the final output would be displaying them separately and recognize individual bytes as < and >, but more importantly for someone to actually exploit this, they would need to predict all of this-- almost impossible and certainly not worth the effort. But if you want to protect yourself specifically from this, ALWAYS use unicode [UTF8] for everything. That's a good idea anyway in almost all cases. To be clear, though, worrying about this is a waste of time, in my opinion.)
mat420
03-12-2011, 08:40 AM
so long story short, im completely fine and dont need to worry about any attacks that can be avoided? as long as im as safe as most of the popular sites out there, im content.
after all of this tho i might as well go the extra mile and block < >
this didnt work, how would i enter it to block <, > please? feel free to add any other newly thought of characters I may want blocked.
$new_string = ereg_replace("[^<>]", "", $body);
thanks SO much everyone. not sure what id do without this forum, esp since..the others seem to suck (sshh. :oP) THANKS AGAIN!
jscheuer1
03-12-2011, 09:33 AM
Use preg, ereg has been deprecated. But the main problem is that you're still using the not token - ^. Do:
$new_string = preg_replace("/[<>]/", "", $body);
instead. Notice also that preg requires the addition of the / tokens.
If you have PHP < 4 (very unlikely), you might actually need to use ereg:
$new_string = ereg_replace("[<>]", "", $body);
mat420
03-12-2011, 10:08 AM
aawesome thanks a lot
to make things simple i first just tried using
$new_string = ereg_replace("[<>]", "", $body);
mail($myaddress, 'Contact Form Submission', $new_string );
and i sent myself a test form, and everything appears fine, no /div or anything, i assume that puts me in the clear now? thanks a million
jscheuer1
03-12-2011, 03:08 PM
to make things simple i first just tried using (ereg)
Not good, not even simple, really. To use mail(), you must have PHP 4 or greater, which supports preg. If you ever migrate to PHP 5.3 or greater (either by upgrading the host, or if it's not your own server, if the host upgrades, or if you switch to a more modern host), all code that you have that uses ereg will break.
In other words, if you don't use preg now, and use it everywhere that you may currently be using ereg, it could get real complicated finding and fixing things later. The syntax is generally the same, it just requires the extra delimiters for the regex. There may be minor exceptions, check the docs for any specific implementation. But for this, all that's required are the extra delimiters as already mentioned in my previous post.
As to what you do have:
Unless /div wasn't in the raw data, or something you're not showing is stripping it out, or mail() itself is stripping out /div, it should come through.
I looked through the documentation on php.net for mail() (that's where I discovered it requires PHP 4 or greater). It doesn't come right out and say it strips anything, but does say to (for HTML emails):
. . .
// To send HTML mail, the Content-type header must be set
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
// Additional headers
$headers .= 'To: Mary <mary@example.com>, Kelly <kelly@example.com>' . "\r\n";
$headers .= 'From: Birthday Reminder <birthday@example.com>' . "\r\n";
$headers .= 'Cc: birthdayarchive@example.com' . "\r\n";
$headers .= 'Bcc: birthdaycheck@example.com' . "\r\n";
// Mail it
mail($to, $subject, $message, $headers);
and:
Note:
If intending to send HTML or otherwise Complex mails, it is recommended to use the PEAR package » PEAR::Mail_Mime (http://pear.php.net/package/Mail_Mime).
It's possible that without employing one or the other of those two approaches, mail() is stripping the tags. But I'm really not sure. And, since you strip out <> before that, they wouldn't really be tags any more, so would be difficult (but not impossible) for mail() to identify them as tags at that point.
djr33
03-12-2011, 04:38 PM
Your site is secure, since this content doesn't appear on the site (by default). Your personal email is the only possible problem, but as we've discussed it's probably fine and definitely fine if you remove < and >.
CORRECTION: We've been mentioning the function htmlentities(). This is actually not required-- it converts extra characters than required. (It would still be secure, but it's more than you need.)
The simple function I was thinking of is htmlspecialchars().
(Note: this also converts single quotes, so that might help sometimes.)
(Sorry for the confusion-- the names of these functions are similar and they do similar things, but htmlentities() just does more than is required here.)
So you don't need to make your own function for this. Just use htmlspecialchars() and it will all be fine.
To clarify and summarize everything:
1. You are not posting user input on your website. That in itself makes your website secure.
2. You probably are secure with your email already.
3. To completely disable HTML, the characters < and > need to be disabled.
4. The easiest (default) way of doing this is htmlspecialchars().
Powered by vBulletin® Version 4.2.2 Copyright © 2021 vBulletin Solutions, Inc. All rights reserved.