fix(csp): suppress localhost/loopback CSP violations from Smart TV browsers (#2603)

Smart TV browsers (Tizen, webOS) inject scripts that call localhost
services (e.g., localhost:9009/service/tvinfo). CSP correctly blocks
these, but the violation listener was reporting them to Sentry.
Matches any port on localhost and 127.0.0.1 over http/https.
This commit is contained in:
Elie Habib
2026-04-01 23:27:54 +04:00
committed by GitHub
parent b162b3e84e
commit 017d72b191
2 changed files with 16 additions and 0 deletions

View File

@@ -382,6 +382,8 @@ function shouldSuppressCspViolation(
if (blockedURI === 'inline' && directive === 'script-src-elem') return true;
// Null blocked URI from in-app browsers.
if (blockedURI === 'null') return true;
// localhost/loopback — Smart TV browsers (Tizen, webOS) and dev tools inject local service calls.
if (/^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?\//.test(blockedURI)) return true;
return false;
}
// Detect once whether BOTH the meta tag and HTTP header CSP allow https: in connect-src.

View File

@@ -140,6 +140,20 @@ describe('CSP violation filter (shouldSuppressCspViolation)', () => {
});
});
describe('localhost/loopback', () => {
it('suppresses http://localhost:9009 (Smart TV tuner service)', () => {
assert.ok(suppress('enforce', 'connect-src', 'http://localhost:9009/service/tvinfo', '', false));
});
it('suppresses http://127.0.0.1:8080', () => {
assert.ok(suppress('enforce', 'connect-src', 'http://127.0.0.1:8080/api', '', false));
});
it('suppresses https://localhost:3000', () => {
assert.ok(suppress('enforce', 'connect-src', 'https://localhost:3000/dev', '', false));
});
});
describe('real violations pass through', () => {
it('reports third-party script-src violation', () => {
assert.ok(!suppress('enforce', 'script-src', 'https://evil.com/crypto-miner.js', '', true));