Is Claude Tuner - Claude·ChatGPT·Gemini Tracker safe?

Medium risk

Claude Tuner sends snapshot submissions to its backend using a shared fallback API key.

Claude Tuner prepares snapshot POST requests to its backend API and includes authentication headers with those submissions. When no per-user bearer token is stored, the extension falls back to a shipped shared API key for requests to the snapshots endpoint.

Chaehyunv1.33.0Chrome Web Store
45Risk
Who publishes it

DataMax - no other listings under this identity

What this publisher told the store about itself, and the other listings that told it the same thing.

Publisher
Chaehyun
Declared legal entity
DataMax
Registered address
테헤란로 108길 42, 5층, 강남구, 서울특별시 06176, KR
Registered contact
askanywhere

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

Publishers can request a review.

Findings

Claude Tuner ships a hardcoded shared API key as its default auth credential

Claude Tuner embeds one API key in every install.

Until an install gets its own personal token, it authenticates heartbeat, preference, and usage-snapshot requests to the vendor's backend with that same hardcoded key instead.

Severity
Medium unwanted
Type
Unexpected
CWE
CWE-522
Source
Dynamic sandbox
What actually happens
You did this

You install Claude Tuner before it has issued your copy a personal login token.

This is the extension's normal state on first run and any time the per-install token is absent.

The extension did this

The extension authenticates its own backend requests with a single API key hardcoded into every copy of the extension.

The same literal value is sent as the X-API-Key header for heartbeat and preference requests, and as the _auth field in the body of snapshot uploads.

The fallback credential, as shipped
  • Fallback API key
    claude-manager-dev-key-2024

    Every install without a personal token authenticates with this exact value, the same one every other affected install also uses.

  • Header name (heartbeat, preferences)
    X-API-Key

    The field the key travels in for two of the three affected backend routes.

  • Body field (snapshot uploads)
    _auth

    Where the same key travels for usage-snapshot submissions, inside the JSON body instead of a header.

The code that does this

Where the fallback key is defined and used

Readable version

bg/constants.js: the hardcoded literal

bg/constants.js
export const DEFAULT_SERVER_URL = 'https://api.claudetuner.com';export const DEFAULT_API_KEY = 'claude-manager-dev-key-2024';

bg/storage.js: getAuthHeaders() falls back to the literal

bg/storage.js
export async function getAuthHeaders(config) {  const extToken = await getExtToken();  if (extToken) {    return { 'Authorization': `Bearer ${extToken}` };  }  return { 'X-API-Key': config.apiKey };}

bg/storage.js: simplePost() falls back to the same literal in the body

bg/storage.js
export async function simplePost(config, url, payload) {  const extToken = await getExtToken();  const response = await fetch(url, {    method: 'POST',    body: JSON.stringify({ ...payload, _auth: extToken || config.apiKey }),  });  return { response, sentToken: extToken || null };}

bg/storage.js: getConfig() seeds apiKey from the same default

bg/storage.js
export async function getConfig() {  return new Promise((resolve) => {    chrome.storage.sync.get(      { serverUrl: DEFAULT_SERVER_URL, apiKey: DEFAULT_API_KEY, intervalMinutes: DEFAULT_INTERVAL_MINUTES, intervalExplicitlySet: false, optimizationMode: 'notify_only', selectedOrgId: null },      resolve    );  });}
Where the shared key authenticates
    • api.claudetuner.com

    The vendor's own backend. Accepts the shared fallback key as valid authentication for heartbeat, preference-sync, and usage-snapshot requests when no personal token is present.

Check if you're affected

Reads an unpacked copy of the extension and reports whether it still ships the hardcoded fallback API key, without sending any network traffic itself.

Requires
  • Node.js 18+
check_shared_key.js · js
// check_shared_key.js// Confirms whether an unpacked copy of Claude Tuner still ships the hardcoded// fallback API key described in this report. Reads local files only; makes// no network requests.//// Usage: node check_shared_key.js /path/to/unpacked-extensionconst fs = require('fs');const path = require('path');const PREVIOUSLY_OBSERVED_KEY = 'claude-manager-dev-key-2024';function readFile(extDir, rel) {  const p = path.join(extDir, rel);  return fs.existsSync(p) ? fs.readFileSync(p, 'utf8') : null;}const extDir = process.argv[2];if (!extDir) {  console.error('Usage: node check_shared_key.js <unpacked-extension-dir>');  process.exit(1);}const constants = readFile(extDir, 'bg/constants.js');if (!constants) {  console.error('bg/constants.js not found under ' + extDir);  process.exit(1);}const match = constants.match(/DEFAULT_API_KEY\s*=\s*'([^']+)'/);if (!match) {  console.log('No DEFAULT_API_KEY literal found. This build may no longer ship a fallback key.');  process.exit(0);}const shippedKey = match[1];console.log('Shipped fallback key:', shippedKey);console.log('Matches the key in this report:', shippedKey === PREVIOUSLY_OBSERVED_KEY);console.log('Any install without a personal token sends this exact value as:');console.log('  - the X-API-Key header on /api/heartbeat and /api/users/preferences');console.log('  - the _auth body field on /api/snapshots');
How to run it
  1. 1Unpack the extension's .crx (chrome://extensions in Developer Mode, or unzip the .crx directly).
  2. 2Run: node check_shared_key.js <unpacked-extension-dir>.
  3. 3Compare the printed key against the one this report cites.

Where it sends data

Destinations our analysis observed Claude Tuner - Claude·ChatGPT·Gemini Tracker contacting. Sending data somewhere is not a finding on its own - an extension that syncs your settings has to talk to its own server - but it is where your data can go, and who else it goes to.

  • api.claudetuner.com

    Claude Tuner - Claude·ChatGPT·Gemini Tracker sends data to api.claudetuner.com. No other extension we have analysed sends data here.

Updated 30 September 2026ajnnckikagphjbgpicpoffockabnhond