Back to skill

Security audit

Personal Data Hub

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent personal-data gateway purpose, but it automatically handles durable credentials and setup in ways users should review carefully before installing.

Review this before installing. It is meant to access personal data through PersonalDataHub, so some credential and network use is expected, but installation currently bootstraps services automatically, stores/reads a durable local API key, may log a full newly created key, and accepts hub URLs without clear trust boundaries. Prefer installing only in a controlled environment, with a trusted pinned PersonalDataHub CLI, validated localhost or HTTPS hub URL, and rotated keys if any logs may have captured credentials.

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
src/index.ts:108
Finding

Bearer API Key Is Written to Application Logs

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
src/hub-client.ts:48
Finding

Unvalidated Hub URL Can Receive Bearer Credentials and Sensitive Action Data

Content
View full analysis
{ const res = await fetch(`${this.hubUrl}/app/v1/pull`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${this.apiKey}`, }, body: JSON.stringify(params), }); if (!res.ok) { const text = await res.text(); throw new HubApiError('pull', res.status, text); } return res.json() as Promise; } async propose(params: ProposeParams): Promise { const res = await fetch(`${this.hubUrl}/app/v1/propose`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${this.apiKey}`, }, body: JSON.stringify(params), }); if (!res.ok) { const text = await res.text(); throw new HubApiError('propose', res ...[truncated 2058 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Error
Location
SKILL.md:9
Finding

Install Hook Executes Unpinned Registry Tool and Broad Parent-Workspace Scripts

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/setup.test.ts:133
Finding

Test Suite Reads the User's Real PersonalDataHub Credential File

Content
View full analysis
{ it('returns credentials from file or null without throwing', () => { // This test just verifies readCredentials doesn't throw const creds = readCredentials(); expect(creds === null || (typeof creds === 'object' && !!creds.hubUrl && !!creds.apiKey)).toBe(true); }); it('exports CREDENTIALS_PATH', () => { expect(CREDENTIALS_PATH).toContain('.pdh'); expect(CREDENTIALS_PATH).toContain('credentials.json'); }); }); ``` The tested implementation accesses the real home-directory path: ```ts export const CREDENTIALS_PATH = join(homedir(), '.pdh', 'credentials.json'); export function readCredentials(): Credentials | null { try { if (!existsSync(CREDENTIALS_PATH)) return null; const raw = readFileSync(CREDENTIALS_PATH, 'utf-8'); const parsed = JSON.parse(raw); if (parsed.hubUrl && parsed.apiKey) return parsed as Credentials; return null; } catch { return null; } } ``` ### Technical Analysis The test directly invokes `readCredentials()` without mocking the filesystem, overriding the home directory, or injecting a temporary credential path. On a developer or CI host with PersonalDataHub configured, the real bearer API key is read and parsed inside the test process. The assertion does not print the key, and network calls in the setup test are mocked. Therefore, the code does not by itself confirm network exfiltration. Nevertheless, reading a production credential is unnecessary for verifying parser behavior and exposes it to the test runtime, diagnostic tooling, instrumentation, and all dependencies loaded into that process. ### Attack Path 1. A developer or CI worker has a real `~/.pdh/credentials.json`. 2. The test suite runs under that user's home directory. 3. ...[truncated 591 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (41)

Tp4

High
Category
MCP Tool Poisoning
Confidence
83% confidence
Finding

This skill instructs reading a local credential file and performing local service checks/startup, while presenting itself primarily as a filtered gateway for personal data. In a personal-data context, undisclosed credential access and provisioning behavior materially increase risk because the agent may obtain reusable secrets and operational control over the hub.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

This skill instructs reading a local credential file and performing local service checks/startup, while presenting itself primarily as a filtered gateway for personal data. In a personal-data context, undisclosed credential access and provisioning behavior materially increase risk because the agent may obtain reusable secrets and operational control over the hub.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

This skill instructs reading a local credential file and performing local service checks/startup, while presenting itself primarily as a filtered gateway for personal data. In a personal-data context, undisclosed credential access and provisioning behavior materially increase risk because the agent may obtain reusable secrets and operational control over the hub.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

This skill instructs reading a local credential file and performing local service checks/startup, while presenting itself primarily as a filtered gateway for personal data. In a personal-data context, undisclosed credential access and provisioning behavior materially increase risk because the agent may obtain reusable secrets and operational control over the hub.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

This skill instructs reading a local credential file and performing local service checks/startup, while presenting itself primarily as a filtered gateway for personal data. In a personal-data context, undisclosed credential access and provisioning behavior materially increase risk because the agent may obtain reusable secrets and operational control over the hub.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
96% confidence
Finding

Reading ~/.pdh/credentials.json exposes a reusable API key and service location to the agent. In a personal-data skill, that credential can enable broad access to email, GitHub-connected data, or staged outbound actions, making compromise or misuse particularly damaging.

Content

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

If the tools above are not available, you can call the PersonalDataHub API directly via HTTP.

Credentials: Read ~/.pdh/credentials.json to get hubUrl and apiKey.

Pull data:

bash

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The troubleshooting flow instructs reading the credentials file to discover hubDir, exposing internal paths and potentially the same credential material during a support operation. This expands secret exposure into a path that users or agents may treat as low risk, increasing the chance of accidental leakage.

Content

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

If the server is not running, find and start it:

bash
# Check where PersonalDataHub is installed
cat ~/.pdh/credentials.json   # look at hubDir
# Start the server
cd <hubDir> && node dist/index.js

Credential Access

High
Category
Privilege Escalation
Confidence
94% confidence
Finding

The install flow creates an API key and saves it to a predictable plaintext location in the user's home directory. Predictable, file-based secret storage raises the risk of unintended access by other tools, agents, or local malware, especially when the key grants access to sensitive personal-data workflows.

Content

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

md
The install hook bootstraps PersonalDataHub automatically:
1. Installs dependencies, builds the project, initializes the database
2. Creates an API key and saves it to `~/.pdh/credentials.json`
3. Starts the server in the background

After installation, open `http://localhost:3000` to connect Gmail/GitHub via OAuth.

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

The statement that agents read credentials automatically from ~/.pdh/credentials.json normalizes silent secret access by the skill. In context, this is more dangerous because the skill handles personal communications and outbound actions, so the credential can be used to access or stage highly sensitive operations without fresh user awareness.

Content

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

md
After installation, open `http://localhost:3000` to connect Gmail/GitHub via OAuth.

Agents read credentials automatically from `~/.pdh/credentials.json` — no manual configuration needed.

## Query Syntax (Gmail)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · src/index.test.ts (reported line 3)May include surrounding context.

ts
import { describe, it, expect, vi, afterEach } from 'vitest';

// Mock readCredentials so tests don't depend on real ~/.pdh/credentials.json
vi.mock('./setup.js', async (importOriginal) => {
  const actual = await importOriginal() as Record<string, unknown>;
  return {

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · src/index.ts (reported line 10)May include surrounding context.

ts
import { describe, it, expect, vi, afterEach } from 'vitest';

// Mock readCredentials so tests don't depend on real ~/.pdh/credentials.json
vi.mock('./setup.js', async (importOriginal) => {
  const actual = await importOriginal() as Record<string, unknown>;
  return {

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · src/setup.test.ts (reported line 142)May include surrounding context.

ts
import { describe, it, expect, vi, afterEach } from 'vitest';

// Mock readCredentials so tests don't depend on real ~/.pdh/credentials.json
vi.mock('./setup.js', async (importOriginal) => {
  const actual = await importOriginal() as Record<string, unknown>;
  return {

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The skill reads a local credentials file to obtain authentication material, which is a credential-access capability beyond simple data retrieval. In this skill's context, that is more dangerous because the plugin handles personal data and can silently bootstrap privileged access using local secrets the operator may not expect it to consume.

Content

Scanner excerpt · src/index.ts (reported line 81)May include surrounding context.

ts
}
    }

    // Step 3: Check credentials file (~/.pdh/credentials.json)
    if (!config?.hubUrl || !config?.apiKey) {
      const creds = readCredentials();
      if (creds) {

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The code logs a newly created API key in plaintext, which can expose the credential to log files, consoles, telemetry pipelines, and other users on the host. Anyone who obtains those logs may be able to authenticate to the PersonalDataHub and access or manipulate personal data.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill looks for persistent credentials in the user's home directory and is documented to participate in self-enrollment, neither of which is justified by the stated role of proposing actions through a preexisting gateway. In skill contexts handling personal data, automatic credential discovery is especially risky because it enables silent access to sensitive systems without explicit user approval at runtime.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
92% confidence
Finding

This code targets a known credential file location in the user's home directory, enabling the skill to obtain an API key for the PersonalDataHub without separate authorization in this flow. Because the hub governs personal emails and issues, access to this secret can expose sensitive data and enable downstream actions under the user's authority.

Content

Scanner excerpt · src/setup.ts (reported line 31)May include surrounding context.

ts
}

/** Path to the credentials file written by `npx pdh init`. */
export const CREDENTIALS_PATH = join(homedir(), '.pdh', 'credentials.json');

/**
 * Read credentials from ~/.pdh/credentials.json.

Credential Access

High
Category
Privilege Escalation
Confidence
92% confidence
Finding

The readCredentials function operationalizes credential access by loading and parsing the persistent credentials file, making the secret directly consumable by the skill. In this context, that materially increases the skill's ability to access personal-data infrastructure outside of a tightly controlled, user-mediated flow.

Content

Scanner excerpt · src/setup.ts (reported line 34)May include surrounding context.

ts
export const CREDENTIALS_PATH = join(homedir(), '.pdh', 'credentials.json');

/**
 * Read credentials from ~/.pdh/credentials.json.
 * Returns null if the file doesn't exist or is malformed.
 */
export function readCredentials(): Credentials | null {

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The file implements autonomous discovery of a local PersonalDataHub and creates a fresh API key for the skill, which materially expands the skill's privileges beyond merely consuming gateway-filtered data. In the context of a skill whose stated purpose is data access through an existing access-control gateway, self-enrollment and credential minting are dangerous because they bypass expected provisioning controls and can silently grant the skill durable access.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
85% confidence
Finding

The skill declares no explicit tool scope while its documented behavior includes network access and reading local files for credentials. That increases the chance an agent is granted broader capabilities than users expect, especially in a skill handling personal data and API keys.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
93% confidence
Finding

Using npx pdh without pinning a version allows execution of whatever package version resolves at install time. This creates a supply-chain risk where a malicious or compromised package release could execute arbitrary code during installation or startup.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The direct HTTP fallback transmits authorization credentials and personal-data requests, but the documentation provides no explicit privacy or transport-security guidance. In a skill centered on sensitive personal data, omitting such warnings can lead to insecure deployment, accidental logging, or use of non-TLS endpoints.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill explicitly instructs agents to read ~/.pdh/credentials.json to obtain hubUrl and apiKey without a strong warning or consent gate. Access to local credential files gives the agent reusable secrets that could be abused for unauthorized data access or service actions beyond the immediate user request.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
74% confidence
Finding

The skill is designed to send data over HTTP to a hub service, so external transmission is expected, but it still represents a real security concern because personal data and bearer tokens are being sent across a network boundary. The context makes this behavior necessary, not harmless; its safety depends on strict transport security and endpoint trust.

Content

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

Pull data:

bash
curl -X POST <hubUrl>/app/v1/pull \
  -H "Authorization: Bearer <apiKey>" \
  -H "Content-Type: application/json" \
  -d '{"source": "gmail", "purpose": "reason for pulling data"}'

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.