Is Sider: Chat with all AI: GPT-5, Claude, DeepSeek, Gemini, Grok safe?

Medium risk

Sider is medium risk. Code analysis shows Sider extracts the page's text, title, description and URL for summarize/chat-with-page, then sends it to Sider API endpoints. Dynamic analysis didn't capture the request body: the side panel required sign-in first.…

ChatGPT Sidebar v5.32.6Chrome Web Store
45Risk

AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.

Publishers can request a review.

Findings

SeverityHIGH
ClassUNWANTED
TypeUnexpected
CWECWE-200
SourceAI SANDBOX

Sider forwards page text for AI summarization

Code analysis shows Sider extracts the page's text, title, description and URL for summarize/chat-with-page, then sends it to Sider API endpoints.

Dynamic analysis didn't capture the request body: the side panel required sign-in first.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You use Sider to summarize or chat with the current page.

The workflow requires sign-in and an explicit summarize action in the side panel.

The extension did this

The extension prepares readable page text, page metadata, and API requests for Sider processing.

02EvidenceFIELD TABLE
Fields prepared for the summarize workflow
FieldValueWhy it matters
Readable page text
Example article heading and paragraph text selected from the pageThis can include the main article, issue, discussion, or document text from the page you asked Sider to process.
Page URL
https://en.wikipedia.org/wiki/Rubber_duck_debuggingThis identifies the exact page connected to the text being summarized.
Page title
Rubber duck debugging - WikipediaThis gives the service additional context about the page you selected.
Page description
Software engineering debugging methodThis can add a short page summary from the site metadata.
03EvidenceNETWORK CAPTURE
Captured request
POSThttps://sider.ai/api/v1/completion/summarize_all
No request body was captured because the feature stopped at Sider sign-in during dynamic analysis.
04EvidenceCODE COMPARE
The code that does this

Extraction, packaging, and summarization sinks in the shipped extension

What it actually does
DOM text extraction helperscontent-all.js
function P6e(e){if(!e)return"";let t=e.cloneNode(!0),r=t.querySelectorAll("script, style");for(let o of r)o.remove();let n=new Uz({linkReferenceStyle:"shortcut",linkStyle:"referenced",codeBlockStyle:"fenced"});return n.addRule("removeHiddenElements",{filter:o=>o instanceof HTMLElement&&o.style.display==="none",replacement:()=>""}),n.turndown(t)}c();function Vrn(){let e="",t=document.getElementById("centerCol"),r=document.getElementById("detailBullets_feature_div"),n=document.getElementById("productDescription"),o=document.getElementById("customerReviews");return t&&(e+=P6e(t)),n&&(e+=`

`+P6e(n)),r&&(e+=`

`+P6e(r)),o&&(e+=`

`+P6e(o)),e.trim()}
Webpage text packaged as a File with URL metadatacontent-all.js
async function Bue(e){let t=null,r,n,o;if(e.type==="webpage"&&e.text){let i=new Blob([e.text],{type:"text/plain"});t=new File([i],Jgt(e.title)+".txt",{type:i.type}),n="webpage",r=e.url,o=e.description}else if(e.type==="video"&&e.subTitle)t=jie(e),n="video",r=e.url;else if(e.type==="pdf"&&e.pdfUrl)t=e.file||await ZQe(e.pdfUrl),n="pdf";else if(e.type==="file"&&e.objectUrl){let i=await fetch(e.objectUrl).then(a=>a.blob());t=new File([i],Jgt(e.title),{type:i.type}),n=h5(i.type)}if(!t)throw new Error("File not found");return{file:t,title:e.title,url:r,type:n,desc:o,fileFor:n==="video"?"subtitle":""}}
Summarization API calls carrying page contentcontent-all.js
async summaryVideo(e){function t(f){if(f?.total)if(e.vip){let h={"gpt-3.5":{total:f.total,remain:f.remain,extraTotal:f.extra_total,extraRemain:f.extra_quota,period:f.remain_period}};Kie(h)}else{let h={summary:{remain:f.remain}};Kie(h)}}let r=Ki(t,1e3,{leading:!0}),n={app_name:Vo,app_version:xi,tz_name:sa,content:e.text,title:e.title,language:e.lang,source:e.source,source_type:e.sourceType,request_id:cn(),cid:""},o=[];e.getAbortMethod(()=>{for(let f of o)f()});let{content:i,cid:a,...s}=n,l=null;try{l=await Eo("/v1/completion/summarize_init",s,{getAbortMethod(f){o.push(f)}})}catch{}l&&(n.cid=l.cid||"");let u=Eo("/v1/completion/summarize_all",n,{onStreamData({data:f,done:h}){!h&&f&&r(f),e.onStreamData({text:f?.text||"",done:h})},getAbortMethod(f){o.push(f)}}),d=Eo("/v1/completion/summarize",n,{getAbortMethod(f){o.push(f)}}),[p,m]=await Promise.all([u,d]);return t(m),{text:m.text,subtitle:m.subtitle}},
05EvidenceTHIRD PARTY LIST
External hosts and endpoints named by the code and evidence
  • sider.ai

    Receives summarization requests such as /api/v1/completion/summarize_all for Sider AI processing.

  • sider.ai

    Receives uploaded webpage text files through upload endpoints when the file-based path is used.

SeverityMEDIUM
ClassUNWANTED
TypeUnexpected
CWECWE-200
SourceAI SANDBOX

Netflix JSON.parse Patched to Intercept All Page Data

The extension injects a script into every Netflix page replacing global JSON.parse with a wrapper.

Every JSON object Netflix's page parses, player state, subtitles, API responses, is broadcast as a sider-onParseJSON event.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You open any netflix.com page while Sider is installed.

The extension did this

The extension replaces the global JSON.parse function on the Netflix page with a wrapper that broadcasts every parsed JSON object as a custom event.

This gives the extension access to all JSON data that Netflix's page code processes, including player state, account information, and subtitle data, without the extension needing to make its own network requests.

02EvidenceCODE COMPARE
The code that does this

The full Netflix JSON.parse injection script source as shipped:

What it actually does
"use strict";

// Save the original JSON.parse
const originalParse = JSON.parse;

// Replace it with a wrapper that intercepts every parse call on the page
JSON.parse = function(text, ...reviver) {
  try {
    // Call the original parser
    const result = originalParse.bind(JSON)(text, ...reviver);

    // Broadcast every parsed object — not just subtitle-related ones
    if (typeof result === 'object' && result !== null) {
      const event = new CustomEvent('sider-onParseJSON', {
        detail: { data: result }
      });
      window.dispatchEvent(event);
    }

    // Return normally so Netflix code is unaffected
    return result;
  } catch (err) {
    throw err;  // re-throw parse errors unchanged
  }
};
03EvidencePLAIN NOTE
Why intercepting JSON.parse is broader than intercepting network requests

A content script that monitors fetch() or XMLHttpRequest would only see outbound requests the extension itself initiates, or could only intercept at the network level. By patching JSON.parse in the MAIN world — the same JavaScript context Netflix's own code runs in — the extension sees the fully parsed result of every JSON response Netflix receives, including data from requests the extension has no other way to observe. The interception is not scoped to subtitle-related data; it covers all parsed JSON objects on the page for the lifetime of the page load.

04EvidenceARTIFACT
Check if you're affected

Run this in the DevTools console on any Netflix page with Sider installed. It checks whether JSON.parse has been replaced and, if so, logs a sample of the next intercepted data object to confirm what the extension can see.

RequiresChrome DevToolsSider extension installednetflix.com open
sider-netflix-json-intercept-check.js · js
// sider-netflix-json-intercept-check.js
// Detects whether Sider has patched JSON.parse on this Netflix page.
// Run in Chrome DevTools console on netflix.com.

(function() {
  const isPatched = JSON.parse.toString().includes('sider') ||
                    JSON.parse.toString().includes('CustomEvent') ||
                    JSON.parse.toString() !== 'function parse() { [native code] }';

  if (isPatched) {
    console.warn('[SIDER CHECK] JSON.parse has been replaced — not the native implementation.');
    console.info('[SIDER CHECK] Listening for the next sider-onParseJSON event...');

    window.addEventListener('sider-onParseJSON', function handler(e) {
      console.log('[SIDER CHECK] Intercepted JSON object:', e.detail.data);
      window.removeEventListener('sider-onParseJSON', handler);
    }, { once: true });
  } else {
    console.log('[SIDER CHECK] JSON.parse appears to be the native implementation.');
  }

  console.log('[SIDER CHECK] JSON.parse source:', JSON.parse.toString().slice(0, 200));
})();
How to run it
  1. 1
    Install Sider and go to netflix.com.
  2. 2
    Open DevTools (F12), Console tab.
  3. 3
    Paste and run this script.
  4. 4
    A warning appears if JSON.parse was replaced, then the first intercepted JSON object.
SeverityMEDIUM
ClassUNWANTED
TypeUnexpected
CWECWE-200
SourceAI SANDBOX

YouTube XHR Patched to Capture Subtitle Request URLs

The extension injects a script into every YouTube page replacing XMLHttpRequest before page code runs, intercepting every open() call.

Matches to the timedtext endpoint dispatch as a custom event, powering subtitle extraction.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You open any YouTube page while Sider is installed.

The extension did this

Before any YouTube code runs, the extension replaces window.XMLHttpRequest with a custom subclass that monitors every network request made by the page.

When the YouTube player fetches subtitle data, the interception captures the full URL and broadcasts it as a custom event so Sider's sidebar can retrieve and translate the captions.

02EvidenceCODE COMPARE
The code that does this

The full injected XHR script source as shipped:

What it actually does
"use strict";

// Save the original XMLHttpRequest before anything else runs
const OriginalXHR = window.XMLHttpRequest;

// Queue holds subtitle URL events until the sidebar is ready to receive them
window.__SIDER_YOUTUBE_SUBTITLE_URL_EVENT_QUEUE__ = [];

// Flush queued events once the Sider sidebar element is mounted and ready
function flushQueue() {
  const queue = window.__SIDER_YOUTUBE_SUBTITLE_URL_EVENT_QUEUE__;
  if (!queue?.length) return;

  const sidebar = document.querySelector('chatgpt-sidebar');
  if (sidebar &&
      sidebar.dataset.rendered === 'true' &&
      sidebar.dataset.ytSubtitleListenerReady === 'true') {
    window.__SIDER_YOUTUBE_SUBTITLE_URL_EVENT_QUEUE__ = [];
    for (const event of queue) window.dispatchEvent(event);
  }
}

// Called on every XHR open() — checks if this is a subtitle request
function interceptUrl({ url }) {
  flushQueue();
  const urlStr = url.toString();

  if (urlStr.startsWith('https://www.youtube.com/api/timedtext')) {
    const parsed = new URL(urlStr);

    // Only capture if the URL has all three expected subtitle parameters
    if (parsed.searchParams.has('v') &&
        parsed.searchParams.has('lang') &&
        parsed.searchParams.has('potc')) {

      const videoId      = parsed.searchParams.get('v') || '';
      const pageVideoId  = new URLSearchParams(window.location.search).get('v') || '';

      if (!videoId || !pageVideoId) return;

      // Broadcast the full subtitle URL as a custom event
      const event = new CustomEvent('sider-onGetYtSubtitleUrl', {
        detail: { url: urlStr }
      });
      window.__SIDER_YOUTUBE_SUBTITLE_URL_EVENT_QUEUE__?.push(event);
      flushQueue();
    }
  }
}

// Replace window.XMLHttpRequest with a subclass that intercepts open()
class InterceptedXHR extends OriginalXHR {
  constructor(...args) { super(...args); }

  open(method, url, ...rest) {
    try { interceptUrl({ url }); } catch {}
    super.open(method, url, ...rest);
  }
}

window.XMLHttpRequest = InterceptedXHR;
03EvidenceFIELD TABLE
Information available to the extension from each intercepted subtitle URL:
FieldValueWhy it matters
Video ID
dQw4w9WgXcQThe YouTube video you are watching. Included in the timedtext URL as the 'v' parameter.
Subtitle language
enThe language code of the captions being loaded by the YouTube player.
Full timedtext URL
https://www.youtube.com/api/timedtext?v=dQw4w9WgXcQ&lang=en&potc=1&expire=1745001600The complete URL including all query parameters, used by the extension to fetch the subtitle file.
Updated 17 September 2026difoiogjjojoaoomphldepapgpbgkhkb