Back to skill

Security audit

Publish Antigravity Rotator

Security checks for vulnerabilities and agentic risk

Overview

This skill matches its account-rotation purpose, but it exposes powerful account and session controls too broadly for safe default installation.

Install only if you are prepared to audit and harden it first. At minimum, bind the dashboard to 127.0.0.1, add authentication, remove the bundled OAuth secret, replace shell-string exec calls with argument-array process calls, validate model/account inputs, and make auth-profile/session changes explicit and reversible.

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)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/dashboard.js:361
Finding

Unauthenticated Administrative API Exposed on All Network Interfaces

Content
View full analysis
{ if (req.url === '/' && req.method === 'GET') { res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); res.end(this.generateHTML()); } else if (req.url === '/api' && req.method === 'POST') { let body = ''; req.on('data', chunk => body += chunk); req.on('end', async () => { try { const data = JSON.parse(body); const result = await this.handleApi(data); res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify(result)); } catch (e) { res.writeHead(400); res.end(JSON.stringify({ success: false, message: e.message })); } }); } else { res.writeHead(404); res.end('Not Found'); } }); server.listen(port, '0.0.0.0', () => { console.log(`\n🔮 Antigravity Dashboard started on http://0.0.0.0:${port}`); }); } async handleApi(data) { const { action } = data; let changed = false; const currentConfig = this.readJson(this.configPath); if (action === 'addAccount') { if (!currentConfig.accounts.includes(data.email)) { currentConfig.accounts.push(data.email); changed = true; } } else if (action === 'removeAccount') { currentConfig.accounts = currentConfig.accounts.filter(a => a !== data.email); changed = true; } else if (action === 'setPriority') { if (Array.isArray(data.order) && data.or ...[truncated 2675 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/dashboard.js:389
Finding

Account Identities and Operational Logs Disclosed Through the Dashboard API

Content
View full analysis
k.startsWith('google-antigravity:')) .map(k => k.replace('google-antigravity:', '')); let added = 0; for (const email of antigravityAccounts) { if (!currentConfig.accounts.includes(email)) { currentConfig.accounts.push(email); added++; changed = true; } } if (added > 0) { this.writeJson(this.configPath, currentConfig); this.config = currentConfig; } return { success: true, added, accounts: antigravityAccounts }; } else if (action === 'getDetailedLog') { const log = await this.getDetailedLog(); return { success: true, log }; } ``` The log-reading implementation is: ```js async getDetailedLog() { try { const cronLog = path.join( this.home, '.openclaw/workspace/memory/cron-rotate.log' ); if (fs.existsSync(cronLog)) { const content = fs.readFileSync(cronLog, 'utf8'); const lastPart = content.slice(-20000); const sections = lastPart.split( /=== (余量查询 & 自动轮换|Antigravity Rotator Engine)/ ); if (sections.length > 1) return '=== ' + sections.pop(); return lastPart; } } catch (e) {} return '暂无详细日志数据。'; } ``` ### Technical Analysis The `syncAccounts` operation reads profile keys from the OpenClaw authentication-profile store and returns the resulting account identifiers to the caller. The `getDetailedLog` operation returns up to 20 KB of a local workspace log. Neither operation performs authentication or ...[truncated 1364 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/rotator.js:202
Finding

Shell Command Injection Risk Through Unsafely Interpolated Configuration Values

Content
View full analysis
/dev/null || true` ); ``` ### Technical Analysis `execSync()` invokes a shell. Values such as `this.openclawBin`, `choice.model`, and `m` are concatenated directly into command strings without shell-safe argument handling. The model-priority list can be replaced through the dashboard's unauthenticated `setPriority` operation, and the code does not enforce a fixed model allowlist. The direct rotation path additionally requires a corresponding status database entry and selection by the scheduling algorithm, so exploitation through the dashboard alone depends on reachable application state. However, a malicious or compromised configuration/state file can reliably introduce shell metacharacters. The executable path is also configuration-controlled. If an attacker can alter `co ...[truncated 1310 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/rotator.js:21
Finding

OAuth Client Secret Embedded in Source and Example Configuration

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/dashboard.js:130
Finding

Stored HTML and Script Injection in Dashboard Content

Content
View full analysis
${isActive ? '🟢' : '⚫'} ${shortName}
${isActive ? '正在使用' : ''} ×
${modelsHtml || '
暂无配额数据
'}
更新: ${updateTimeStr}
`; } let logsHtml = logs.map(l => `
${l.time || ''} ${l.message} ›
`).join(''); ``` Detailed log output is also assigned to `innerHTML` without escaping: ```js async function viewLogDetail() { try { const result = await apiCall('getDetailedLog', {}); showModal( '轮换日志详情 - 完整输出', '
text
' + result.log + '
' ); } catch (e) { showModal('错误', '无法获取日志。'); } } ``` The modal inserts this content using: ```js document.getElementById('modal-body').innerHTML = content; ``` ### Technical Analysis Account identifiers, sho ...[truncated 2048 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (26)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The documented behavior materially understates what the skill does: it reportedly refreshes OAuth tokens, rewrites local auth profiles, makes direct network calls, executes external commands, and mutates live sessions, while also advertising a dashboard that is apparently absent. This mismatch is dangerous because users may authorize or run the skill without understanding that it can alter authentication state, rotate accounts automatically, and affect active sessions behind the scenes.

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 59)May include surrounding context.

md
- **逻辑引擎**: `scripts/rotator.js` (配额查询与账号调度)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- **Web UI**: `scripts/dashboard.js` (基于 http 模块的极简服务器)

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
89% confidence
Finding

The dashboard component invokes local shell commands to query backend state via execSync using a command string that includes a configurable binary path. While the current command is not directly built from request input, executing shell commands from a web-facing process increases attack surface and can become command injection or privilege abuse if configuration is tampered with.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The HTTP server listens on 0.0.0.0, exposing the dashboard on all network interfaces instead of limiting it to local access. Because the same service also provides unauthenticated control APIs, this turns a local maintenance tool into a remotely reachable control surface.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill advertises operational automation that involves shell execution, network access, and environment interaction, but it declares no explicit tool scope or permissions. This creates an unsafe trust boundary: users and hosting platforms are not clearly informed that the skill can execute commands, access credentials, and perform external calls, increasing the chance of unintended high-privilege execution.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill promotes 'seamless switching' and hot-updating of active sessions, but does not clearly warn users that background account/model changes can affect ongoing conversations or operational state. This is dangerous because silent switching can alter billing, data handling, model behavior, or reliability expectations mid-session without the operator realizing it.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill explicitly says it will 'scan and load' accounts already logged in, but does not present a prominent warning that it will automatically discover and ingest local credentials. Automatic credential scanning is security-sensitive because it can expose, aggregate, or act on multiple accounts without informed consent, especially in shared or multi-profile environments.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This JSON example contains natural-language instructions exclusively in Chinese across multiple comment fields. Per policy, forcing a specific language without offering a user choice or documenting a justified locale constraint is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The example configuration embeds a Google OAuth client secret directly in the repository. Even if intended as a default/demo value, publishing OAuth credentials enables unauthorized reuse of the OAuth client, phishing-style consent flows, or abuse against the associated Google project, and it is unrelated to a harmless local-only example config. In this skill’s context, which manages multiple accounts and OAuth-based authentication, shipping a real-looking secret is more dangerous because users are encouraged to rely on it for live credential flows.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The manifest describes automated account rotation, quota monitoring, hot session updates, and a dashboard. In this file, the optional setup path imports child_process and runs which openclaw, introducing shell execution behavior that is not described as part of the skill's purpose and goes beyond ordinary config/file handling for the stated workflow.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The package description is entirely in Chinese and provides no indication that other languages are supported or that the skill is intentionally limited to a Chinese-speaking audience. Under the stated policy, forcing a specific language without user opt-in or documented justification is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code persists changes directly to the skill's configuration file via writeFileSync, and API actions such as removeAccount, syncAccounts, and setPriority trigger those writes. While some UI flows confirm account removal, there is no visible disclosure that these actions modify local files and persist state on disk.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The dashboard exposes state-changing management actions over HTTP, including account removal, priority changes, account syncing, and rotation triggering, with no authentication, authorization, or origin protection. In combination with the network listener on 0.0.0.0, any reachable client can remotely alter operational state and control account rotation behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This endpoint invokes a shell command through exec to run a rotation action, which is a safety-relevant operation affecting account state and automation behavior. The frontend button immediately calls the API and only reports success afterward, with no prior disclosure or confirmation prompt.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest describes automated account rotation, quota monitoring, hot session updates, and a dashboard. While interacting with the local OpenClaw tool may be part of session switching, this implementation broadly shells out to system binaries (which, curl, openclaw, timeout) rather than limiting itself to direct application logic, introducing command-execution capability not explicitly justified by the stated purpose.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

The skill transmits OAuth client credentials and refresh tokens to Google's token endpoint by constructing a shell command that embeds sensitive values directly in the command line. Even if the endpoint is legitimate, secrets in process arguments can be exposed via process listings, logs, crash reports, or shell-history-like telemetry, making credential theft possible on shared systems.

Content

Scanner excerpt · scripts/rotator.js (reported line 55)May include surrounding context.

js
refresh_token: refreshToken,
            grant_type: 'refresh_token'
        }).toString();
        const cmd = `curl -s --connect-timeout 10 --retry 1 -X POST "${this.REFRESH_TOKEN_URL}" -d "${postData}"`;
        try {
            const output = execSync(cmd, { encoding: 'utf8', timeout: 35000 });
            const json = JSON.parse(output);

External Transmission

Medium
Category
Data Exfiltration
Confidence
83% confidence
Finding

The quota-fetch request sends bearer tokens to an external service using curl with the Authorization header embedded in the shell command line. This risks token exposure through local process inspection or logging and expands trust to a nonstandard internal-looking endpoint, which is especially sensitive in a credential-rotation tool.

Content

Scanner excerpt · scripts/rotator.js (reported line 69)May include surrounding context.

js
const body = { project: projectId || this.DEFAULT_PROJECT_ID };
        const headerArgs = Object.entries(headers).map(([k, v]) => `-H "${k}: ${v}"`).join(' ');
        const bodyStr = JSON.stringify(body).replace(/"/g, '\\"');
        const cmd = `curl -s --connect-timeout 10 --retry 1 -X POST "${this.QUOTA_API_URL}" ${headerArgs} -d "${bodyStr}"`;
        try {
            const output = execSync(cmd, { encoding: 'utf8', timeout: 35000 });
            if (!output.trim()) throw new Error('Empty response');

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This code overwrites the active auth profile and changes the selected model/session without user confirmation, effectively taking control of the operator's current runtime state. In a multi-account environment, silent credential switching can cause actions to run under the wrong identity and can disrupt ongoing sessions or auditability.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The warmup routine performs active inference runs across multiple accounts/models and rewrites the active VIP auth profile, behavior not disclosed by the stated quota/rotation function. This can consume quota, trigger account activity, and temporarily switch credentials in ways users may not expect, increasing the blast radius if the skill is misconfigured or abused.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The warmup flow repeatedly rewrites auth profiles and launches subprocesses with little visibility or consent, creating hidden state changes and background activity. If interrupted or raced, it may leave the wrong credentials active or consume resources/accounts unexpectedly.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The primary description is written in Chinese and the document continues to present core instructions in Chinese, while not stating that the skill is region-specific or offering a language choice. This can violate language/locale policy when a skill imposes a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code formats times using the zh-CN locale, and the generated UI is also explicitly marked as zh-CN elsewhere in the file. Because the skill forces a specific language/locale without opt-in or explanation, it conflicts with the language/locale policy criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The page is explicitly declared as Chinese-language content via the lang attribute, and the surrounding UI strings are written in Chinese. This enforces a specific language experience without presenting a user choice or documenting a justified regional limitation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The manifest focuses on account rotation, quota checks, and live model updates. Altering the inherited PATH environment for the entire process is a broader execution-environment manipulation capability that is not necessary to express at the intent level and can affect how later commands resolve binaries.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.env_credential_access, suspicious.exposed_secret_literal

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
index.js:39

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/dashboard.js:22

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/rotator.js:33

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/dashboard.js:10

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/rotator.js:24