Playwright Integration - SAP/project-foxhound GitHub Wiki

This page contains instructions for building and using the Foxhound browser with browser automation support from Playwright. Playwright is a browser automation framework from Microsoft.

Follow the build instructions in Building Foxhound (with playwright integration).

Generally, running bash build.sh -p in the Foxhound root directory should suffice.

Note: The current version of Foxhound sometimes fails with an error about gkrust. This is caused by out-of-memory and can usually be solved by running the build again. If you use the build.sh script, this is done by passing the (-s) flag to avoid starting anew.

For more help debugging Foxhound builds, see the Firefox documentation.

Once the build is complete, the build script prints the location of a zip file containing the Foxhound binary with the Playwright configuration added on top.

Running

This zip file can be unpacked and used as a path for playwright options. For example, create a simple node project with the following package.json:

{
    "name": "playwright-foxhound",
    "version": "1.0.0",
    "description": "Testing playwright with foxhound",
    "main": "index.js",
    "scripts": {
	"go": "node index.js"
    },
    "author": "",
    "license": "ISC",    
    "dependencies": {
	"playwright": "1.46.0"
    }
}

The version of Playwright matching the current Foxhound version can be found under .PLAYWRIGHT_VERSION or in the release description.

And the following index.js:

const { firefox } = require('playwright');

(async () => {
    options = {
        // Path to unzipped files
        executablePath: "firefox/firefox",
    };

    console.log("Starting browser");
    const browser = await firefox.launch(options);
    console.log("Browser Version:", browser.version(), "connected:", browser.isConnected());
    const context = await browser.newContext();

    // Add hooks to extract taint information
    context.addInitScript(
        { content: "window.addEventListener('__taintreport', (r) => { __playwright_taint_report(r.detail, r.detail.str.taint); });"}
    );
    context.exposeBinding("__playwright_taint_report", async function (source, value, taint) {
        console.log(value);
        console.log(JSON.stringify(taint, null, 2));
    });


    console.log("Loading new page");
    const page = await context.newPage();

    console.log("Navigating");
    await page.goto("https://domgo.at/cxss/example/1?payload=abcd&sp=x#12345");

    await browser.close();
})();

You can setup and run using:

npm install
npm run go

Which should produce the following output:

Starting browser
Browser Version: 98.0.2 connected: true
Loading new page
Navigating
{
  subframe: false,
  loc: 'https://domgo.at/cxss/example/1?payload=abcd&sp=x#12345',
  parentloc: 'https://domgo.at/cxss/example/1?payload=abcd&sp=x#12345',
  referrer: '',
  str: 'Welcome <b>12345</b>!!',
  sink: 'innerHTML',
  stack: {}
}

Followed by the lengthy taint flow formatted as JSON.

Debugging

Playwright has a load of undocumented debug options. To use them, run:

DEBUG="pw:browser,pw:api,pw:proxy,pw:protocol,pw:error" npm run go

or for everything:

DEBUG="pw:*" npm run go
⚠️ **GitHub.com Fallback** ⚠️