Is 帮您淘优惠 safe?

Critical risk

帮您淘优惠 is critical risk. 帮您淘优惠 POSTs to xapi.bntyh.com/fddqa on matching pages. The response can include JS code strings, run in a sandboxed acorn+Babel interpreter. A captured request returned three scripts (7,226/6,209/7,231 chars); a POST confirmed execution.…

xiaochengxu1v3.0.3Chrome Web Store
100Risk

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

Publishers can request a review.

Findings

SeverityCRITICAL
ClassUNWANTED
TypeUnexpected
CWECWE-829
SourceAI SANDBOX

Server Delivers JavaScript Executed on Every Matched Page

帮您淘优惠 POSTs to xapi.bntyh.com/fddqa on matching pages.

The response can include JS code strings, run in a sandboxed acorn+Babel interpreter.

A captured request returned three scripts (7,226/6,209/7,231 chars); a POST confirmed execution.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You visit a page that matches the server's injection scope list.

The extension did this

The extension POSTs to xapi.bntyh.com/fddqa and receives JavaScript code strings, which its sandboxed interpreter executes with access to the page's window object.

Our dynamic analysis confirmed this: the server returned three script payloads totalling over 20,000 characters, and a subsequent beacon to duommai.com confirmed the interpreter ran.

02EvidenceNETWORK CAPTURE
Captured request
POSThttps://xapi.bntyh.com/fddqa
200 OK, 32,697 bytes. Response contained content2.script (7,226 chars), content4.script (6,209 chars), content9.script (7,231 chars), all server-supplied JavaScript. Observed as DA request 1310393.8. Scripts were also cached in chrome.storage.local for reuse on subsequent navigations.
Body
{
  "uuid": "a3f8c921e47b10d2f958c0e3a17b4d89.1744640329122",
  "bid": 8,
  "ver": "3.0.3",
  "eid": "jd_coupon_01",
  "data": {
    "content2": "2026-04-14T14:00:00.000Z"
  }
}
03EvidenceCODE COMPARE
The code that does this

The sandboxed interpreter setup and execution path in the extension source:

What it actually does
Interpreter initialization — creates sandboxed interpreter with window access
// evalCore is loaded from js/umd.js — an acorn+Babel-based JS interpreter
const { evalModule, getEvalInstance } = evalCore;
const Interpreter = evalModule.Interpreter;

// Give the interpreter access to the page's window object
Interpreter.global = window;
new Interpreter(); // bootstrap

// window.evil is now a callable that evaluates strings as JS
window.evil = getEvalInstance(window);
Script execution — runs server-supplied code for each matching content block
// For each content block returned by /fddqa:
if (contentBlock.script) {
  // Inject the HTML template into the target DOM element first
  $(targetElement)[contentBlock.append_type](renderedTemplate);
  if (contentBlock.style) {
    $(targetElement)[contentBlock.append_type](contentBlock.style);
  }
  // Execute the server-supplied JavaScript via the sandboxed interpreter
  evil(contentBlock.script);
  break;
}
04EvidenceSTORAGE DUMP
What's stored on your device

Scripts are cached locally after the first fetch, then re-executed on later visits without re-fetching, so old code persists.

Locationchrome.storage.local key 'ad_{eid}_content{N}'
Contents (JSON)
{
  "aid": "jd_coupon_01",
  "dom": "#BANGNITAO_AD|.jd-promo-container",
  "script": "window.BANGNITAO_ad_loaded=true; /* 7226 chars */",
  "template": "<div class='yhc-coupon'>...</div>",
  "append_type": "after"
}
05EvidenceARTIFACT
Reproduce it yourself

Intercepts the sandboxed interpreter call in 帮您淘优惠 and logs the server-supplied JavaScript strings to the DevTools console before they execute. Run this in the DevTools console on any JD.com product page after the extension has loaded.

RequiresChrome with Developer mode enabled帮您淘优惠 extension installedJD.com product page (item.jd.com)
bangnintao-script-capture.js · js
// bangnintao-script-capture.js
// Intercepts the sandboxed interpreter function in the BANGNINTAO content
// script and logs each server-supplied script string before execution.
//
// Usage: paste into Chrome DevTools console on a JD.com product page
// after 帮您淘优惠 has loaded. Navigate to a product page and watch
// the console for [BANGNINTAO_INTERP] entries.

(function() {
  // The interpreter function is set on window by the extension's content script (js/utils.js)
  // We need to wait for the extension to initialize it first.
  function hookInterp() {
    if (typeof window.evil !== 'function') {
      setTimeout(hookInterp, 100);
      return;
    }
    const originalInterp = window.evil;
    window.evil = function(script) {
      console.group('[BANGNINTAO_INTERP] Server-supplied script intercepted');
      console.log('Script length:', script.length, 'chars');
      console.log('Script contents:', script);
      console.groupEnd();
      // Call the original to allow normal execution (remove this line to block)
      return originalInterp(script);
    };
    console.log('[BANGNINTAO_INTERP] Hook installed. Navigate to a JD.com product page.');
  }
  hookInterp();
})();
How to run it
  1. 1
    Install 帮您淘优惠.
  2. 2
    Open DevTools (F12) on a JD.com page (e.g. https://item.jd.com/).
  3. 3
    Paste this script into Console, press Enter.
  4. 4
    Reload the page.
  5. 5
    Watch console for [BANGNINTAO_INTERP] entries with script content/length.
SeverityHIGH
ClassUNWANTED
TypeUnexpected
CWECWE-829
SourceAI SANDBOX

Server Controls Which Pages Receive Ad Injection

帮您淘优惠 sends your UUID and version to xapi.bntyh.com/version and gets a list of websites/paths for ad content, cached and re-fetched.

A captured POST (15,448 bytes) returned 7+ domains, checked against every visited page, no integrity check.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You navigate to any web page.

The extension did this

The extension tests your URL against a domain/path list fetched from xapi.bntyh.com/version. On a match, it requests and injects ad content from the same server.

The matching list is entirely server-controlled; the server can add or remove any domain or path without an extension update.

02EvidenceNETWORK CAPTURE
Captured request
POSThttps://xapi.bntyh.com/version
200 OK, 15,448 bytes. Returns JSON with: version (string), area (string), ip (string), duration (refresh interval in hours), domain_list (array), urls (object mapping domains to path+eid+pid entries). Observed in dynamic analysis request 1310393.6.
Body
{
  "uuid": "a3f8c921e47b10d2f958c0e3a17b4d89.1744640329122",
  "t": 1744640329844,
  "pver": "3.0.3",
  "area": "CN",
  "ip": "114.87.42.191"
}
03EvidenceCODE COMPARE
The code that does this

The getServerUrls() function that fetches and stores the injection scope list:

What it actually does
// getServerUrls() — fetches injection scope from server
async function getServerUrls() {
  const cachedUrls = await getStorage('urls');    // existing config if any
  let uuid = await getStorage('uuid');
  if (!uuid) uuid = await yhc_get_uuid();          // generate if missing

  const payload = {};
  if (cachedUrls) {
    // send back server's own values to identify the user's region/IP
    payload.pver  = cachedUrls.version;
    payload.area  = cachedUrls.area;
    payload.ip    = cachedUrls.ip;
  }
  payload.uuid = uuid;
  payload.t    = getTime(); // current timestamp

  // POST to /version — no signature, no integrity check
  const response = await httpSync({ url: '/version', type: 'post', data: payload });

  // Cache the response's injection scope list directly
  await setStorage({ urls: response.data });
  return response.data;
}
04EvidenceCODE COMPARE
The code that does this

How the content script uses the server list to select pages for injection:

What it actually does
// In contentScript.js — runs on every page navigation
const config = await getStorage('urls');      // server-supplied scope list
const urlList  = config.urls;                  // domain → [{ path, eid, pid }]
const domainList = config.domain_list;         // additional platform hints

if (domainList) getEcommercePlatform({ hosts: domainList });

const currentPath = window.location.href.replace(window.location.origin, '');

for (const domain of Object.keys(urlList)) {
  if (window.location.origin.includes(domain)) {
    for (const entry of urlList[domain]) {
      // Convert glob-style path to regex
      let pattern = entry.path.replace(/\*$/, '\\S+').replace(/\/$/,'').replace(/\*/g,'[^\\s/]+');
      if (new RegExp(pattern, 'gi').test(currentPath)) {
        shouldInject = true;
        eid = entry.eid;   // ad campaign ID
        pid = entry.pid;   // publisher ID
        break;
      }
    }
  }
}
05EvidenceTHIRD PARTY LIST
Servers involved in the injection scope mechanism:
  • xapi.bntyh.com

    Receives UUID + version info via POST /version; returns the domain/path injection scope list and refresh interval.

SeverityMEDIUM
ClassUNWANTED
TypeUnexpected
CWECWE-359
SourceAI SANDBOX

Device Fingerprint + IP Fused into Persistent Tracking ID

On first install, 帮您淘优惠 fetches your IP and runs Fingerprint2 to collect device data, hashed into a UUID.

Dynamic analysis captured the api.yhchj.com/ip GET, then the UUID in POSTs to xapi.bntyh.com and beacons to sr.anhuiry.com/sp.gif.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You install 帮您淘优惠 for the first time.

The extension did this

The extension fetches your external IP, collects browser fingerprint attributes, combines them into a 128-bit hash, and stores it permanently as your unique ID.

This UUID is then included in every subsequent request to the extension's servers for the lifetime of the install.

02EvidenceNETWORK CAPTURE
Captured request
GEThttps://api.yhchj.com/ip
Returns the user's external IP address as plain text (e.g. "114.87.42.191"). Observed 8 times in a single dynamic analysis (requests observed during dynamic analysis).
03EvidenceFIELD TABLE
Inputs to the UUID hash (everything Fingerprint2.get() collects, minus excluded attributes):
FieldValueWhy it matters
Browser and OS attributes
canvas: data:image/png;base64,iVBORw0KGgo...Canvas rendering, WebGL renderer, screen resolution, timezone, language, and plugins that together uniquely identify your device.
Your external IP address
114.87.42.191Fetched from api.yhchj.com/ip before hashing. Ties the fingerprint to a geographic location and ISP.
Install timestamp
1744640329122The millisecond timestamp at the moment the UUID is first created. Appended after the hash to produce the final UUID string.
04EvidenceSTORAGE DUMP
What's stored on your device

The UUID is written here on first install and read on every subsequent request. It persists indefinitely unless you uninstall the extension.

Locationchrome.storage.local key 'uuid'
Contents
a3f8c921e47b10d2f958c0e3a17b4d89.1744640329122
05EvidenceCODE COMPARE
The code that does this

The UUID generation code from background.js (shipping source vs annotated reading):

What it actually does
// yhc_get_uuid() — runs once on first install if no UUID stored yet
const installTimestamp = Math.round(new Date()); // milliseconds

// Wait for browser idle, then fetch IP and fingerprint
requestIdleCallback(() => {
  // Step 1: fetch external IP
  httpSync({ url: '/ip', baseUrl: 'https://api.yhchj.com' })
    .then(ipResponse => {
      // Step 2: collect browser fingerprint attributes
      Fingerprint2.get(
        { excludes: { enumerateDevices: true, fontsFlash: true, deviceMemory: true } },
        (components) => {
          // Step 3: append IP to the fingerprint array
          components.push({ key: 'ip', value: ipResponse.data });
          const values = components.map(c => c.value);

          // Step 4: hash everything into a 128-bit fingerprint
          const hash = Fingerprint2.x64hash128(values.join(''), 31);
          const uuid = hash + '.' + installTimestamp;

          // Step 5: persist permanently
          setStorage({ uuid: uuid });
          resolve(uuid);
        }
      );
    });
}, { timeout: 500 });
06EvidenceTHIRD PARTY LIST
Where the UUID is transmitted:
  • api.yhchj.com

    IP address lookup, supplies the IP component used in UUID construction.

  • xapi.bntyh.com

    Primary backend for 帮您淘优惠, receives the UUID in POST bodies for /version and /fddqa endpoints on every page load.

  • sr.anhuiry.com

    Analytics pixel beacon, receives the UUID as a query parameter in GET requests to /sp.gif.

Updated 20 September 2026hmlpiahhoampfgiodhahfofmeppmkaeo