Exploiting Slack Video Embeds for End-to-End Encryption

Slack Video Blocks as a Vector for Client-Side Execution

Slack's video_url field within the video block allows for the execution of arbitrary client-side code because it lacks runtime content validation. While intended for video embeds, the platform only verifies that the provided URL is accessible and returns a 2xx or 3xx HTTP response code. Once verified, the content is rendered as a simple iframe, enabling developers to load custom web applications directly within the Slack interface.

Implementing End-to-End Encryption (E2EE) in Slack

By utilizing the iframe capability of video blocks, it is possible to build a system where cryptographic keys are handled exclusively on the client side, ensuring the server never sees decrypted private keys. The implementation uses the browser's Subtle Crypto API and the openpgpjs library (maintained by Proton) to handle the complex cryptographic operations.

The E2EE Workflow

The process for sending an encrypted message follows these steps:

  1. Initiation: The user executes the /e2ee send command, which opens a Slack modal to select recipients.
  2. Slug Generation: The server generates a unique slug containing the author's encrypted private key and the recipients' public keys, storing this in a KV database.
  3. Client Loading: When the user interacts with the video block, the local client loads the data associated with the slug.
  4. Local Decryption: The author decrypts their private key locally using a passphrase.
  5. Local Encryption: The author writes the message, encrypts it for the recipients, and signs it with their own key—all performed locally within the iframe.
  6. Transmission: Only the encrypted ciphertext is sent back to the server.
  7. Delivery: The server delivers "envelopes" containing the encrypted message to the recipients.

Technical Constraints and Implementation Details

  • TypeScript: The project was developed using TypeScript for rapid iteration.
  • Ephemeral Message Limitation: Video blocks cannot be included in ephemeral messages, a behavior that is not documented in Slack's official Block Kit reference.
  • Data Storage: To minimize server-side data retention, the system uses a slug-based system to pass necessary cryptographic data to the client-side iframe.
  • Node.js Integration: The project utilizes native .env file support provided by modern Node.js versions for environment configuration.

Project Availability and Compliance

The source code for this implementation is available at github.com/v1ctorio/e2ee-slack. The author notes that this approach is a "hack" because it does not strictly comply with Slack's design constraints for video blocks. It serves as a proof-of-concept demonstrating the need for more flexible, fully-featured app integrations similar to Discord's "Activities" or Telegram's "Mini Apps".

Sources