Inspect and execute JavaScript in Microsoft Office Copilot WebViews. Attaches to a running Word process via Frida, discovers embedded WebView instances, and provides single-shot JS execution and an interactive REPL with live tab completion.
uv sync# List all WebView instances in Microsoft Word
uv run python3 copilot_js.py list
# Execute JavaScript on the Copilot WebView
uv run python3 copilot_js.py exec --js "document.title"
uv run python3 copilot_js.py exec --js "JSON.stringify({host: Office.context.host})"
# Execute a script file
uv run python3 copilot_js.py exec --file scripts/probe-bridge.js
# Start an interactive REPL with live tab completion
uv run python3 copilot_js.py repl
# Target a specific process
uv run python3 copilot_js.py --pid 12345 list
uv run python3 copilot_js.py --name "Microsoft Word" repl
# Override JS execution timeout (default 5000ms)
uv run python3 copilot_js.py --timeout 10000 exec --js "document.title"| Command | Description |
|---|---|
.help |
Show all commands and tab completion usage |
.quit / .exit / .q |
Exit the REPL |
.url |
Show the current page URL |
.title |
Show the current page title |
.dom [path] |
Save full DOM HTML to file (default: /tmp/copilot-dom.html) |
.file <path.js> |
Execute a JavaScript file |
.import <path.js> |
Alias for .file |
.views |
Re-enumerate all WebViews |
.clear |
Clear the completion cache |
On startup the REPL eagerly loads all enumerable objects from the WebView's global scope (walking the full prototype chain). Every global variable, DOM API, Office JS object, and built-in is immediately completable. The completion popup shows the typeof each name.
doc<TAB>→document(object)document.get<TAB>→getElementById(function),getElementsByClassName(function), ...Off<TAB>→Office(object),OfflineAudioContext(function), ...- After
var myObj = {alpha: 1}, typingmyObj.<TAB>showsalpha(number)
Completions are fetched by evaluating Object.getOwnPropertyNames() in the running process. The cache is invalidated after every user eval so newly created variables are immediately completable. Property access (e.g. document.<TAB>) walks the full prototype chain (HTMLDocument → Document → Node → EventTarget → Object).
copilot_js.py (Python CLI)
│
├── frida.attach(pid / name)
│
└── session.create_script(agent.js)
│
└── agent.js (injected into Word)
│
├── objc_msgSend → NSApp.windows → view hierarchy walk
│ └── Finds WKWebView / AgaveView instances
│
└── evaluateJavaScript:completionHandler:
└── Manual ObjC block construction
└── Results via Frida RPC
The agent uses Frida's NativeFunction API to call objc_msgSend directly — the Copilot WebView (AgaveView, a WKWebView subclass) is discovered by walking the NSApp window hierarchy via ObjC runtime calls. JavaScript is executed via evaluateJavaScript:completionHandler: with a manually constructed ObjC block for the completion handler.
See scripts/README.md for documentation on all available probe scripts, their output, and security implications.
- macOS (arm64 or x86_64) with Frida 17.x
- Python 3.10+
- uv for dependency management
- Microsoft Word running with Copilot panel open
- SIP disabled or appropriate debugging entitlements for process attachment
copilot-js/
├── copilot_js.py # Python CLI (list, exec, repl)
├── agent.js # Frida agent injected into Word
├── pyproject.toml # Python dependencies (frida, prompt-toolkit)
├── uv.lock # Locked dependency versions
├── scripts/ # 17 JavaScript probe scripts
│ ├── README.md # Script documentation with output and implications
│ ├── probe-bridge.js # WebKit message handlers + Office JS API
│ ├── probe-dom.js # DOM element counts
│ ├── probe-office-api.js # Office context properties
│ ├── probe-storage.js # Storage sizes
│ ├── probe-message-handlers.js # Deep handler enumeration
│ ├── enumerate-msal-tokens.js # OAuth token scope enumeration
│ ├── extract-responses.js # data-testid values
│ ├── extract-copilot-response.js # Latest AI response text
│ ├── extract-document-content.js # Full document text via Word JS API
│ ├── capture-injection-results.js # Injection marker detection
│ ├── write-document-test.js # Document write test
│ └── ... # Additional probes
├── test-docs/ # Test Word documents for injection scenarios
├── CLAUDE.md # Development guide
└── SPECIFICATION.md # Formal specification
The test-docs/ directory contains Word documents designed for testing Copilot injection scenarios.