playwright icon indicating copy to clipboard operation
playwright copied to clipboard

[BUG] Interception of a network request for the top document/HTML, renders insecure context in the browser

Open eni987 opened this issue 2 years ago • 1 comments

System info

  • Playwright Version: [v1.34.0]
  • Operating System: [Windows 11, Windows 10, macOS 13.4]
  • Browser: [Chromium, Firefox]
  • IDE: VSCode

Issue description

When navigating to a website with the https protocol and using any of the two APIs Playwright provides (BrowserContext.route or Page.route) to intercept network requests/responses on the main document/HTML, the connection to the site renders insecure.

As shown in the image below - image

This issue could potentially affect the behavior of a website; for example, I got the following errors on one website I tested - image

As you'll see in the snippet below, I literally, didn't do anything with the request/response, other than to fetch and fulfill it, though my requirement is to actually modify the response.

So what I am asking is -

  1. Is this the expected behavior ?
  2. How can I actually modify a response for the main document/HTML and still keep the website in a secure context ?
  3. If you'd suggest to use a proxy server, I would have to ask, is it possible to use it just to intercept the response I need ? rather than having all the network traffic pass through it (for that browser's context that is).

Please note that I did pass the ignoreHTTPSErrors argument to the newly created context.

Source code

snippet.ts

import * as Playwright from "playwright";

const launchOptions = {
	headless: false,
	args: ["--start-maximized", "--disable-dev-shm-usage", "--no-sandbox", "--no-zygote", "--disable-setuid-sandbox"],
};

// check if the resource type is the main document
function isMainDocument(resourceType: string, request: Playwright.Request) {
	const hasNoParentFrame = !request.frame().parentFrame();
	const isDocument = resourceType === "document";

	return hasNoParentFrame && isDocument;
}

async function requestsHandler(route: Playwright.Route, request: Playwright.Request) {
	const resourceType = request.resourceType(); // document, stylesheet, image, media, font, script, texttrack, xhr, fetch, eventsource, websocket, manifest, other.

	if (isMainDocument(resourceType, request)) {
		// perform fetch to get the response
		const response = await route.fetch();

		// do nothing with it, simply fulfill it (though my requirement is to actually manipulate it)
		await route.fulfill({ response });
	} else {
		// if not the main document, simply continue
		route.continue();
	}
}

async function launch() {
	const { chromium } = Playwright;
	const browser = await chromium.launch(launchOptions);

	const context = await browser.newContext({
		ignoreHTTPSErrors: true,
		serviceWorkers: "block",
	});

	const page = await context.newPage();

	await page.route("**/*", requestsHandler);
	page.goto("https://my-website.com");  // replace the address with any website with https protocol
}

launch();

Steps

  • Run this snippet, no other files/dependencies required.
  • Check the "View site information" button, left to the address bar in Chromium

Expected To have the website run in a secure context

Actual Chromium/Firefox warns about an insecure context

Thanks in advance for any advice or possible solution.

eni987 avatar May 22 '23 00:05 eni987

@eni987 Well, you did fulfill request with an arbitrary content, so context is not secure indeed. Technically, no certificate was provided to the browser, just document content.

Are there any behavior issues that you observe because of that, except for the badge in the UI? If so, please share a repro, and we'll happily take a look.

dgozman avatar May 23 '23 23:05 dgozman

Closing as part of the triage process since it seemed stale. Please create a new issue with a detailed reproducible or feature request if you still face issues.

mxschmitt avatar Jun 02 '23 19:06 mxschmitt