Skip to main content
  1. posts/

XSS in Outlook Adaptive Cards via Action.OpenUrl

While testing Adaptive Cards in Outlook, I discovered a cross-site scripting (XSS) vulnerability that allows an attacker to execute arbitrary JavaScript in the context of a victim’s Outlook inbox. The vulnerability exists in how Outlook handles the Action.OpenUrl action in Adaptive Cards, which does not properly validate URLs before passing them to window.open().

The Vulnerability #

The vulnerability exists in how Adaptive Cards handle the Action.OpenUrl action. This property is designed to open URLs when clicked, but it does not properly validate that the URL is actually a valid HTTP/HTTPS URL before passing it to window.open(). This allows an attacker to inject JavaScript code using the javascript: protocol scheme.

When a user clicks on an action button in an Adaptive Card, the url value from Action.OpenUrl is passed directly to window.open(), which will execute JavaScript payloads. Even though this execution occurs in a new window, the JavaScript can use window.opener to gain full access to the recipient’s inbox, allowing for session hijacking, data exfiltration, and other malicious activities.

The root cause is a combination of factors:

  • The Action.OpenUrl property does not validate URLs before use
  • The URL is passed directly to window.open() without sanitization
  • No Content Security Policy (CSP) is in place to prevent JavaScript execution
  • The window.opener property allows the new window to access the parent window’s context

Affected Products #

  • Outlook Web App: Vulnerable to XSS via Action.OpenUrl in Adaptive Cards
  • Microsoft Teams: The payload is passed along, but JavaScript execution is blocked by CSP (partial mitigation)
  • Other products using Adaptive Cards: Potentially affected depending on their implementation

The vulnerability affects any product that renders Adaptive Cards with Action.OpenUrl actions without proper URL validation.

How It Works #

The attack works by crafting an Adaptive Card with a malicious Action.OpenUrl that uses the javascript: protocol:

  1. Card Creation: An attacker creates an Adaptive Card with an Action.OpenUrl action containing a javascript: URL
  2. Card Delivery: The card is sent to a victim via email (or other delivery mechanism)
  3. User Interaction: When the victim clicks the action button, the URL is passed to window.open()
  4. JavaScript Execution: The JavaScript payload executes in a new window
  5. Context Access: The malicious JavaScript uses window.opener to access the parent window (Outlook inbox)

Even though the JavaScript executes in a new window, window.opener provides full access to the parent window’s context, allowing the attacker to:

  • Access the victim’s inbox
  • Read email content
  • Perform actions on behalf of the user
  • Exfiltrate sensitive data
  • Steal authentication tokens

Proof of Concept #

To demonstrate this vulnerability, you can use the Adaptive Cards MessageCard Playground:

Steps to Reproduce #

  1. Browse to https://messagecardplayground.azurewebsites.net/
  2. Authenticate with the application
  3. Send the following payload:
{
    "$schema": "https://adaptivecards.io/schemas/adaptive-card.json",
    "type": "AdaptiveCard",
    "version": "1.0",
    "body": [
        {
            "type": "ColumnSet",
            "columns": [
                {
                    "type": "Column",
                    "width": "10",
                    "items": [
                        {
                            "type": "Image",
                            "size": "auto",
                            "horizontalAlignment": "center",
                            "url": "https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/160/microsoft/106/hacker-cat_1f431-200d-1f4bb.png",
                            "altText": "Mostly cloudy"
                        },
                        {
                            "type": "TextBlock",
                            "horizontalAlignment": "center",
                            "wrap": false,
                            "color": "dark",
                            "text": "Test XSS"
                        }
                    ],
                    "selectAction": {
                        "type": "Action.OpenUrl",
                        "title": "View Sunday",
                        "url": "javascript:alert(window.opener.location.href)"
                    }
                }
            ]
        }
    ]
}
  1. Click “Send Via Email” from the top bar to send this to yourself
  2. Check your email from Outlook web
  3. Click on the Action button

The JavaScript alert will execute, demonstrating that the XSS vulnerability is present. In a real attack, this could be replaced with malicious code that exfiltrates data or performs unauthorized actions.

Additional Payload (New Outlook) #

Interestingly, the following payload works on “the new Outlook” but is blocked in the other version:

{
    "@type": "MessageCard",
    "@context": "https://schema.org/extensions",
    "summary": "Issue 176715375",
    "themeColor": "0078D7",
    "title": "Test XSS",
    "sections": [
        {
            "text": "Test from OpenUri"
        }
    ],
    "potentialAction": [
        {
            "@type": "OpenUri",
            "name": "View in GitHub",
            "targets": [
                {
                    "os": "default",
                    "uri": "javascript:alert(1)"
                }
            ]
        }
    ]
}

This demonstrates that the vulnerability exists in multiple card formats and affects different versions of Outlook differently.

Testing with Originator #

This vulnerability was tested not only by sending emails to myself, but also with an “originator” key, delivering the payload to anyone in my organization. This confirms that the vulnerability is not limited to “self” emails and can be exploited against any recipient.

The Impact #

This vulnerability is particularly dangerous because:

  • Session hijacking: An attacker can steal authentication tokens and session cookies from the victim’s Outlook session
  • Data exfiltration: The attacker can read email content, contacts, and other sensitive information from the victim’s inbox
  • Unauthorized actions: The attacker can perform actions on behalf of the user, such as sending emails, deleting messages, or modifying settings
  • Credential theft: The attacker could potentially access other services if the victim uses single sign-on (SSO)
  • Persistent access: The attacker could establish persistent access to the victim’s account

The attack is especially concerning because it requires minimal user interaction; just clicking on a button in an email. The user doesn’t need to explicitly visit a malicious website or download a file; the vulnerability is triggered through normal email interaction.

Expected Fixes #

I would expect the following security measures to be implemented:

  1. URL Validation: Proper validation of the Action.OpenUrl property to ensure it only accepts valid HTTP/HTTPS URLs
  2. Protocol Whitelisting: Only allow http:// and https:// protocols, explicitly blocking javascript:, data:, and other potentially dangerous protocols
  3. Content Security Policy: Implement CSP headers to prevent JavaScript execution even if validation fails
  4. Sanitization: Sanitize all user-controlled input before passing it to window.open()
  5. Same-Origin Restrictions: Consider using rel="noopener" or similar mechanisms to prevent window.opener access

Disclosure #

This vulnerability has been reported to Microsoft through their security program. The issue demonstrates the importance of proper input validation and the need for defense-in-depth security measures, including Content Security Policies, even when validation is in place.

References #

  1. Adaptive Cards Documentation
  2. MessageCard Playground
  3. Proof of Concept Video
  4. OWASP XSS Prevention Cheat Sheet
  5. Content Security Policy (CSP)