A simple proof-of-concept implementation of WASM-based HTML smuggling. Unlike other implementations, this one uses web-sys to manipulate the DOM and register event handlers with pure Rust, so all you have to do is import the web assembly like so:
import init from '../pkg/smuggle_rs.js';
await init();The resulting web assembly will work out of the box with any input element (such as a button) that supports the click event. As soon as the input element is clicked, the file will be downloaded (as long as the web assembly is loaded).
If you need to support other elements or events, simply modify lib.rs and change the event handler that calls initiate_download(). If you use this in production, I recommend you rename the WASM and JS files to something innocuous, and update all references within the autogenerated JavaScript "glue" files.
This is only released for educational purposes.
You will need the basic Rust toolchain to build this project, along with wasm-pack. We use environment variables to pass information about the payload at compile time:
- SMUGGLER_ID: The ID of the HTML input element we are using as a trigger.
- SMUGGLER_EVENT: Which event we should be handling on the trigger element.
- SMUGGLER_PAYLOAD: The base64-encoded data that should be served to the user.
- SMUGGLER_FILENAME: The filename that should be specified.
The provided build.sh script is prefilled with valid examples for the demo (which uses a button with an ID of dlinit):
$ ./build.shWhen compilation is complete, the WASM and JavaScript glue files will be compiled to the pkg directory. From the root of the repository:
$ python3 -m http.serverThen navigate to:
Click on the button and the file should be downloaded with no additional HTTP requests.