Before I start I want to do a spoiler: most of this is post is a security disclosure for vulnerabilities I found in two WordPress plugins.

One of the most requested feature at the time I started to maintain Post SMTP is full email body preview in the email log.

Post SMTP only show the raw email, and when you think of this allowing full preview can cause a big headache in the security aspect.
Some of the users point me to existing plugin for reference named: “WP Mail Logging“.
The plugin has 20,000 active installs, well that is good for me.

I’m not a shame to say I always love to see other developers code, you can always learn and find new ways to get the result you wanted.

I downloaded the plugin and Contact Form 7 for the check.

First Try

My goal here is the message field and how is escaped to achieve the best preview result.
I started with the following string injection:

<script>alert(document.cookie);</script>

Everything sent, no errors, I browsed to WP Mail Log menu and pressed the View button and boom:

The result in the security world is called: Stored XSS Attack , you are welcome to read the full attack description in the link to owasp.org.

Check the code shows two problems.

Problem 1, saving the input

Checking the WPML_Plugin.php code show that input doesn’t pass any sanitize

    private function extractMessage( $mail ) {
        if ( isset($mail['message']) ) {
            // usually the message is stored in the message field
            return $mail['message'];
        } elseif ( isset($mail['html']) ) {
            // for example Mandrill stores the message in the 'html' field (see gh-22)
            return $mail['html'];
        }
        return "";
    }

Problem 2, print the input

Inside the file WPML_Email_Log_List.php the same thing

    function column_default( $item, $column_name ) {
        switch ( $column_name ) {
            case 'mail_id':
            case 'timestamp':
            case 'host':
            case 'subject':
            case 'message':
            case 'headers':
            case 'attachments':
            case 'error':
            case 'plugin_version':
            case 'receiver':
                return $item[ $column_name ];
            default:
                // If we don't know this column maybe a hook does - if no hook extracted data (string) out of the array we can avoid the output of 'Array()' (array).
                return ( is_array( $res = apply_filters( WPML_Plugin::HOOK_LOGGING_COLUMNS_RENDER, $item, $column_name ) ) ) ? '' : $res;
        }
    }

The conclusion here that every email field that gets external input is vulnerable to cross-site scripting.

Second try

OK, let’s leave WP Mail Logging on the side, I downloaded Email Log – 10,000 active installs.

Same test, SAME RESULTS – Stored XSS.

What did I do?

I work full time, I didn’t have too much time to monitor the developers fix on this, so I contact WordPress plugin team.
After one shutdown the developers fix the only the message body, I thought they will understand to check everything. so for the second time, I contact them myself, felt bad to cause the second shutdown.

If you want mail logging solution I want to highly recommend the plugin Email Log by Sudar. Sudar answer by contact and updated me after the fix super fast.

While the WP Mail Logging developer didn’t even reply back and notice he fixed it after a day (maybe more).

** Edit: Christian Zöller answered me this in my facebook post:

You should have respected my wish to use one of the listed support channels instead of my private website. (I don’t run a mailserver but catch all mails with my plugin). Stored XSS is possible due the nature of my plugin: log mail 1:1. XSS was an security issue for sure – message vuln. fixed 4h after suspension (but delayed due review process) of the plugin. Field vuln. fixed 2h after finding your mail unexpected in my WP backend. Thanks for your cooperation. https://goo.gl/n173ub

The short link is for a book cover that I can only guess deal with the thankless of open source software –
well, it’s an exaggerate hint, no one is forcing to maintain an open source software.

My answer:

My responsibility is to notify you as soon as possible and for me, the contact form on your website for reporting “not a bug issue” was the best notify option.
Maybe you should consider making the message more clear about mail server issue.
Side note: tried to contact you in Slack too.

Even if for your opinion I did something wrong, for the security of your 20,000 users you should respond me back in an adult way back by email, and not “punish” me for not listening to your message.

Conclusion

I’m not a security expert, the XSS attack is one of the attacks I know and can easily test.

If you have one of the plugins installed you SHOULD update immediately to the latest version.