Kevin Froman's blog

Blog on security, programming, & other musings

Exploiting I2P 3


This is part 3 in my series of exploits in I2P/related software, I recommend reading the 1st and 2nd posts first.

As I continued testing I2P software, I have discovered the most severe vulnerability yet, once again within I2P-Bote, a distributed email system for I2P.

Unable to find any more CSRF vulnerabilities, I decided to look for another common vulnerability, XSS (Cross-Site scripting), in which I found 2 critical issues.

i2p mascot

All user input is evil

When developing any software, a developer should assume that the user is going to input the most, nonsensical, perhaps even evil input possible, and account for it. This is information security 101.

As I have mentioned before, I2P and much of its related software is potentially vulnerable to traditional browser exploits, such as XSS. In a browser context, a developer must be careful when any data supplied by a 3rd party is rendered to the page. A commonly overlooked vector is file names. Despite size & character restrictions, a file name can easily contain malicious code.


When Bote listed file names as email attachments, it did not use any sanitation, allowing for arbitrary HTML code to be injected into the user’s client when they open an email. While this in itself is dangerous, I was not happy with the restricted size of the payload.

(Bote also failed to sanitize its title tag & another title area.)

Increasing payload size with eval

One thing that Bote did properly sanitize was the main message area; however, it occurred to me that I could still place code inside in the message and force it to execute using the eval() function in JavaScript, which executes a string as code.

I wrote a 1 liner to identify & execute the message contents, with the malicious filename being as follows:

<img style='display: none;' src=x onerror=eval(document.getElementsByClassName('show-email-value')[6].innerHTML)>.bin

Payload Concept

The Bote back-end applied some formatting, so I used JSF*ck to encode a simple payload, with the deobfuscated version being:

var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
}"GET", "", true);

This small payload demonstrates how XSS within I2P’s plugins can be used to exfiltrate a nonce from the I2P router page, allowing for an attacker to–among other things– install custom plugins into the user’s I2P client. Under most circumstances the plugin would have access to the user’s machine at the permission level I2P is running, and could in turn download additional malware.

CSS Payload

Although serious exploitation requires users to have JavaScript enabled, a full page link could have still been lain over the page using CSS, redirecting the user when they click anywhere to a malicious page.

Fixing Bote

I reported the vulnerability to str4d, who fixed the issues in a timely manner. We came to the conclusion that the best way to remedy the situation was to both sanitize all user input and also to implement a Content Security Policy header for stronger defense in depth.

I2P Bote version 0.4.5 addresses these issues.


I would like to thank str4d again for his work on I2P & I2P-Bote.

Written by anonymous