T09 · Insecure Skill Coding Practices
- Location
scripts/linkedin.mjs:8- Finding
User-Controlled API Endpoint Can Receive the Unipile Access Token
- Content
View full analysis
Vulnerability Details
File Location:
scripts/linkedin.mjs, lines 8–16
Vulnerability Type: Unvalidated credential-bearing service endpoint
Risk Level: MediumVulnerable Code
js const DSN = process.env.UNIPILE_DSN; const TOKEN = process.env.UNIPILE_ACCESS_TOKEN; if (!DSN || !TOKEN) { console.error('Error: Set UNIPILE_DSN and UNIPILE_ACCESS_TOKEN environment variables'); console.error('Get credentials from https://dashboard.unipile.com'); process.exit(1); } const client = new UnipileClient(DSN, TOKEN);Technical Analysis
The CLI obtains both the API endpoint and access token from environment variables and passes them directly to
UnipileClient. Although the code checks that both values exist, it does not validate the endpoint's protocol, hostname, port, embedded credentials, or destination.Consequently, an attacker who can influence
UNIPILE_DSNwhile preserving the legitimateUNIPILE_ACCESS_TOKENcan redirect authenticated SDK requests to an attacker-controlled service. Depending on how the SDK transmits authentication, that service may receive the access token or another reusable authorization value.This requires control over the process environment, an environment file loaded by
dotenv/config, or the mechanism that supplies skill configuration. The issue does not independently provide such control.Attack Path
- A legitimate Unipile access token is configured in
UNIPILE_ACCESS_TOKEN. - An attacker modifies the process environment or loaded dotenv configuration so that
UNIPILE_DSNreferences an attacker-controlled endpoint. - A user or agent invokes any CLI command, such as
accounts. - The CLI initializes
UnipileClientwith the attacker-selected endpoint and legitimate token. - The SDK sends an authenticated request to that endpoint.
- The attacker captures the exposed authentication material and attempts to reuse it against the legitimate Unipile service.
Impact Assessment
Successfu ...[truncated 691 chars]
- A legitimate Unipile access token is configured in
- Remediation
View remediation
Remediation Suggestions
Validate and normalize the endpoint before constructing the API client:
- Parse
UNIPILE_DSNwithnew URL()and reject malformed values. - Require the
https:protocol. - Enforce an explicit allowlist of trusted Unipile hostnames or the exact tenant endpoint provisioned through a trusted configuration source.
- Reject IP literals, loopback addresses, private-network destinations, link-local addresses, embedded URL credentials, fragments, and unexpected ports.
- Ensure the HTTP client does not forward authorization headers across cross-origin redirects; preferably disable redirects or validate every redirect destination.
- Store the endpoint in deployment-controlled configuration that untrusted users and skill inputs cannot modify.
- Scope and rotate the access token, and revoke it immediately if endpoint manipulation or credential exposure is suspected.
- Consider deriving the endpoint from a trusted tenant or region identifier rather than accepting an unrestricted URL.
Example validation pattern:
js function validateUnipileDsn(rawDsn) { const url = new URL(rawDsn); if (url.protocol !== 'https:') { throw new Error('UNIPILE_DSN must use HTTPS'); } if ( url.username || url.password || url.hash || !url.hostname.endsWith('.unipile.com') ) { throw new Error('UNIPILE_DSN is not an approved Unipile endpoint'); } return url.origin; } const client = new UnipileClient( validateUnipileDsn(process.env.UNIPILE_DSN), process.env.UNIPILE_ACCESS_TOKEN );A strict tenant-specific hostname allowlist is preferable to a broad suffix check.
- Parse
