That's a cool idea for a hack -- and I haven't seen it in my logs yet...
I'll have to unit test my validator to make sure it doesn't happily send
that along, but I'm 99% sure it won't.
I'm totally a validation nut -- I validate to the point of overkill, and
while I don't explicity test for specific attacks, I code with the
expectation of user abuse, and try to take an approach that will just
simply hose anything that isn't input that I'm expecting. In many
instances, I don't necessarily care that the user enters garbage, as
long as it doesn't make it to my sendmail or database daemons.
After years of writing one-offs for validation, I finally broke down and
created a "Sanitize" class that I pipe all user input through. I built
it initially for preventing SQL injection attacks, and have expanded it
to include various kinds of input that are specific to projects that I'm
working on, and some that my employer would be pissed about me handing
out. Sanitize::text is pretty simple (and fast), and I bet it would
thoroughly hose any attempt like you're describing below. Our lead QA
engineer pounded on an email script I wrote using similar techniques
with no success. The only thing I'm doing is validating the sender's
email address, and running all of the text input through the method below.
Here's the function I use --- I pass pretty much all user input through
this -- you can come up with instances where it would be bad, but it
works in 99% of the circumstances I come across regularly:
Transforming input to html entities ensures that they're still render if
they're retreived from a database and sent back to the user. The %
might slip by htmlentities(), as there's no correlating HTML entity, in
which case, you could use the ereg_replace example below (or incorporate
it into the sanitize::text method) to strip all non-alpha characters.
class Sanitize() {
// We don't need a constructor
function Sanitize() {
return true;
}
/**
* Sanitizes freeform text for database storage
* Replaces slashes, single and double quotes with character codes
* Strips HTML tags
* @param $strText user text
* @return string Sanitized user text
*/
function text($strText,$boolAddSlashes=false) {
// Replace any HTML special characters with their HTML entity
equivalents
$strText = htmlentities(strip_tags($strText),ENT_QUOTES,'UTF-8');
if($boolAddSlashes == true) {
$strText = addslashes($strText);
}
return $strText;
}
}
I just call Sanitize::text as a static method... like
<?php
require_once('class.sanitize.php');
$strUserInput = Sanitize::text($_POST['user_input']);
?>
This little guy might be handy too...
// Strip any weird punctuation and replace it with a space
// This will kill quotes, so you might want to use sanitize::text first.
$strKeywords = ereg_replace("[^[:space:]a-zA-Z0-9]", " ", $strKeywords);
If it's eating your punctuation, you might need to modify it a little...
I don't feel like testing it right now, so YMMV, but this seems
reasonably permissive...
$strKeywords = ereg_replace("[^[:space:]a-zA-Z0-9;.,&-?]", " ",
$strKeywords);
That should definitely hose hex input.
Oh, and I found this after doing a lot of research.
IMO, it's the definitive email validator.
<?php
//Good, lightweight email validation
/**
* Validates an email address based on RFC 2822
* @param $strEmailAddress email
* @return bool
*/
function validate_email_address($strEmailAddress) {
// The email is invalid because it meets one of the following criteria:
// There is a wrong number of characters in one section (Length of 0
or exceeds maxlength)
if (!ereg("[EMAIL PROTECTED],[EMAIL PROTECTED]@]{1,255}", $strEmailAddress)) {
return false;
}
// We`ll split the email address into it`s basic parts
$arrEmail = explode("@", $strEmailAddress);
// If $arrEmail is bigger than two elements, there are too many @`s in
the email address.
if(sizeof($arrEmail) != 2) {
return false;
}
$arrLocal = explode(".", $arrEmail[0]);
for ($i = 0; $i < sizeof($arrLocal); $i++) {
if(strlen($arrLocal) < 1) {
return false;
}
if
(!ereg("^(([A-Za-z0-9!#$%&'*+/=?^_`{|}~-][A-Za-z0-9!#$%&'*+/=?^_`{|}~\.-]{0,63})|(\"[^(\\|\")]{0,62}\"))$",
$arrLocal[$i]
)) {
return false;
}
}
// Check to see if the domain is an IP Address
// If not, it should be a valid domain name.
if (!ereg("^\[?[0-9\.]+\]?$", $arrEmail[1])) {
// Explode the domain
$arrDomain = explode(".", $arrEmail[1]);
// If the domain array isn't at least two parts, it's wrong
if (sizeof($arrDomain) < 2) {
return false;
}
for ($i = 0; $i < sizeof($arrDomain); $i++) {
if
(!ereg("^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|([A-Za-z0-9]+))$",
$arrDomain[$i])) {
return false;
}
}
} else {
// If it`s an IP domain, it should have four elements
$arrDomain = explode(".",$arrEmail[1]);
if(sizeof($arrDomain) != 4) {
return false;
}
}
return true;
}
?>
-Jeromie
>Hi All,
>
>One of my sites has been subjected to injection attacks recently. I've
>done what I can for the moment and searching for "TO:" and "CC:" in
>the user input foils most attempts. However, some attempts are getting
>a little too close for comfort. These attacks are not succeeding - but
>only because of a side effect of some unrelated cleaning that my
>script performs before calling the mail() function.
>
>The problem seems to be that the attacker is encoding some or all of
>their input as hex, which the PHP interpreter is happily decoding and
>then acting upon. For example, an attacker might inject a BCC: field
>by encoding it as %62%63%63%3A.
>
>Is there a PHP function to decode inline hex, for example to decode
>the above example to "bcc:" ?
>
>TIA,
>
>
>
------------------------ Yahoo! Groups Sponsor --------------------~-->
Get Bzzzy! (real tools to help you find a job). Welcome to the Sweet Life.
http://us.click.yahoo.com/A77XvD/vlQLAA/TtwFAA/CefplB/TM
--------------------------------------------------------------------~->
The php_mysql group is dedicated to learn more about the PHP/MySQL web database
possibilities through group learning.
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/php_mysql/
<*> To unsubscribe from this group, send an email to:
[EMAIL PROTECTED]
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/