Back to Articles

How a Browser Userscript Bypassed Skype's Message Sanitization

[ View on GitHub ]

How a Browser Userscript Bypassed Skype's Message Sanitization

Hook

What happens when a 50-line userscript can bypass years of security engineering? SkypeDestroyer proved that even Microsoft's Skype couldn't fully prevent client-side message tampering.

Context

In the mid-to-late 2010s, Skype Web emerged as Microsoft's browser-based answer to desktop messaging clients. Like most web applications handling user-generated content, it implemented HTML sanitization to prevent cross-site scripting (XSS) attacks and maintain message consistency across clients. The client-side JavaScript would escape HTML tags, strip dangerous attributes, and ensure that what you typed was what recipients saw—no hidden links, no font injection, no surprises.

But here's the architectural problem: Skype Web, like many single-page applications, performs input sanitization in the browser before sending messages to the server. This creates a window of opportunity. If someone can intercept the message between user input and transmission, they can modify it before sanitization occurs—or replace the sanitized content entirely. SkypeDestroyer was a proof-of-concept that exploited exactly this gap. Built as a TamperMonkey userscript, it demonstrated how browser extensions could manipulate the DOM and outgoing network requests to inject arbitrary HTML into Skype messages, bypassing all client-side protections. It wasn't about finding a server-side vulnerability; it was about controlling the client so completely that server-side validation became the only defense.

Technical Insight

Skype Web Client

SkypeDestroyer Userscript

No

Yes

User Types Message

in Skype Web

Starts with

'#' command?

Normal Skype

Send Flow

Parse Command

Syntax

Extract Parameters

URL, Display Text

Generate Malicious

HTML Payload

Inject into

DOM/Message

Bypass Skype

Sanitization

Send Modified

Message

System architecture — auto-generated

SkypeDestroyer operates at the intersection of DOM manipulation and event interception. When you load web.skype.com with this userscript active, it injects itself into the page's JavaScript execution context and begins monitoring the message composition area. The script watches for specific command prefixes that trigger transformations. For example, typing #link|https://malicious.com|Totally Safe Bank Site would send a message where the displayed text reads "Totally Safe Bank Site" but the actual hyperlink points to a completely different domain—a classic phishing vector.

The technical approach relies on intercepting Skype's message sending mechanism. Here's a simplified version of how the transformation pipeline works:

// Intercept the contenteditable div where users type messages
const messageInput = document.querySelector('[contenteditable="true"]');

// Listen for send events (Enter key, send button click)
messageInput.addEventListener('keydown', function(e) {
  if (e.keyCode === 13 && !e.shiftKey) {
    const rawMessage = messageInput.innerText;
    
    // Parse custom command syntax
    if (rawMessage.startsWith('#')) {
      e.preventDefault();
      e.stopPropagation();
      
      // Transform: #link|URL|Display Text
      const parts = rawMessage.substring(1).split('|');
      if (parts[0] === 'link' && parts.length === 3) {
        const injectedHTML = `<a href="${parts[1]}">${parts[2]}</a>`;
        
        // Directly manipulate the DOM or intercept XHR
        messageInput.innerHTML = injectedHTML;
        
        // Trigger Skype's send mechanism with modified content
        triggerSkypeSend();
      }
    }
  }
});

The genius—and danger—of this approach is that it operates at the browser extension privilege level. TamperMonkey scripts run with elevated permissions that allow them to modify page behavior before the web application's own JavaScript executes defensive measures. By the time Skype's sanitization code runs, the userscript has already replaced the message content with raw HTML.

The script also implemented other transformations: !font|red|text would wrap content in <font color="red"> tags, and ##heading would apply heading styles. Each command exploited the same vulnerability: Skype Web trusted that the content in the composition area was what the user actually typed, rather than what a script injected.

The DOM manipulation strategy reveals a fundamental architectural tension in modern web applications. Single-page apps use frameworks like React or Angular that manage DOM state through virtual DOM diffing and controlled updates. When a userscript forcibly mutates the DOM outside the framework's knowledge, it creates a race condition. If the userscript's changes happen after the framework captures state but before transmission, those changes persist in the outgoing message. SkypeDestroyer exploited this exact timing window.

From a security perspective, this demonstrates why client-side validation alone is insufficient. The proper defense requires server-side HTML sanitization that treats every incoming message as potentially malicious, regardless of what the client claims to have sent. If Skype's servers had stripped all HTML tags and re-encoded special characters before storing or forwarding messages, SkypeDestroyer would have been harmless. The vulnerability wasn't in Skype's code per se—it was in the architectural decision to rely on client-side enforcement for security-critical operations.

The broader lesson for developers building web applications: never trust the client. Even if your JavaScript implements perfect input validation, users can disable it, modify it, or replace it entirely through browser extensions, DevTools manipulation, or intercepting proxies. Security boundaries must exist on the server, where attackers can't simply edit the code.

Gotcha

The repository is archived and has been non-functional for years. Skype Web has undergone multiple complete rewrites since this userscript was created, changing DOM structure, element selectors, and message transmission mechanisms. The specific CSS selectors and event listeners SkypeDestroyer relies on no longer exist in the current version of the application. More importantly, Microsoft appears to have implemented server-side HTML sanitization, which means even if you could get the injection to work client-side, the server would strip the malicious content before forwarding it to recipients.

There are also serious ethical and legal considerations. Using tools like this to inject misleading HTML into messages could constitute fraud, phishing, or violation of computer fraud laws depending on jurisdiction and intent. Bypassing an application's security measures, even for "fun" or "research," crosses into legally gray territory. The repository exists as a historical artifact and educational example, but deploying it in real conversations could have consequences ranging from account suspension to criminal liability. This isn't a tool for pranks—it's a demonstration of exploitation techniques that should inform defensive programming practices, not offensive actions.

Verdict

Use if: You're studying web application security vulnerabilities, learning how browser userscripts can manipulate page behavior, or teaching developers why server-side validation is non-negotiable. This repository serves as an excellent case study in client-side exploitation patterns and the limitations of trusting browser-based input sanitization. It's valuable in academic or training contexts where you're dissecting what went wrong and how to prevent similar vulnerabilities in your own applications. Skip if: You want a functional tool for modifying Skype messages (it doesn't work anymore), you're looking for legitimate message formatting options (use official platform features), or you're considering using client-side manipulation techniques in production systems (don't—implement proper server-side validation instead). This is a security research artifact, not a deployment-ready tool.

// ADD TO YOUR README
[![Featured on Starlog](https://starlog.is/api/badge/cybersecurity/mitchzinck-skypedestroyer.svg)](https://starlog.is/api/badge-click/cybersecurity/mitchzinck-skypedestroyer)