Click the icon to Follow me:- twitterTelegramRedditDiscord


Sometimes, while investigating incident implying emails, you can get a copy of the original message in EML format. Reading an EML file is not easy with all the SMTP headers and the multiple MIME parts it may contain. But it may also contain suspicious code that is dangerous to be executed from sensitive environments. EMLRender is a Python script that provides a REST API to render submitted EML files into PNG images. This way, it’s easy to have a clear overview of the mail content.

Here is a sample of generated image: 

image 12
Sample Email


EMLRender is based on the wkhtmltoimage tool to render HTML code. It consists of a single Python script that provides an HTTP interface or REST API. The best way to use it is to run it in a Docker container. This way, it can be easily deployed.


Building the container

Use the provide Dockerfile to build your image:

$ git clone https://github.com/xme/emlrender
$ cd emlrender
$ docker build -t emlrender:latest .

An image is ready to use on hub.docker.com: https://hub.docker.com/r/rootshell/emlrender/

Starting the container

EMLRender is a stand-alone container that does not have any dependency.

$ docker run emlrender:latest

Once started, it will listing to port 443. Note: a self-signed certificate is generated when the container is created.

Setup & Configuration

User database creation

EMLRender requires user authentication to render EML files. The first action is to generate the users database and an admin account:

$ curl -k -X POST -d '{"password":"strongpw"}'
[{"message": "Users database successfully initialized"}, {"password": "strongpw"}]

If you don’t specify a password, a random one will be generated:

$ curl -k -X POST -d '{}'
[{"message": "Users database successfully initialized"}, {"password": "1o03uqjm6w"}]

User accounts management


New users can be added with the following request:

$ curl -k -u admin:secretpw -X POST -d '{"username":"john", "password":"strongpw"}'
[{"message": "Account successfully created", "username": "john", "password": "strongpw"}]

Note: If no password is provided, a random one will be generated.

Password change

Account passwords can be changed with the following request:

$ curl -k -u admin:secretpw -X POST -d '{"username":"john", "newpassword":"verystrongpw"}'
[{"message": "Password successfully updated", "username": "john", newpassword": "verystrongpw"}]

Note: Regular users can change their own password.


Users can be deleted with the following request:

$ curl -k -u admin:secretpw -X POST -d '{"username":"john"}'
[{ "message" : "Account successfully deleted" }]

Users listing

A list of users can be fetched with the following request:

$ curl -k -u admin:secretpw
[{"message": "Success"}, {"username": "admin"}, {"username": "john"}]


Help page

A simple help page is available when you point your browser to the following URL:

EML Rendering


To submit an EML file, use the following request:

$ curl -k -u john:strongpw -F [email protected]"spam.eml" -o spam.png

The generated picture will be saved into spam.png. It is possible to submit a ZIP archive containing the EML file (encrypted archives are supported):

$ curl -k -u john:strongpw -F [email protected]"malicious.zip" -F password=infected -o malicious.png

Web browser

Point your browser to to submit your EML file via a normal HTML form.


HTTP log

A classic HTTP log is available via the Docker interface:

$ docker logs -f emlrender
 * Running on (Press CTRL+C to quit) - - [18/May/2018 11:59:43] "POST /init HTTP/1.1" 200 - - - [18/May/2018 12:06:36] "POST /users/add HTTP/1.1" 200 - - - [18/May/2018 12:12:08] "GET /users/list HTTP/1.1" 200 -

The application log is available via the api.log file in the container:

$ docker exec -it emlrender tail -f api.log
[2018-May-18 11:59] POST /init? [INFO] Init page requested
[2018-May-18 11:59] POST /init? [INFO] Users database successfully initialized
[2018-May-18 12:06] POST /users/add? [INFO] AddUser page requested
[2018-May-18 12:06] POST /users/add? [INFO] Admin authentication successful
[2018-May-18 12:06] POST /users/add? [INFO] Account john successfully created
[2018-May-18 12:12] GET /users/list? [INFO] ListUsers page requested
[2018-May-18 12:12] GET /users/list? [INFO] Accounts list successfully returned
[2018-May-18 12:24] POST /upload? [INFO] User john successfully authenticated
[2018-May-18 12:24] POST /upload? [INFO] Date: Fri, 18 May 2018 10:38:26 +0200
[2018-May-18 12:24] POST /upload? [INFO] From: <redacted>
[2018-May-18 12:24] POST /upload? [INFO] To: <redacted>
[2018-May-18 12:24] POST /upload? [INFO] Subject: <redacted>
[2018-May-18 12:24] POST /upload? [INFO] Message-Id: <redacted>
[2018-May-18 12:24] POST /upload? [INFO] Created headers 6346209b0e191fe5e9a740db4e7a2db6.png
[2018-May-18 12:24] POST /upload? [INFO] Multipart found, continue
[2018-May-18 12:24] POST /upload? [INFO] Found MIME part: text/plain
[2018-May-18 12:24] POST /upload? [INFO] Decoded 693d8cdec2a72278157ac4bb107b44b0.png
[2018-May-18 12:24] POST /upload? [INFO] Found MIME part: text/html
[2018-May-18 12:24] POST /upload? [INFO] Decoded 461c46fefa1b887857398ba17446b822.png

Download the tool from its GitHub REPO located here

Available for Amazon Prime