Is picture in picture safe?
Picture in Picture is critical risk. Every time you navigate, the extension sends the URL's origin and path to backend.pictureinpic.com. Capture confirmed five POSTs with the visited URL. The stated purpose, picture-in-picture video, does not require sending every URL visited.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
PiP Extension Reports Every Page You Visit to Its Own Server
Every time you navigate, the extension sends the URL's origin and path to backend.pictureinpic.com.
Capture confirmed five POSTs with the visited URL.
The stated purpose, picture-in-picture video, does not require sending every URL visited.
- Severity
- Critical unwanted
- Type
- Unexpected
- CWE
- CWE-200
- Source
- Dynamic sandbox
You navigate to any page in any tab.
The extension immediately POSTs the page's origin and path to its own backend server.
Fires automatically with no user interaction. Covers every site, not just video pages.
JSON response containing optional cselector/dselector values used to inject content; observed to return empty val object on most navigations.
- Content-Type
- application/json
{ "uri": "https://en.wikipedia.org/wiki/Picture-in-picture"}- Page origin and pathhttps://en.wikipedia.org/wiki/Picture-in-picture
The site and page you are viewing, enough to reconstruct your browsing activity across all sites.
The navigation listener in background.js (lines 55-98):
// Fires every time any tab finishes loading.// For every completed navigation, constructs the page origin + path// and POSTs it as JSON to the extension's backend.chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { if (changeInfo.status !== 'complete') return; const pageUrl = new URL(tab.url); const uri = pageUrl.origin + pageUrl.pathname; // e.g. "https://example.com/path" fetch('https://backend.pictureinpic.com/api/video-selector', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ uri }) }) .then(res => res.json()) .then(g => { // Server may return CSS selectors to inject into the page if (g.val['cselector']) fetchAndInject(g.val['cselector'], tabId); if (g.val['dselector']) fetchUrl(g.val['dselector']); });});- backend.pictureinpic.com
Backend server run by the Picture in Picture developer. Receives the origin+pathname of every page visited and returns CSS selectors for optional content injection.
Intercepts the fetch() call in the extension's service worker and logs every URL reported to backend.pictureinpic.com as you browse.
- Chrome with Developer mode enabled
// pip-navigation-monitor.js// Run this in Chrome DevTools on the service worker for the Picture in Picture extension.// Open chrome://extensions, enable Developer mode, find the extension, click// the 'service worker' link to open its DevTools, then paste this into the console.(function () { const originalFetch = self.fetch.bind(self); self.fetch = function (url, options) { if (typeof url === 'string' && url.includes('backend.pictureinpic.com/api/video-selector')) { let body = '(no body)'; try { body = options && options.body ? options.body : '(no body)'; } catch (e) {} console.log('[PIP_MONITOR] Navigation reported:', url); console.log('[PIP_MONITOR] Request body:', body); } return originalFetch(url, options); }; console.log('[PIP_MONITOR] Installed. Navigate to any page to see reported URLs.');})();- 1Install Picture in Picture.
- 2Open chrome://extensions, enable Developer mode.
- 3Open the service worker DevTools console.
- 4Paste this script, press Enter.
- 5Visit any page; navigation logs the URL sent to backend.pictureinpic.com.