Skip to content

Feature/log chat gpt queries#57

Open
Agrejus wants to merge 3 commits intopalantir:mainfrom
Agrejus:feature/log-chat-gpt-queries
Open

Feature/log chat gpt queries#57
Agrejus wants to merge 3 commits intopalantir:mainfrom
Agrejus:feature/log-chat-gpt-queries

Conversation

@Agrejus
Copy link
Copy Markdown

@Agrejus Agrejus commented Dec 12, 2025

Added functionality to capture ChatGPT API requests and user inputs. To capture what users send to ChatGPT, we needed to intercept network requests and read their bodies. This is challenging in Chrome extensions due to security restrictions. The chrome.webRequest.onBeforeRequest API can intercept requests but doesn't expose request bodies, so we can't read POST payloads. Given this, I came up with two alternative approaches:

  1. UI event capture: Listen for Enter or send button clicks in the content script, extract the input, and correlate it with the next conversation request by timestamp. This is unreliable due to timing and race conditions.
  2. Monkey patching fetch/XHR: Intercept window.fetch and XMLHttpRequest at the page level to access the actual Request objects and read their bodies.

I ended up choosing monkey patching. Monkey patched fetch and XHR in the MAIN world content script using the @rxliuli/vista library. This allows intercepting requests before they're sent, cloning requests to read their bodies, filtering for ChatGPT conversation endpoints, extracting user inputs from the request payload, and sending the data to the background service worker via window.postMessage (since MAIN world scripts don't have direct access to chrome.runtime APIs). The content script (interceptor) runs in "world": "MAIN" to access the page's JavaScript context, otherwise monkey patching will not work. We use a discriminated union type system for type-safe message passing. Requests are filtered by URL pattern (chatgpt.com + /conversation endpoint). We parse ChatGPT's request format to extract user message inputs. This approach requires careful implementation to comply with Chrome Web Store policies, I would have to double check and see if monkey patching fetch and XHR would be an issue. The extension only intercepts requests to specific endpoints and processes data locally before sending alerts to the server.

Once the intercepted data is processed in the background service worker, alerts are sent to the server via POST requests to the /alert endpoint (e.g., http://localhost:8000/alert). The alert payload uses a discriminated union type system with two main alert types: CredentialAlert (for password reuse, DOM hash, user reports, etc.) and ConversationAlert (for ChatGPT conversation intercepts). The server validates the pre-shared key (PSK) and processes each alert type accordingly. Failed alerts are stored locally and retried automatically, with old alerts being filtered out during cleanup. The server endpoint is configured via the extension's config and can be set to any server URL.

@palantirtech
Copy link
Copy Markdown
Member

Thanks for your interest in palantir/phishcatch, @Agrejus! Before we can accept your pull request, you need to sign our contributor license agreement - just visit https://cla.palantir.com/ and follow the instructions. Once you sign, I'll automatically update this pull request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants