Skip to content

pwn-all/smp-plugin

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SMP Logo

SMP - Secure Messages Plugin

Automatically replaces raw secrets in chats with encrypted SecNote links.

Version Manifest V3 Chrome 137+ E2E Encrypted

A Chrome extension (Manifest V3) that detects passwords, API keys, tokens, and other secrets in web-based messaging apps and replaces the original plaintext with encrypted SecNote links before sending.

Generated SecNote URLs are bearer secrets until first successful view or expiry. When a URL is posted into a chat, the chat platform can store and read that URL, including the fragment key. SMP prevents the original raw secret string from being posted, but it does not hide the generated SecNote link from the messaging platform. With the original unmodified SecNote server software, a viewed note is deleted; forwarding the same URL after that point should not reveal the note again.


Features

39 detection patterns API keys (OpenAI, Anthropic, AWS, GitHub, Stripe, GCP, Azure, and more), JWTs, bearer tokens, private keys, TOTP URIs, connection strings, and high-entropy generic tokens
Shannon entropy analysis Optional statistical detection for secrets that don't match a named pattern; configurable sensitivity
Confirmation modal Intercepts the send action and shows a Shadow DOM dialog listing every detected secret before the original plaintext is transmitted
AES-256-GCM encryption The key lives in the recipient URL fragment — never sent to the SecNote server during note retrieval
One-time view The original unmodified SecNote server software deletes the note on first successful retrieval; configurable TTL (12 h or 24 h)
Ed25519 response verification Signed server responses with TOFU trust model; optional pubkey pinning in every link
Proof-of-Work Client-side PoW (up to 28 bits) required before note creation — mitigates server abuse
Custom sites Extend coverage to any HTTPS site or localhost with a URL pattern and editor selector
Auto-replace mode Skip the confirmation dialog and replace silently on every send

Supported Platforms

Platform URL
Slack https://app.slack.com/*
Discord https://discord.com/*
Telegram Web https://web.telegram.org/*
Microsoft Teams (web) https://teams.live.com/*
WhatsApp Web https://web.whatsapp.com/*
Outlook Web App https://*/*/owa/*
Custom sites Configurable in Settings

How It Works

Send flow

User types secret → presses Enter / clicks Send
        │
        ▼
interceptor.js  (MAIN world)
  detects secrets in editor
  blocks the send event
  fires secnote-guard-send-blocked
        │
        ▼
bridge.js  (isolated world)
  shows confirmation modal
  user clicks "Secure & Send"
        │
        ▼  chrome.runtime.sendMessage
background.js  (service worker)
  encrypts text with AES-256-GCM
  solves Proof-of-Work challenge
  POST /api/v1/notes  →  receives note ID
        │
        ▼
bridge.js
  replaces secrets with {SC:0001}, {SC:0002}, …
  appends SecNote URL to message
  posts pending replacements to interceptor.js
        │
        ▼
interceptor.js
  intercepts the real fetch / XHR / WebSocket send
  patches request body: plaintext → {SC:…} placeholder
        │
        ▼
App's servers receive no original plaintext secret strings
but they do receive the SecNote bearer URL until it is viewed or expires

Architecture

┌─────────────────────────────────────────────┐
│  background.js  (service worker)            │
│  ─ AES-256-GCM encryption                  │
│  ─ Ed25519 response verification            │
│  ─ PoW solver                               │
│  ─ chrome.storage.sync                      │
└──────────────────────┬──────────────────────┘
                       │ chrome.runtime.sendMessage
          ┌────────────┴───────────────┐
          │                            │
┌─────────┴─────────────┐   ┌──────────┴────────────┐
│  bridge.js            │   │  popup.js             │
│  (isolated world)     │   │  options.js           │
│  ─ secret detection   │   │  ─ status display     │
│  ─ Shadow DOM modal   │   │  ─ settings form      │
│  ─ editor patching    │   │  ─ trust management   │
│  ─ cross-frame comms  │   └───────────────────────┘
└─────────┬─────────────┘
          │ window.postMessage
┌─────────┴─────────────────────────┐
│  interceptor.js  (MAIN world)     │
│  ─ fetch / XHR / WS / sendBeacon  │
│  ─ request-body secret patching   │
│  ─ WhatsApp Lexical editor API    │
└───────────────────────────────────┘

Component summary

File World Role
background.js Service worker Crypto, API client, settings, trust store
bridge.js Isolated (content script) UI modal, editor detection, send interception, cross-frame coordination
interceptor.js MAIN (page context) Network interception, request-body patching, Lexical editor integration
dist/secretDetector.js Both Compiled secret-detection engine (39 patterns + entropy)
popup.html/js Extension popup Status display, quick-open settings, manual scan
options.html/js Extension options page Full settings, custom rules, trust management

Installation

From source

# 1. Clone the repository
git clone https://github.com/pwn-all/smp-plugin.git

# 2. Open Chrome and navigate to
chrome://extensions

# 3. Enable Developer mode (toggle, top-right)
# 4. Click "Load unpacked" and select the source/ directory

The SMP icon will appear in the toolbar.

Configuration

  1. Click the SMP icon → Settings
  2. Enter your SecNote API endpoint and click Test connection
  3. Accept the server public key fingerprint (TOFU)
  4. Choose TTL, enable/disable detection patterns, and optionally add custom sites

Permissions

Permission Why
storage Persist settings across sessions via chrome.storage.sync
scripting Dynamically inject content scripts into custom user-defined sites
https://*/* (optional) Required only when a custom site is added
http://localhost/* (optional) Testing against a local SecNote server
http://127.0.0.1/* (optional) Testing against a local SecNote server

The extension never reads cookies, browsing history, or any content beyond the text fields it protects.


Detection Patterns

Show all 39 built-in patterns
Category Patterns
AI / ML OpenAI API key, Anthropic API key
Cloud — AWS Access key ID, secret access key, session token
Cloud — Azure Connection string, SAS token
Cloud — GCP Service account JSON
Version control GitHub token, GitLab token, npm token
Payments Stripe secret key, Stripe webhook secret
Communication Slack API token, Slack webhook, Mailchimp API key, Docker Hub token
Auth JWT, Bearer token, TOTP URI (otpauth://), magic link
Credentials Inline SSH key, Git clone with credentials, CLI password flag, connection string
Cryptography PEM private key
Generic High-entropy token, password field, license key

Settings Reference

Setting Default Description
API Endpoint SecNote server base URL
TTL 24 h Maximum note lifetime before server auto-deletes; first successful view deletes earlier
Pin pubkey on Embed server public key in every generated link so recipients can verify
Auto-replace off Skip the confirmation dialog
Statistical detection on Entropy-based detection for secrets without a named pattern
Sensitivity medium Entropy threshold — low: 4.0 bit, medium: 3.5 bit, high: 3.0 bit
Enabled patterns all Toggle individual detection rules
Custom sites none URL glob + CSS selector for additional sites

Browser Support

Chrome 137+ (Manifest V3 with service worker and WebCrypto Ed25519). Not tested on other Chromium-based browsers.


License

GPL-3.0-only. See LICENSE.


Built with ❤️ for people who accidentally paste secrets into Slack.

About

Detects passwords, tokens and secrets in messaging apps and secures them with end-to-end encrypted SecNote links.

Topics

Resources

License

Security policy

Stars

Watchers

Forks

Contributors