Fixing the "Possible XSS attack - ignoring email" error message in Postie
As you may know if you read my earlier post on
fixing the Wordpress plugin Postie when it wouldn't let me pass multiple categories in their various formats in the subject line
a new version of Postie has come out since.
However I have been regularly noticing that emails that should be appearing on my Wordpress site when they are
posted by email using Postie haven't been.
Today I looked into why and when I ran the manual process to load emails by pressing the
"Run Postie" button I was met with an error message that said
possible XSS attack - ignoring email
I looked into the code and searched for the error message which is on line 38 of the file
postie_getmail.php and it gets displayed when
a Regular Expression runs that is supposed to detect XSS attacks.
The code is below
if (preg_match("/.*(script|onload|meta|base64).*/is", $email)) {
echo "possible XSS attack - ignoring email\n";
continue;
}
I tested this was the problem by
running the script manually in the config area of Postie and outputting the full email before the regular expression test.
As
the email is base64 encoded (well mine is anyway) the full headers are shown at the top of the encoded email e.g
Return-Path:
X-Original-To: xx12autopost230.sitename@domain-name.com
Delivered-To: xx12autopost230.sitename@domain-name.com
Received: from smtp-relay-2.myrelay (smtp-relay-2.myrelay [111.11.3.197])
by domain-name.com (Postfix) with ESMTP id 8497724009C
for ; Mon, 22 Oct 2012 05:49:32 +0000 (UTC)
Received: from xxxxxxx (unknown [11.1.1.1])
by smtp-relay-2.myrelay (Postfix) with ESMTP id 9E3B495733
for ; Mon, 22 Oct 2012 06:45:30 +0100 (BST)
MIME-Version: 1.0
From: admin@sitename.com
To: xx12autopost230.sitename@domain-name.com
Date: 22 Oct 2012 06:46:28 +0100
Subject: Subject: [My Subject Category1] [My Subject Category2] Title of Email
October 2012
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding:
base64
Message-Id: <20121022054530 .9e3b495733=".9e3b495733" smtp-relay-2.myrelay="smtp-relay-2.myrelay">20121022054530>
PHA+PHN0cm9uZz5ZZXN0ZXJkYXlzIG1lbWJlcnMgaGFkIGFjY2VzcyB0byA0NSB0aXBzIGFj
cm9zcyA4IGRpZmZlcmVudCBzeXN0ZW1zLjwvc3Ryb25nPjwvcD48cD5JZiB5b3UgaGFkIHBs
YWNlZCBhIEJldGZhaXIgbWluaW11bSBiZXQgb2YgJnBvdW5kOzIuMDAgb24gZWFjaCBiZXQg
PHN0cm9uZz5vbiBFVkVSWSBzeXN0ZW08L3N0cm9uZz4gKExheXMsIFBsYWNlIERvdWJsZXMs
IFdpbnMgZXRjKSB0aGF0IGhhZCBhbiBTUCBsZXNzIHRoYW4gMTkvMSBhdCB0aGUgdGltZSBJ
I've just shown a bit of the message which is base64 encoded.
As you can see if you do a search for one of the strings he is searching for as a word not in a scriptual context e.g
base64 not base64("PHA+PHN0cm9");
The word base64 appears in the headers of the email e.g:
Content-Transfer-Encoding: base64
Therefore the regular expression test fails and Postie displays the "
possible XSS attack - ignoring email" error message.
Therefore just doing a basic string search for these words:
script, onload, meta and
base64
Will mean that you could find yourself having emails deleted and content not appearing on your Wordpress site when you expect it to. All due to this regular expression which will be popping up
false positives for XSS attacks when none really exist.
Also these words could legitimately appear in your HTML content for any number of reasons and not just because they are used in the email headers so a better regular expression is required to
check for XSS attacks.
How to fix this problem
You could either
remove the word base64 from the regular expression or you could delete the whole test for
the XSS attack.
However I went for
keeping a test for XSS attacks but making sure they were checking more thoroughly for proper usage of the functions rather than simple tests for occurrences of the word.
The regular expression is more complicated but it covers more XSS attack vectors and I have tested it myself on my own site and it works fine.
You can replace the code that is causing the problem with the code below.
if(preg_match("@((%3C|<)/?script|<meta|document\.|\.cookie|\.createElement|onload\s*=|(eval|base64)\()@is",$email)){
echo "possible XSS attack - ignoring email\n";
continue;
}
Not only does this mean that it won't fall over when the words are mentioned in headers but it actually looks for the correct usage of the hack and not just the word appearing. E.G instead of looking for "
script" it will look for
<script %3Cscript </script %3Cscript
This includes not only the basic <script but also
urlencoded brackets which are another
common XSS attack vector. You could include other forms of encoding such as
UTF-8 but it all depends on how complicated you want to make the test.
As you may know if you have read my blog for a long time hackers are always changing their methods and I have come across
clever two stage SQL injection attacks which involve
embedding an encoded hack string first and then a second attack that's role is to
unencode the first injection and role out the hack.
The same can be done in
XSS attacks, e.g encoding your hack so it's not visible and then decoding it before
using an eval statement to execute it. However I am keeping things simple for now.
I have also added some more well known
XSS attack vectors such as:
eval( , document. , .createElement and .cookie
As you can see I have all prefixed or suffixed them with a bracket or dot which is how they would be used in
JavaScript or PHP.
Notice however that I haven't prefixed
createElement and
cookie with the word
document. This is because it is all too easy to do something like this:
var q=document,c=q.cookie;alert(c)
Which stores
the document object in a variable called
"q" and then uses that to
access the cookie information. If you have a console just run that piece of JavaScript and you will see all your cookie information.
This regular expression still also tests for:
<script, base64(, <meta, onload= and onload =
but as you can see I have prefixed the words with angled brackets or suffixed them with rounded brackets, dots or equal signs (with or without a space).
This has solved the problem for me and
kept in the XSS attack defence however if you are passing
HTML emails containing JavaScript to your site just beware that if you use any of these functions they might be flagged up.
but let me know of any problems with the regular expression.
before and after the original test as it's not required. Also it just uses up memory as its
and the longer the string it's searching the more memory it eats up.
I have updated my own version of this file and everything has gone onto the site fine since I have done so.