Jump to content

Recommended Posts

Posted

On my website, IPB community is on subdomain, and I'm using it's session system to display info about notifications, avatar, username (and to get user id).

I've recently noticed, that when user would visit forum before logging in, on login, they're redirected to:

FORUM.DOMAIN.COM?app=core&module=system&controller=serviceworker&v=[a-z0-9]+&type=front&loggedIn=false

After 5 hours of debugging (as I recently didn't known what service worker is...) I've found cause.

My login form is on DOMAIN.COM, while forum is on FORUM.DOMAIN.COM. On logging in, a "fetch" evenlistener starts to work and since it's "loggedIn" value is "false", it checks for CSRF key:

self.addEventListener("fetch", (e) => {
	const { request } = e;

	// ... some other code here

	let matches = e.currentTarget.location.href.match(/loggedIn=(true|false)/);
	const loggedIn = matches[1];

	// If we're logged in, we need none of this
	if (loggedIn == 'true') {
		log("Logged in, nothing to do...");
		return;
	}

	e.respondWith(
		new Promise((resolve, reject) => {
			log(`On navigation, logged_in is ${loggedIn}`);

			// Situation 2: POST requests when we're a guest
			if (loggedIn == 'false' && request.method === "POST") {
			
				// >>> HERE MY ISSUE STARTS <<<

However, because of "Referrer-Policy: strict-origin-when-cross-origin", HTTP_REFERER is changed from "DOMAIN.COM" to serviceworker url "FORUM.DOMAIN.COM?app=core&module=system&controller=serviceworker&v=XXXXXXXXXX+&type=front&loggedIn=false" and that's what IPB sees from now.

Then in login page "applications/core/modules/front/system/login.php:78" we have this line:

$_ref = \IPS\Http\Url::createFromString( $_SERVER['HTTP_REFERER'] );

and as you probably guess, that causes to redirect user into SERVICEWORKER page after logging in...

My dirty hack (don't do that on live site) solution is to add in constants.php:

$reg = '/(app=core&module=system&controller=serviceworker&v=[a-z0-9]+&type=front&loggedIn=false)/';
if (preg_match($reg, $_SERVER['HTTP_REFERER'])) {
    $_SERVER['HTTP_REFERER'] = preg_replace($reg, '', $_SERVER['HTTP_REFERER']);
}

However, a proper solution should look like this:
in forum/system/Output/Output.php:1152 a new code should be added:

if ($url instanceof \IPS\Http\Url\Internal)
{
	if (isset($url->queryString['controller']) and $url->queryString['controller'] == 'serviceworker')
	{
		$url = \IPS\Http\Url::internal('');
	}
}

I would love to see this fix/addon in next release of IPB, is it possible?

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...