Back to skill

Security audit

Dolphin Anty

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent Dolphin Anty automation tool, but it gives an agent broad control over stealth browser profiles, authenticated sessions, stored profile data, and API credentials with limited safeguards.

Install only if you intentionally want an agent to control Dolphin Anty profiles. Use short-lived limited tokens, keep the skill directory private, avoid running custom JavaScript from untrusted prompts or pages, confirm profile deletion manually, and be aware that automated browsing, scraping, registration, warm-up, and profile sync may affect third-party accounts and stored session data.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (3)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/dolphin_setup.js:100
Finding
API Token Stored in an Unprotected Plaintext File<![CDATA[ ## Vulnerability Details **File Location**: `scripts/dolphin_setup.js:18, 100-101` **Vulnerability Type**: Plaintext credential storage **Risk Level**: Medium ### Vulnerable Code ```javascript const TOKEN_FILE = path.join(__dirname, '..', '.token'); ``` ```javascript // 2. Save token to file fs.writeFileSync(TOKEN_FILE, token, 'utf8'); console.log(`💾 Токен сохранён: ${TOKEN_FILE}`); ``` ### Technical Analysis The setup script writes a reusable Dolphin Anty API bearer token directly into `.token` inside the project directory. The file permissions are determined by the process umask; the script does not explicitly restrict the file to its owner, validate existing file ownership, use an operating-system credential store, or encrypt the credential. Storing the token within the project also increases the probability that it will be included accidentally in source-control commits, backups, archives, or project-directory transfers. In addition, the documented `--token` argument exposes the secret to shell history and may temporarily expose it through process-list inspection. The token is subsequently used to authenticate to the Dolphin Anty cloud API, including profile listing, creation, and deletion operations. ### Attack Path 1. A user runs `dolphin_setup.js --token <API_TOKEN>`. 2. The script writes the token to the project-root `.token` file. 3. A local user or process with read access to the project directory reads the file. Alternatively, the file is accidentally included in a repository, archive, or backup. 4. The attacker extracts the bearer token. 5. The attacker submits the token to `https://dolphin-anty-api.com`. 6. The attacker accesses or modifies the victim's Dolphin Anty browser profiles according to the token's account permissions. ### Impact Assessment Successful exploitation discloses a reusable cloud API credential. The attacker may obtain the same Dolphin Anty API privileges as the token holder, potentially including: - Enum ...[truncated 470 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Store the token in an operating-system credential manager, such as macOS Keychain, Windows Credential Manager, or Linux Secret Service. 2. If file-based storage is unavoidable: - Store the file outside the project directory. - Create it with owner-only permissions such as mode `0600`. - Verify that the file is owned by the current user and is not a symbolic link before writing. - Refuse to use files with unsafe permissions. 3. Add `.token` to the project's `.gitignore` and relevant packaging exclusion files. 4. Accept the token through standard input or an interactive hidden prompt rather than a command-line argument. 5. Avoid printing the credential file's exact location unless required for troubleshooting. 6. Use short-lived, minimally scoped API tokens and document immediate revocation procedures. 7. Rotate any token that may already have been stored with excessive permissions or included in a shared artifact. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/dolphin_setup.js:105
Finding
Reusable Cloud API Token Sent to an Unauthenticated Local HTTP Service<![CDATA[ ## Vulnerability Details **File Location**: `scripts/dolphin_setup.js:105-109`; related behavior in `scripts/dolphin_profiles.js:17, 39-48, 213` **Vulnerability Type**: Credential disclosure through unauthenticated local transport **Risk Level**: Medium ### Vulnerable Code ```javascript // 3. Register token with local API try { const res = await apiCall('POST', 'http://localhost:3001/v1.0/auth/login-with-token', { token: token }, { 'Content-Type': 'application/json' } ); ``` Related local API configuration and authorization behavior: ```javascript const LOCAL_API = 'http://localhost:3001'; ``` ```javascript const base = useCloud ? CLOUD_API : LOCAL_API; const fullPath = useCloud ? apiPath : '/v1.0' + apiPath; const url = new URL(base + fullPath); const isHttps = url.protocol === 'https:'; const token = getToken(); const headers = { 'Content-Type': 'application/json' }; if (token) headers['Authorization'] = 'Bearer ' + token; ``` ```javascript await apiRequest('POST', '/auth/login-with-token', { token: token }); ``` ### Technical Analysis The scripts send the reusable Dolphin Anty cloud bearer token to a service listening on `localhost:3001` over plaintext HTTP. Loopback traffic is not normally exposed to remote network hosts, but the client does not authenticate the identity of the process bound to that port. If the legitimate Dolphin Anty application is not running, another local process can bind to port 3001 and impersonate its API. The setup and status operations will then transmit the token to that process. In the setup request, the token appears in the JSON body. The profile helper also attaches the token as an `Authorization` header to local API requests whenever a token exists. The security issue is therefore not merely the lack of TLS encryption on loopback. It is the absence of a mechanism that verifies the local endpoint before disclosing a reusable cloud credential. ### Attack Path 1. The attacker obtains the abil ...[truncated 1324 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not transmit a reusable cloud bearer token to an unauthenticated local HTTP endpoint. 2. Prefer a protected IPC mechanism, such as a Unix-domain socket or named pipe with strict user-level access controls. 3. If TCP must be used, authenticate the local service using a pinned certificate, challenge-response protocol, or another cryptographically verifiable mechanism. 4. Exchange the cloud token for a short-lived, narrowly scoped local-session credential rather than reusing the cloud credential. 5. Separate cloud and local API request helpers so cloud authorization headers are never attached automatically to local requests. 6. Verify that the expected Dolphin Anty process owns the listening endpoint where supported by the operating system. 7. Bind explicitly to `127.0.0.1` rather than relying on hostname resolution, while recognizing that loopback binding alone does not authenticate the listener. 8. Expire and rotate any cloud token believed to have been disclosed to an untrusted local service. ]]>

T08 · Insecure Dependencies

Note
Location
scripts/dolphin_automate.js:113
Finding
Unpinned Global Playwright Dependency Is Loaded Without Integrity Verification<![CDATA[ ## Vulnerability Details **File Location**: `scripts/dolphin_automate.js:113-124`; installation guidance in `SKILL.md:43-55` **Vulnerability Type**: Unsafe third-party dependency installation and resolution **Risk Level**: Low ### Vulnerable Code ```javascript async function connectBrowser(port, wsEndpoint) { let playwright; try { playwright = require('playwright'); } catch { // Fallback: try global node_modules try { const globalPath = require('child_process').execSync('npm root -g', { encoding: 'utf8' }).trim(); playwright = require(require('path').join(globalPath, 'playwright')); } catch { console.error('❌ Playwright не установлен. Выполните: npm install -g playwright'); process.exit(1); } } ``` The documentation instructs users to install an unpinned global package: ```bash npm install -g playwright ``` ### Technical Analysis The project does not declare an exact Playwright version in a package manifest or provide a lockfile. Instead, users are instructed to install the latest globally available `playwright` package, and the runtime falls back to loading whatever module is present in the global npm root. This design provides no project-level version pinning or reproducible integrity control. The effective code loaded by the Skill can vary by system and installation date. A compromised package release, maliciously configured npm registry, or locally replaced global package can execute arbitrary code when loaded through `require()`. Calling `npm root -g` through `execSync` does not directly create command injection in this code because the command string is constant. The primary risk is trusting an unpinned, mutable global dependency location. ### Attack Path One applicable supply-chain path is: 1. An attacker compromises the configured npm registry, a relevant package release, or the local global npm installation. 2. The victim follows the documentation and runs `npm install -g playwri ...[truncated 1183 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Add a project-level `package.json` and declare an exact, reviewed Playwright version. 2. Generate and commit a lockfile containing package versions and integrity hashes. 3. Install dependencies reproducibly with `npm ci` rather than using a mutable global installation. 4. Remove the fallback that dynamically loads Playwright from the global npm root. 5. Use the official npm registry over HTTPS and review project-level and user-level npm registry configuration. 6. Enable dependency provenance, integrity, vulnerability, and license checks in CI. 7. Review dependency updates before changing the pinned version. 8. Run browser automation under a dedicated, least-privileged account or sandbox to limit the impact of a compromised package. ]]>
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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (23)

Vague Triggers

High
Confidence
97% confidence
Finding
The skill advertises very broad trigger phrases such as generic browser opening, scraping, account registration, and data collection, which can cause an agent to invoke a powerful antidetect-browser automation capability in contexts the user did not explicitly intend. Because the skill enables stealth browsing, profile manipulation, and external-site interaction, accidental invocation could lead to unauthorized automation, privacy-impacting actions, or policy-sensitive behavior with little friction.

Ae1

High
Category
analysis-evasion
Content
node scripts/dolphin_profiles.js list
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/dolphin_profiles.js list
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/dolphin_profiles.js list
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/dolphin_profiles.js list
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/dolphin_profiles.js list
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/dolphin_automate.js --profile-id <ID> --task <TASK> [--url <URL>] [--code <JS>]
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/dolphin_automate.js --profile-id <ID> --task <TASK> [--url <URL>] [--code <JS>]
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/dolphin_automate.js --profile-id <ID> --task <TASK> [--url <URL>] [--code <JS>]
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/dolphin_automate.js --profile-id <ID> --task <TASK> [--url <URL>] [--code <JS>]
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/dolphin_automate.js --profile-id <ID> --task <TASK> [--url <URL>] [--code <JS>]
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/dolphin_automate.js --profile-id <ID> --task <TASK> [--url <URL>] [--code <JS>]
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The custom task accepts arbitrary JavaScript from the command line and executes it in the browser context via page.evaluate(code). In an agent or skill setting, this creates a powerful code-execution primitive over authenticated browser sessions, enabling data theft, unauthorized actions on websites, or execution of attacker-supplied logic well beyond the declared automation tasks.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The capability description promotes scraping, account warm-up, profile persistence, and human-like behavior without clear warnings that these actions can modify third-party accounts, store cookies/localStorage, touch external sites, and create compliance or privacy risks. In this context, omission of warnings is more dangerous because the skill is explicitly designed for stealth automation and fingerprint spoofing, increasing the chance that users or agents will underestimate the consequences of use.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
Suspicious Unicode normalization or mixed-script content

Context-Inappropriate Capability

Medium
Confidence
87% confidence
Finding
When local require fails, the code runs execSync('npm root -g') through child_process to discover a global module path. For a skill with unknown purpose and documentation centered on Dolphin/Playwright browser automation, executing host shell commands is a separate capability that is not clearly required by the stated task behavior.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The script exposes arbitrary browser-context JavaScript execution without guardrails, meaningful warnings, or restrictions. In practice this can be abused to read page data, manipulate authenticated sessions, trigger transactions, or exfiltrate sensitive information from sites opened in the Dolphin profile.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The delete command performs an irreversible destructive action immediately after receiving a profile ID, with no confirmation prompt, dry-run mode, or safeguard against accidental invocation. In a CLI that manages real browser profiles, this materially increases the risk of accidental data loss from user error, scripting mistakes, or misuse by another tool calling the command.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
Suspicious Unicode normalization or mixed-script content

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script writes a bearer API token directly to a predictable local file (`.token`) in plaintext without setting restrictive file permissions, encrypting it, or warning the user about credential handling. If the host is multi-user, the workspace is backed up/synced, or the repository is accidentally shared, the token can be exposed and reused to access the Dolphin Anty account/API.

Natural-Language Policy Violations

Low
Confidence
97% confidence
Finding
Natural-language strings in comments, help text, logs, and errors are presented in Russian, which effectively forces a specific language for users interacting with the script. The file does not offer language selection or explain that the tool is intentionally limited to a Russian-speaking context.

Natural-Language Policy Violations

Low
Confidence
93% confidence
Finding
Comments, help text, and runtime messages are presented in Russian throughout the script, and the user is not offered any way to select a different language. This can violate language/locale policy when a skill forces a specific language without user opt-in or documented regional justification.

Natural-Language Policy Violations

Low
Confidence
98% confidence
Finding
The file's natural-language comments, prompts, and status messages are entirely in Russian, which imposes a specific language on all users. There is no opt-in, language selection, or indication that the skill is intentionally limited to a Russian-speaking or region-specific audience.