GoogleChrome / GoogleChrome/lighthouse
People detect Lighthouse to cheat its performance score
- Dominant language
- JavaScript
- Stars
- 30.8k
- Forks
- 9.8k
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 19
Description
**Summary**
Hey! I work as a performance technical architect at Shopify. Lighthouse (PSI) has always been one of the go-to tools for our merchants when it comes to checking the performance of their stores. Unfortunately this ended up as an opportunity for some bad 3rd party actors to offer "speed optimisation services" that heavily strip down the page content when the Lighthouse test is detected. This generates a false image of the actual experience real users are getting, preventing store owners from even learning it's worth to improve.
**Most popular techniques**
Here are the most popular techniques that I found during the investigation:
1. Checking for the `Lighthouse` string in the user agent.
2. Checking for the `Linux x86_64` value of `navigator.platform`.
3. Checking for the `moto g power` string in the user agent.
After Lighthouse is detected, there are usually scripts in place that do a mix of the following:
- Append an LCP hack.
- Prevent all/3rd party JavaScript from loading.
- Prevent all/lazyloaded images from loading.
- Prevent all/lazyloaded iframes from loading.
- Stop parsing of the HTML using `document.close()`.
**Proposed solution**
While we're working internally to address this issue, we probably won't be able to find and fix all of the affected pages. The malicious JavaScript is usually heavily obfuscated so it's not always as simple as looking for one of the strings mentioned above. That's why I thought it would be good to fix the problem at its root instead.
When it comes to the UA, I can see it was already removed by @paulirish in this [PR](https://github.com/GoogleChrome/lighthouse/pull/14384). That said, it seems like PSI still appends the `Chrome-Lighthouse` string. The information still leaks through the `Sec-Ch-Ua` header as well through: https://github.com/GoogleChrome/lighthouse/blob/d2517556d5e4ebf371179705a5a1a0b3644d0c2c/core/lib/emulation.js#L32
My first proposal would be to remain consistent and remove those completely.
I think that the `navigator.platform` issue can be addressed by adding the following logic somewhere inside the emulate function:
```javascript
await session.sendCommand('Page.addScriptToEvaluateOnNewDocument', {
source: `Object.defineProperty(
navigator,
'platform',
{ value: '${formFactor === 'mobile' ? 'Android' : 'MacIntel'}' }
);`,
});
```
This should keep its value consistent with the rest of the user agent.
For the `moto g power` I don't think there are any elegant ways to address it. If someone wants to risk breaking the page for the actual users of this device then so be it.
Let me know what you think. I'm happy to prepare a PR with the changes mentioned above so we can make sure it's not so easy to cheat people with those shady practices in the future.
Contributor guide
Assessment
This issue has not been assessed yet.