Is StylerGPT for ChatGPT safe?

Medium risk

StylerGPT for ChatGPT sends a keyed hash of the user's ChatGPT email to api.stylergpt.com for trial checks.

When ChatGPT pages load, the extension reads the signed-in account email from the page bootstrap data and derives a stable HMAC-SHA256 hash with a bundled key. It stores that hash locally and sends it with the extension instance name to StylerGPT's trial API for new or free users.

stylergpt.comv2026.9.10Chrome Web Store
45Risk
Who publishes it

stylergpt.com - 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
stylergpt.com
Registered address
Via Matte Trucco 65, Roma, RM 00132, IT
Registered contact
Fabio Viola

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

Publishers can request a review.

Findings

StylerGPT ships a hardcoded API bearer token accepted by its production backend

StylerGPT's extension ships a hardcoded API bearer token and HMAC signing key in its code.

We replayed the extension's own license-check request with that embedded token and the vendor's backend accepted it, granting premium access.

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

You sign into ChatGPT and open chatgpt.com in your browser.

No StylerGPT-specific action is needed; visiting the page is enough.

The extension did this

The extension automatically calls StylerGPT's licensing API using a bearer token that is hardcoded in the extension's own code, not tied to your account.

The same token and HMAC signing key ship inside every copy of the extension.

The code that does this

The hardcoded token and HMAC signing key in app.js, and how they reach the Authorization header

Readable version

Constant declarations, renamed

let bearerToken = "wGEgV0p3Sf3Xm2Ud58gMQwFaz5lSAvCl";let apiBase = "https://api.stylergpt.com/v7/";let anonymousEmail = "anonymous@stylergpt.com";let hmacSecret = "StylerGPT-Secret-Key";let cachedHmac = null;

Authorization header assembly, renamed

function callStylerGptApi(path, method, payload) {  const headers = {    Accept: "application/vnd.api+json",    "Content-Type": "application/vnd.api+json",    Authorization: "Bearer " + bearerToken   // same hardcoded token, every install  };  return fetch(apiBase + path, { method, headers, body: JSON.stringify(payload) });}
Captured request
POSThttps://api.stylergpt.com/v7/is-trial-available

HTTP 200 with a signed entitlement token granting premium_access: true, from a request built with only the token shipped in app.js.

Headers
Accept
application/vnd.api+json
Content-Type
application/vnd.api+json
Authorization
Bearer wGEgV0p3Sf3Xm2Ud58gMQwFaz5lSAvCl
Body
{  "hashed_email": "<hmac-sha256 hash>",  "instance_name": "<extension instance id>"}
Where the licensing request goes
    • api.stylergpt.com

    StylerGPT's own licensing/entitlement backend. Accepts the bearer token embedded in the extension to grant premium features.

Check if you're affected

Pulls the hardcoded bearer token, API base, and HMAC signing key straight out of a local copy of the extension's app.js, so you can confirm they are static across installs.

Requires
  • Node.js 14+
stylergpt_token_extractor.js · js
// stylergpt_token_extractor.js// Statically pulls StylerGPT's hardcoded API bearer token and HMAC secret// out of the extension's own shipped app.js. Run it against a copy of the// extension you have already installed, then check for yourself that the// same values reappear across separate installs / downloads.const fs = require("fs");function extract(appJsPath) {  const src = fs.readFileSync(appJsPath, "utf8");  // The four constants are declared together in one statement:  //   TOKEN_VAR="<token>",BASE_VAR="https://api.stylergpt.com/vN/",  //   EMAIL_VAR="anonymous@...",SECRET_VAR="<hmac secret>"  const re = /[A-Za-z_$][\w$]*="([^"]{20,64})",[A-Za-z_$][\w$]*="(https:\/\/api\.stylergpt\.com\/v\d+\/)",[A-Za-z_$][\w$]*="([^"]+@[^"]+)",[A-Za-z_$][\w$]*="([^"]+)"/;  const m = src.match(re);  if (!m) {    console.log("Pattern not found. The variable names or shape may have changed.");    return;  }  console.log("Bearer token: " + m[1]);  console.log("API base:     " + m[2]);  console.log("Anon email:   " + m[3]);  console.log("HMAC secret:  " + m[4]);}const path = process.argv[2];if (!path) {  console.log("Usage: node stylergpt_token_extractor.js <path-to-app.js>");  process.exit(1);}extract(path);
How to run it
  1. 1Unpack the StylerGPT .crx you downloaded from the Chrome Web Store.
  2. 2Run: node stylergpt_token_extractor.js /path/to/app.js.
  3. 3Compare the printed token/key against another copy of the extension; they match.

Where it sends data

Destinations our analysis observed StylerGPT 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.stylergpt.com

    StylerGPT sends data to api.stylergpt.com. No other extension we have analysed sends data here.

Updated 30 September 2026hmmijabfpeeiddcjlckllcogkpcaglhg