Back to skill

Security audit

Keyapi Linkedin Company Analysis

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a LinkedIn analysis wrapper, but its bundled runner has broader MCP access and credential handling than the user-facing purpose suggests.

Review before installing. Use this only in a workspace where plaintext .env and .keyapi-cache files are acceptable, avoid entering tokens interactively, set KEYAPI_TOKEN through a safer secret mechanism, do not set KEYAPI_SERVER_URL unless you fully trust the destination, and verify commands always use the intended LinkedIn platform and expected tool names.

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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/run.js:59
Finding

Bearer Token Can Be Redirected to an Arbitrary Server

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/run.js:258
Finding

API Token Is Persisted in a Plaintext Project File

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/run.js:393
Finding

LinkedIn and API Responses Are Retained in Plaintext Files

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
package.json:5
Finding

Dependency Version Is Not Reproducibly Pinned

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (30)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill is presented as a LinkedIn company analysis tool, but the described runtime behavior can enumerate schemas/tools, invoke generic KeyAPI MCP functionality, target multiple platforms, persist tokens/cache data, and perform unrelated auxiliary processing. That mismatch is dangerous because users may authorize the skill expecting narrow LinkedIn-only behavior while it actually enables broader data access, capability discovery, and persistence than disclosed.

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

md
node scripts/run.js --platform linkedin --list-tools

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/run.js --platform linkedin --list-tools

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/run.js --platform linkedin --list-tools

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/run.js --platform linkedin --list-tools

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/run.js --platform linkedin --list-tools

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/run.js --platform linkedin --list-tools

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/run.js --platform linkedin --list-tools

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/run.js --platform linkedin --list-tools

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/run.js --platform linkedin --list-tools

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/run.js --platform linkedin --list-tools

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/run.js --platform linkedin --list-tools

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/run.js (reported line 45)May include surrounding context.

js
const __dirname = dirname(fileURLToPath(import.meta.url));
const ROOT = resolve(__dirname, "..");

// ── .env loader ───────────────────────────────────────────────────────────────

(function loadDotenv() {
  const envPath = join(ROOT, ".env");

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/run.js (reported line 106)May include surrounding context.

js
const __dirname = dirname(fileURLToPath(import.meta.url));
const ROOT = resolve(__dirname, "..");

// ── .env loader ───────────────────────────────────────────────────────────────

(function loadDotenv() {
  const envPath = join(ROOT, ".env");

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/run.js (reported line 240)May include surrounding context.

js
const __dirname = dirname(fileURLToPath(import.meta.url));
const ROOT = resolve(__dirname, "..");

// ── .env loader ───────────────────────────────────────────────────────────────

(function loadDotenv() {
  const envPath = join(ROOT, ".env");

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/run.js (reported line 247)May include surrounding context.

js
const __dirname = dirname(fileURLToPath(import.meta.url));
const ROOT = resolve(__dirname, "..");

// ── .env loader ───────────────────────────────────────────────────────────────

(function loadDotenv() {
  const envPath = join(ROOT, ".env");

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/run.js (reported line 48)May include surrounding context.

js
// ── .env loader ───────────────────────────────────────────────────────────────

(function loadDotenv() {
  const envPath = join(ROOT, ".env");
  if (!existsSync(envPath)) return;
  for (const line of readFileSync(envPath, "utf8").split("\n")) {
    const m = line.match(/^\s*([A-Z_][A-Z0-9_]*)\s*=\s*(.*)$/);

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/run.js (reported line 248)May include surrounding context.

js
// ── .env loader ───────────────────────────────────────────────────────────────

(function loadDotenv() {
  const envPath = join(ROOT, ".env");
  if (!existsSync(envPath)) return;
  for (const line of readFileSync(envPath, "utf8").split("\n")) {
    const m = line.match(/^\s*([A-Z_][A-Z0-9_]*)\s*=\s*(.*)$/);

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

This code persists the entered KEYAPI_TOKEN into a plaintext .env file in the project root, creating a durable local credential artifact. In the context of a distributable skill, that is more dangerous because users may run it inside shared workspaces or repositories where the secret can be discovered, backed up, or committed unintentionally.

Content

Scanner excerpt · scripts/run.js (reported line 262)May include surrounding context.

js
reject(new Error("No token entered. Set KEYAPI_TOKEN and try again."));
        return;
      }
      const envPath = join(ROOT, ".env");
      writeFileSync(envPath, `KEYAPI_TOKEN=${token}\n`, "utf8");
      log(`[token] Saved to ${envPath} — future runs will load it automatically`);
      process.env.KEYAPI_TOKEN = token;

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill requires access to an environment secret (KEYAPI_TOKEN) but does not declare any explicit tool scope or allowed-tools boundary. That weakens least-privilege controls and makes it harder for a host or reviewer to determine what the skill is permitted to access, increasing the chance of unintended secret exposure or broader execution than users expect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill description does not clearly warn that company identifiers, queries, and retrieved LinkedIn data are sent to a third-party service (mcp.keyapi.ai). This creates a data handling and privacy risk because users may provide sensitive research targets or use the skill in regulated environments without understanding that the data leaves the local system.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill caches API responses on local disk under .keyapi-cache/ without surfacing that behavior in the user-facing description. Cached responses may contain sensitive company research, employee/job data, or other operational artifacts, which can be exposed to other local users, backups, or later processes if retention and file permissions are not controlled.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This runner is a generic KeyAPI MCP client that can invoke arbitrary server tools with caller-supplied parameters, pagination, schema inspection, and caching, which materially exceeds the declared LinkedIn company analysis scope. In a skill ecosystem, this kind of scope mismatch is dangerous because users and reviewers may trust the manifest while the code actually enables broader data access and capability use.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The CLI accepts an arbitrary --platform value and builds the server URL dynamically, allowing use against unrelated platforms such as TikTok or YouTube despite the skill being presented as LinkedIn company analysis. This expands the attack surface and enables capability drift beyond the user-approved context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

When the token is entered interactively, the script writes it directly to a plaintext .env file for future reuse without an explicit security warning or permission hardening. Persisting credentials in plaintext within the skill directory raises the risk of accidental commit, local theft, or exposure to other processes/users.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.