Back to skill

Security audit

Binance Square Skill

Security checks for vulnerabilities and agentic risk

Overview

This skill is meant to post to Binance Square, but it uses full browser-session credentials and includes under-scoped browser/API tooling that could leak credentials or mutate the account beyond a simple publish action.

Review before installing. Use this only if you are comfortable giving an agent live Binance browser-session credentials and authority to post publicly. Prefer an isolated/test account, keep credentials out of shared files, restrict configuration to https://www.binance.com and local trusted CDP only, and avoid running the analyzer or endpoint probe against a real account.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
src/api/client.ts:116
Finding

Binance credentials can be transmitted to an arbitrary configured API origin

Content
View full analysis
{ const configShape = { cdpUrl: env.BINANCE_CDP_URL, apiBaseUrl: env.BINANCE_API_BASE_URL, cookieHeader: env.BINANCE_COOKIE_HEADER, csrfToken: env.BINANCE_CSRF_TOKEN, sessionToken: env.BINANCE_SESSION_TOKEN, userAgent: env.BINANCE_USER_AGENT, referer: env.BINANCE_REFERER, ``` ```ts // src/api/client.ts:116-133 public async request(options: RequestOptions): Promise { const url = `${this.config.apiBaseUrl}${options.path}${buildQueryString(options.query)}`; const hasJsonBody = options.body !== undefined && !options.formData; const headers = new Headers({ Accept: "application/json, text/plain, */*", Cookie: this.config.cookieHeader, Referer: this.config.referer, "User-Agent": this.config.userAgent, ...(hasJsonBody ? { "Content-Type": "application/json" } : {}), ...(this.config.csrfToken ? { "X-CSRF-Token": this.config.csrfToken } : {}), ...(this.config.sessionToken ? { "X-Session-Token": this.config.sessionToken } : {}), ...(options.headers ?? {}) }); ``` ### Technical Analysis The configuration schema accepts any syntactically valid URL for `apiBaseUrl ...[truncated 1679 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
src/api/browser-client.ts:301
Finding

CDP mode discloses Binance cookies to insufficiently validated browser targets

Content
View full analysis
{ const parsed = new URL(cdpUrl); return `${parsed.protocol}//${parsed.host}`; }; const fetchCdpPages = async (cdpUrl: string): Promise => { const baseUrl = parseCdpBaseUrl(cdpUrl); const response = await fetch(`${baseUrl}/json`); if (!response.ok) { throw new NetworkError(`CDP endpoint returned ${response.status}`); } return response.json() as Promise; }; const findBinancePage = (pages: CdpPage[]): CdpPage => { const binancePage = pages.find((p) => p.url.includes("binance.com")); const target = binancePage ?? pages[0]; if (!target) { throw new NetworkError("No browser page found via CDP"); } return target; }; ``` ```ts // src/api/browser-client.ts:122-143 const injectCookies = async (send: CdpSendFn, cookieHeader: string): Promise => { const segments = cookieHeader .split(";") .map((s) => s.trim()) .filter((s) => s.length > 0); for (const segment of segments) { const eqIndex = segment.indexOf("="); if (eqIndex <= 0) continue; const name = segment.slice(0, eqIndex).trim(); const value = segment.slice(eqIndex + 1).trim(); await send("Network.setCookie", { name, value, domain: ".binance.com", path: "/", httpOnly: false, secure: true }); } }; ``` ```ts // src/api/browser-client.ts:301-320 public async connect(): Promise { if (!this.config.cdpUrl) { throw new NetworkError("BrowserClient requires cdpUrl to be configured"); } const pages = await fetchCdpPages(this.config.cdpUrl); ...[truncated 2169 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
src/utils/image-upload.ts:72
Finding

Unrestricted image URL downloading enables server-side request forgery

Content
View full analysis
=> { let parsedUrl: URL; try { parsedUrl = new URL(imageUrl); } catch { throw new ValidationError("imageUrl must be a valid URL"); } const fetchImpl = dependencies.fetchImpl ?? fetch; const imageResponse = await fetchImpl(parsedUrl.toString(), { method: "GET", redirect: "follow" }); if (!imageResponse.ok) { throw new ApiError(`Unable to download image from URL (status ${imageResponse.status})`, imageResponse.status); } const mimeType = normalizeMimeType(imageResponse.headers.get("content-type")); const allowedMimeTypes = dependencies.config.image.allowedMimeTypes.map((item) => item.toLowerCase()); if (!mimeType || !allowedMimeTypes.includes(mimeType)) { throw new ValidationError(`Unsupported image mime type: ${mimeType ?? "unknown"}`); } const contentLengthRaw = imageResponse.headers.get("content-length"); if (contentLengthRaw) { const declaredSize = Number(contentLengthRaw); if (Number.isFinite(declaredSize) && declaredSize > dependencies.config.image.maxBytes) { throw new ValidationError(`Image exceeds size limit (${dependencies.config.image.maxBytes} bytes)`); } } const bytes = new Uint8Array(await imageResponse.arrayBuffer()); ``` ```ts // src/tools/publish-post.ts:99-113 const parsedInput = publishPostInputSchema.parse(input); const uploadImage = dependencies.uploadImage ?? ((imageUrl: string) => uploadImageFromUrl(imageUrl, { client: dependencies.client, config: dependencies.config })); const imageUrls = parsedInput.imageUrls ?? []; cons ...[truncated 2019 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/analyze-api.ts:132
Finding

API analysis utility persists authenticated request headers and bodies without redaction

Content
View full analysis
{ const url = request.url(); if (!url.includes("/bapi/")) { return undefined; } const parsedUrl = new URL(url); const headers = request.headers(); const postData = request.postData(); return { method: request.method(), url, path: parsedUrl.pathname, headers, ...(postData ? { postData: postData.slice(0, 1200) } : {}) }; }; ``` ```ts // scripts/analyze-api.ts:192-216 page.on("request", (request) => { const normalized = toCapturedRequest(request); if (!normalized) { return; } const key = `${normalized.method} ${normalized.path}`; if (!captured.has(key)) { captured.set(key, normalized); } }); await page.goto(options.targetUrl, { waitUntil: "domcontentloaded", timeout: 60_000 }); await page.waitForTimeout(options.durationMs); const requests = Array.from(captured.values()).sort((a, b) => a.path.localeCompare(b.path)); const uniquePaths = Array.from(new Set(requests.map((request) => request.path))).sort(); const report = { generatedAt: new Date().toISOString(), targetUrl: options.targetUrl, sampleSize: requests.length, uniquePaths, suggestedEnv: buildSuggestions(uniquePaths), capturedRequests: requests }; const outputPath = path.resolve(process.cwd(), options.outputPath); writeFileSync(outputPath, JSON.stringify(report, null, 2), "utf8"); ``` ### Technical Analysis The analyzer obtains all request headers returned by Playwright for matching `/bapi/` requests and includes those headers unchanged in `capturedRequests`. It also stores up to 1,200 characters of each captured POST body. The report is then written to a predicta ...[truncated 1419 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/probe-endpoints.ts:73
Finding

Endpoint probing utility sends broad authenticated state-changing requests

Content
View full analysis
extends Promise ? T extends { send: infer S } ? S : never : never, method: string, path: string, body?: Record ) => { const bodyStr = body ? JSON.stringify(body) : "undefined"; const expression = ` fetch("${path}", { method: "${method}", headers: { "content-type": "application/json", "clienttype": "web" }, credentials: "include", body: ${method === "GET" ? "undefined" : bodyStr} }).then(async r => { const t = await r.text(); return { status: r.status, body: t.slice(0, 400) }; }) `; ``` ```ts // scripts/probe-endpoints.ts:73-112 const target = await getTarget(); process.stdout.write(`Target: ${target.url}\n`); const { ws, send } = await connectCdp(target.webSocketDebuggerUrl); const endpoints: Array<[string, string, Record?]> = [ // Content creation ["POST", "/bapi/composite/v1/private/pgc/content/create", { content: "test" }], ["POST", "/bapi/composite/v2/private/pgc/content/create", { content: "test" }], ["POST", "/bapi/composite/v1/private/pgc/content/publish", { content: "test" }], ["POST", "/bapi/composite/v1/private/pgc/post/create", { content: "test" }], ["POST", "/bapi/composite/v1/private/pgc/post/publish", { content: "test" }], ["POST", "/bapi/composite/v1/private/pgc/content/short/create", { content: "test" }], ["POST", "/bapi/composite/v2/private/pgc/content/short/create", { content: "test" }], ["POST", "/bapi/composite/v1/private/pgc/content/article/create", { content: "test" }], ["POST", "/bapi/composite/v2/private/pgc/content/article/create", { content: "test" }] ...[truncated 2691 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (53)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

Connecting to a local CDP endpoint, executing fetch calls inside an existing browser session, and probing multiple private endpoints goes well beyond a standard publishing skill. In context, this broadens the skill into authenticated browser/session exploitation and reconnaissance, which materially raises the risk of unintended actions, data access, and policy bypass.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

Connecting to a local CDP endpoint, executing fetch calls inside an existing browser session, and probing multiple private endpoints goes well beyond a standard publishing skill. In context, this broadens the skill into authenticated browser/session exploitation and reconnaissance, which materially raises the risk of unintended actions, data access, and policy bypass.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

Connecting to a local CDP endpoint, executing fetch calls inside an existing browser session, and probing multiple private endpoints goes well beyond a standard publishing skill. In context, this broadens the skill into authenticated browser/session exploitation and reconnaissance, which materially raises the risk of unintended actions, data access, and policy bypass.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 74)May include surrounding context.

md
node scripts/bn-square.mjs validate_session

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 80)May include surrounding context.

md
node scripts/bn-square.mjs validate_session

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 86)May include surrounding context.

md
node scripts/bn-square.mjs validate_session

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The guide tells users to copy cookie, CSRF, and session token values from authenticated requests into local configuration without clearly warning that these are bearer-style secrets that may grant direct account access if exposed. In the context of a publishing skill, this is especially dangerous because an agent or downstream tool with these values could post content, impersonate the user, or access account-scoped actions.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/bn-square.mjs (reported line 44)May include surrounding context.

js
module.exports = {
      name: "dotenv",
      version: "16.6.1",
      description: "Loads environment variables from .env file",
      main: "lib/main.js",
      types: "lib/main.d.ts",
      exports: {

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The endpoint list includes multiple private content creation, publish, draft-save, media upload, and vote creation routes, and the script automatically issues authenticated POST requests with credentials included. Because this happens without any user-facing warning, consent, or dry-run mode, executing the script can create or publish content on the user's Binance account and normalize silent authenticated actions beyond the skill's documented purpose.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/bn-square.mjs (reported line 79)May include surrounding context.

js
return envFromProcess;
  }

  const resolvedEnvPath = path.resolve(cwd, options.envPath ?? ".env");
  if (!existsSync(resolvedEnvPath)) {
    return envFromProcess;
  }

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/bn-square.mjs (reported line 251)May include surrounding context.

js
return envFromProcess;
  }

  const resolvedEnvPath = path.resolve(cwd, options.envPath ?? ".env");
  if (!existsSync(resolvedEnvPath)) {
    return envFromProcess;
  }

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/bn-square.mjs (reported line 5045)May include surrounding context.

js
return envFromProcess;
  }

  const resolvedEnvPath = path.resolve(cwd, options.envPath ?? ".env");
  if (!existsSync(resolvedEnvPath)) {
    return envFromProcess;
  }

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · src/config/loader.ts (reported line 71)May include surrounding context.

ts
return envFromProcess;
  }

  const resolvedEnvPath = path.resolve(cwd, options.envPath ?? ".env");
  if (!existsSync(resolvedEnvPath)) {
    return envFromProcess;
  }

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill declares required environment variables and clearly intends to perform authenticated network actions, but it does not define an explicit tool scope such as allowed tools or permissions. That omission weakens containment and reviewability, increasing the chance an agent executes network or secret-bearing operations without least-privilege boundaries.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill instructs users to extract a full authenticated Binance cookie header and CSRF token from browser traffic and store them as environment variables, but it does not prominently warn that these are live account credentials equivalent to session access. In an agent context, this is especially dangerous because compromise, mishandling, or overbroad reuse of those values could enable unauthorized posting or broader account actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The publish_post command is documented as a normal core command without a clear warning that it performs a real external action on the user's Binance account. In an autonomous-agent setting, insufficient disclosure can lead to accidental public posting, reputational damage, or unauthorized content publication.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The manifest describes a limited publishing skill focused on session validation, publishing posts, and status checks. However, the documented endpoints also include draft saving, vote creation, and pre-check operations, which extend the skill beyond that stated scope rather than serving as clearly necessary implementation details.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documentation explicitly instructs users to reverse-engineer private Binance API paths and harvest authenticated browser headers and cookies, which enables use of undocumented authenticated endpoints outside normal supported flows. That materially expands the skill's capability beyond ordinary publishing guidance and can facilitate account misuse, break platform protections, and normalize credential extraction from an active browser session.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The example config.json stores live authentication material in plaintext, increasing the chance of accidental disclosure through source control, backups, local malware, or agent file reads. Because these values appear sufficient to replay an authenticated Binance session, plaintext file storage creates a practical path to account takeover or unauthorized posting.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script accepts Binance session cookies from CLI or the BINANCE_COOKIE_HEADER environment variable and then injects them into a browser context for network capture. In the context of a publishing skill, pulling live auth material into an API-analysis utility expands the trust boundary and creates unnecessary exposure of sensitive session credentials.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The tool accepts sensitive cookie material via command-line flags or environment variables without explicit warning, making accidental exposure more likely through shell history, process inspection, logs, or inherited environment settings. Because these are active Binance session credentials, mishandling them can lead to account takeover or unauthorized actions.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This code passively records Binance /bapi/ traffic, guesses undocumented endpoints, and builds a report of discovered API paths rather than limiting itself to validating session state, publishing posts, or checking post status. In a skill advertised for publishing, this extra capability is risky because it enables authenticated endpoint discovery and broad traffic inspection beyond the declared function.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script serializes captured request headers and truncated POST bodies to a JSON report on disk, which can include authorization headers, CSRF tokens, cookies, account identifiers, or post content. Writing this data without redaction or prominent warning creates a high risk of credential leakage and secondary compromise if the file is shared, committed, or read by other local processes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This request builder automatically attaches cookie, CSRF, and session-token headers to outbound network requests, which can transmit authenticated user/session data. While the code sanitizes some error messages, there is no nearby comment, prompt, or disclosure in this file warning that running the skill will send browser/session credentials to a remote service.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The code can connect to a Chrome DevTools Protocol endpoint, enumerate pages, inject cookies, navigate pages, and execute arbitrary JavaScript fetch expressions in the browser context. That is substantially broader than simple publishing and, if a cdpUrl is supplied, gives the skill powerful browser automation primitives that could act on a live logged-in session beyond the stated purpose.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/bn-square.mjs:175