Back to skill

Security audit

Pinboard Manager

Security checks for vulnerabilities and agentic risk

Overview

This Pinboard management skill is mostly purpose-aligned, but it handles sensitive bookmark data and account-changing actions with several under-scoped privacy and safety risks.

Install only if you are comfortable giving the agent Pinboard API authority to read, modify, and delete bookmarks. Before running dead-link or timeliness modes, review the URL set, exclude private/internal/signed URLs, avoid bulk deletion without an export backup, and treat /tmp/pinboard_all.json as sensitive data that should be stored in a private per-user location instead.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (4)

T09 · Insecure Skill Coding Practices

Warning
Location
references/timeliness.md:61
Finding
Bookmark URLs Disclosed to a Third-Party Content Service Without Explicit Per-Use Consent<![CDATA[ ## Vulnerability Details **File Location**: `references/timeliness.md:61-67` **Vulnerability Type**: Third-party disclosure of potentially sensitive bookmark URLs **Risk Level**: Medium ### Vulnerable Code ```bash ## Step 3: Content fetching via Jina Reader For each candidate, fetch content using Jina Reader: CONTENT=$(curl -s "https://r.jina.ai/BOOKMARK_URL" | head -c 5000) sleep 2 # Rate limiting between requests ``` ### Technical Analysis The timeliness workflow embeds each selected bookmark URL into a request to the external Jina Reader service. Consequently, Jina receives the complete bookmark URL and is instructed to retrieve its target. Bookmark URLs may contain sensitive information, including: - Private interests or browsing history - Internal hostnames and network topology - Unlisted document or repository identifiers - Authentication tokens, signed parameters, or session data in query strings - Customer, project, or account identifiers - URLs pointing to resources that users did not intend to disclose to Jina The Skill explains that it uses Jina Reader, but it does not require explicit confirmation immediately before sending the selected URLs. It also does not screen out private addresses, authenticated URLs, signed URLs, or URLs containing query strings. The third-party request is not strictly necessary for all timeliness checks. Local content retrieval or analysis based only on existing bookmark metadata would require less disclosure and would better follow the principle of minimum privilege. ### Attack Path 1. A user stores a sensitive or unlisted URL in Pinboard. 2. The bookmark has a technology-related tag and satisfies the age or version-number filter. 3. The Skill selects the bookmark as a timeliness-analysis candidate. 4. The Skill constructs a request to `https://r.jina.ai/BOOKMARK_URL`. 5. Jina receives the full URL and attempts to retrieve the referenced resource. 6. Jina or its infrastructure can log the URL, associ ...[truncated 651 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Display the exact candidate URLs before submitting them to Jina Reader and obtain explicit opt-in confirmation. 2. Make local retrieval and local analysis the default; use Jina only when the user specifically enables third-party processing. 3. Reject or redact URLs containing query strings, fragments, user information, signed parameters, or apparent secrets. 4. Exclude localhost, private-network, link-local, internal-domain, and non-HTTP(S) URLs. 5. Clearly document what data Jina receives, why it is needed, and the relevant retention or privacy implications. 6. Allow users to approve URLs individually rather than approving the entire candidate set. 7. Avoid transmitting credentials embedded in URLs under all circumstances. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
references/dead-link.md:9
Finding
Arbitrary Bookmark Fetching Permits Server-Side Request Forgery Against Local and Internal Services<![CDATA[ ## Vulnerability Details **File Location**: `references/dead-link.md:9-29` **Vulnerability Type**: Unrestricted URL fetching and redirect following **Risk Level**: Medium ### Vulnerable Code ```bash ## Step 2: Check links in batches Process 10 URLs per batch using HTTP HEAD requests: # HEAD request with 10 second timeout HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" -L --max-redirs 5 -I -m 10 "URL") ``` Classification (based on final status after following redirects): | Status | Meaning | Action | |--------|---------|--------| | 2xx | Working | No action | | 403, 405 | HEAD rejected | Retry with GET | | 4xx (other) | Broken | Report to user | | 5xx | Server error | Report to user | | 000 | Timeout/unreachable | Report to user | For HEAD-rejected URLs, retry once with GET: ```bash HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" -L --max-redirs 5 -m 10 "URL") ``` ### Technical Analysis The dead-link checker performs HTTP requests against arbitrary URLs from the user's bookmark collection. It follows up to five redirects and does not validate the URL scheme, resolved address, or redirect destinations. A bookmark can therefore target or redirect to: - Loopback services such as `127.0.0.1` or `::1` - RFC1918 private networks - Link-local addresses - Cloud instance metadata endpoints such as `169.254.169.254` - Local administration panels or development services - Internal services reachable from the agent but not from an external attacker Although response bodies are discarded, HTTP status codes are returned and classified. This creates an internal-service probing channel. The GET fallback also creates a greater risk than HEAD because some poorly designed endpoints perform state-changing operations in response to GET requests. The use of `-L` makes validation of only the initial bookmark URL insufficient: an apparently public URL may redirect to a restricted destination. ### Attack Path 1. An attacker causes a crafted URL to app ...[truncated 1158 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Allow only explicit `http` and `https` schemes. 2. Resolve the destination hostname before each request and reject loopback, private, link-local, multicast, unspecified, and reserved address ranges for both IPv4 and IPv6. 3. Explicitly block common cloud metadata destinations, including `169.254.169.254`. 4. Disable automatic redirects or validate every redirect target before following it. 5. Re-resolve hostnames when processing redirects to mitigate DNS rebinding. 6. Prefer HEAD requests and require separate user approval before performing a GET fallback. 7. Do not report detailed internal status information for rejected or non-public destinations. 8. Apply an outbound network policy that restricts the process to public HTTP(S) destinations. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
references/tag-audit.md:5
Finding
Predictable Shared Temporary File Enables Symlink Overwrite, Cache Poisoning, and Bookmark Data Exposure<![CDATA[ ## Vulnerability Details **File Location**: `references/tag-audit.md:5-10` **Additional Locations**: `SKILL.md:107-111`, `references/timeliness.md:10-17` **Vulnerability Type**: Unsafe temporary-file handling **Risk Level**: Medium ### Vulnerable Code ```bash ## Step 1: Fetch all bookmarks curl -s "https://api.pinboard.in/v1/posts/all?auth_token=$PINBOARD_AUTH_TOKEN&format=json" > /tmp/pinboard_all.json ``` The timeliness workflow subsequently trusts the same fixed path: ```bash # Only fetch if cache doesn't exist or is stale if [ ! -f /tmp/pinboard_all.json ]; then curl -s "https://api.pinboard.in/v1/posts/all?auth_token=$PINBOARD_AUTH_TOKEN&format=json" > /tmp/pinboard_all.json fi ``` ### Technical Analysis The Skill uses the globally predictable path `/tmp/pinboard_all.json` for sensitive Pinboard data. It does not securely create the file, validate its owner, verify that it is a regular file, set restrictive permissions, or use a per-user directory. Shell output redirection follows symbolic links. A local attacker who can write to `/tmp` may create `/tmp/pinboard_all.json` as a symbolic link to another file writable by the Skill's user. When the Skill fetches bookmarks, the shell can overwrite the symlink target. A local attacker can also create a regular file at the expected location. The timeliness workflow checks only whether the file exists. Despite the comment referring to stale files, no age or integrity check is implemented. Attacker-supplied JSON may therefore be trusted as bookmark data and influence which URLs are fetched or which modifications are recommended. The cache may include bookmark URLs, titles, notes, tags, timestamps, and visibility-related fields. Depending on the process umask and operating-system configuration, this information may be accessible to other local users. ### Attack Path #### Symlink overwrite 1. A local attacker predicts the fixed path `/tmp/pinboard_all.json`. 2. The attacker creates a symbol ...[truncated 1445 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create a private temporary directory with `mktemp -d` rather than using a fixed global path. 2. Set `umask 077` before writing bookmark data. 3. Store the cache under a user-private runtime or cache directory with permissions set to `0700`. 4. Create files atomically and reject symbolic links. 5. Before reusing a cache, verify that it is a regular file owned by the current user and not writable by group or others. 6. Implement the stated cache-expiration policy by recording and validating the fetch time. 7. Validate the JSON structure and expected field types before using cached records. 8. Remove the cache at the end of the session unless the user explicitly opts into persistent caching. 9. Use a session-specific filename to prevent collisions between simultaneous runs. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
SKILL.md:68
Finding
Pinboard API Token and Private Bookmark Metadata Exposed Through Command-Line Query Parameters<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:68-91` **Additional Locations**: `references/tag-audit.md:49-54`, `references/dead-link.md:59-63`, `references/timeliness.md:121-133`, `references/user-config.md:26-31` **Vulnerability Type**: Sensitive information placed in process arguments and URL query parameters **Risk Level**: Low ### Vulnerable Code ```bash # Fetch all bookmarks curl -s "https://api.pinboard.in/v1/posts/all?auth_token=$PINBOARD_AUTH_TOKEN&format=json" # Fetch bookmarks with toread=yes curl -s "https://api.pinboard.in/v1/posts/all?auth_token=$PINBOARD_AUTH_TOKEN&format=json&toread=yes" # Fetch a specific bookmark by URL curl -s "https://api.pinboard.in/v1/posts/get?auth_token=$PINBOARD_AUTH_TOKEN&format=json&url=ENCODED_URL" ``` ```bash curl -s "https://api.pinboard.in/v1/posts/add?auth_token=$PINBOARD_AUTH_TOKEN&format=json&url=ENCODED_URL&description=ENCODED_TITLE&extended=ENCODED_NOTES&tags=ENCODED_TAGS&shared=ORIGINAL_SHARED&toread=ORIGINAL_TOREAD&replace=yes" ``` ```bash curl -s "https://api.pinboard.in/v1/posts/delete?auth_token=$PINBOARD_AUTH_TOKEN&format=json&url=ENCODED_URL" ``` ### Technical Analysis The Pinboard API requires the authentication token as a query parameter, but the documented implementation constructs the complete request URL directly in the `curl` command line. Once the shell expands the environment variable, the process argument can contain: - The Pinboard API token - Private bookmark URLs - Bookmark titles - Bookmark notes - Tags and visibility metadata HTTPS encrypts this information in transit, but it does not protect the expanded command line from local process inspection. Depending on the operating system and process-monitoring configuration, other local users, diagnostic tools, endpoint-monitoring products, shell tracing, or crash reports may capture the arguments. Query parameters may also be retained by URL-aware logging infrastructure. The Skill acknowledges that the token is a ...[truncated 996 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Avoid placing the expanded token and bookmark metadata directly in command-line arguments. 2. Use a protected curl configuration supplied through standard input or a securely created file so sensitive values are not present in the process argument vector. 3. Set restrictive permissions on any temporary curl configuration and delete it immediately after use. 4. Disable shell tracing before processing credentials and ensure expanded commands are never printed. 5. Redact authentication query parameters and bookmark metadata from application, proxy, and diagnostic logs. 6. Keep requests short-lived and rotate the Pinboard token immediately if process arguments or logs may have been exposed. 7. Document the residual risk if Pinboard does not provide an authentication mechanism that avoids query parameters. 8. Verify update responses and apply user confirmation before every destructive or account-modifying operation. ]]>
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 (18)

Vague Triggers

High
Confidence
97% confidence
Finding
The skill is scoped as the default for essentially any Pinboard-related request, including broad phrases like 'manage their Pinboard account in any way' and 'invoke immediately.' Overly broad activation increases the chance the agent will invoke a capability-bearing skill in contexts the user did not clearly intend, expanding exposure to account-wide read, update, and delete operations.

External Transmission

Medium
Category
Data Exfiltration
Content
**CRITICAL**: Always pass ALL fields to avoid data loss. The `/posts/add` endpoint overwrites the entire bookmark.

```bash
curl -s "https://api.pinboard.in/v1/posts/add?auth_token=$PINBOARD_AUTH_TOKEN&format=json&url=ENCODED_URL&description=ENCODED_TITLE&extended=ENCODED_NOTES&tags=ENCODED_TAGS&shared=ORIGINAL_SHARED&toread=ORIGINAL_TOREAD&replace=yes"
```

Required fields to preserve:
Confidence
79% confidence
Finding
The update example places the authentication token directly in the URL query string while sending bookmark content externally. Query-string secrets can be exposed through shell history, process listings, logs, proxies, or error reporting, making credential leakage more likely even though the destination service is legitimate.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The document includes a direct bookmark deletion API call but does not state, in that section, that deletion requires explicit user confirmation or warn that it is destructive. In a skill that can operate over an entire bookmark corpus, omission of a clear confirmation guard raises the risk of accidental or over-broad deletion actions.

External Transmission

Medium
Category
Data Exfiltration
Content
### Delete a bookmark

```bash
curl -s "https://api.pinboard.in/v1/posts/delete?auth_token=$PINBOARD_AUTH_TOKEN&format=json&url=ENCODED_URL"
```

### Rate limiting
Confidence
82% confidence
Finding
The delete example also embeds the Pinboard auth token in the query string, compounding credential exposure risk for a destructive operation. If the token leaks, an attacker could read, modify, or delete the user's bookmarks through the Pinboard API.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The instructions direct the agent to probe every bookmarked URL with HEAD/GET requests but do not warn that this will generate outbound traffic to all saved sites. That can disclose the user's bookmark corpus to third parties, trigger tracking or rate limits, and contact internal or sensitive URLs if such bookmarks exist. In a bookmark-management skill, automatic network access is contextually relevant, but the lack of explicit user warning/confirmation still makes it risky.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The workflow includes permanent deletion through the Pinboard API but does not prominently warn that applying decisions will irreversibly remove bookmarks. Without an explicit confirmation step and clear notice of permanence, an agent could carry out destructive actions the user did not fully understand or intend. In this skill, deletion is a legitimate feature, but silent or weakly signaled destructive capability increases the chance of harmful mistakes.

External Transmission

Medium
Category
Data Exfiltration
Content
## Step 1: Fetch all bookmarks

```bash
curl -s "https://api.pinboard.in/v1/posts/all?auth_token=$PINBOARD_AUTH_TOKEN&format=json" > /tmp/pinboard_all.json
```

Parse the JSON and count total bookmarks.
Confidence
93% confidence
Finding
This skill instructs fetching the user's entire Pinboard bookmark corpus, including titles, URLs, notes, tags, and metadata, from an external service and storing it in a world-accessible temporary path under /tmp. Even though Pinboard is the intended service, this is still an external transmission of potentially sensitive user data and increases exposure through broad collection and insecure local handling.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# URL-encode all parameters
curl -s "https://api.pinboard.in/v1/posts/add?auth_token=$PINBOARD_AUTH_TOKEN&format=json&url=ENCODED_URL&description=ENCODED_TITLE&extended=ENCODED_NOTES&tags=NEW_TAGS&shared=ORIGINAL_SHARED&toread=ORIGINAL_TOREAD&replace=yes"
sleep 3  # Rate limit
```
Confidence
96% confidence
Finding
This step sends bookmark content back to Pinboard via a GET request containing the auth token, URL, title, notes, tags, and other metadata in the query string. Query parameters may be exposed in logs, shell history, process listings, proxies, or monitoring systems, so sensitive bookmark data and credentials can leak during normal operation.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
Line L005 states "All tags in English, lowercase," which imposes a language policy in natural language. Under the policy rules, forcing a specific language without user opt-in or a clearly documented justification is a reportable violation.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# Only fetch if cache doesn't exist or is stale
if [ ! -f /tmp/pinboard_all.json ]; then
  curl -s "https://api.pinboard.in/v1/posts/all?auth_token=$PINBOARD_AUTH_TOKEN&format=json" > /tmp/pinboard_all.json
fi
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# Only fetch if cache doesn't exist or is stale
if [ ! -f /tmp/pinboard_all.json ]; then
  curl -s "https://api.pinboard.in/v1/posts/all?auth_token=$PINBOARD_AUTH_TOKEN&format=json" > /tmp/pinboard_all.json
fi
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# Only fetch if cache doesn't exist or is stale
if [ ! -f /tmp/pinboard_all.json ]; then
  curl -s "https://api.pinboard.in/v1/posts/all?auth_token=$PINBOARD_AUTH_TOKEN&format=json" > /tmp/pinboard_all.json
fi
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# Only fetch if cache doesn't exist or is stale
if [ ! -f /tmp/pinboard_all.json ]; then
  curl -s "https://api.pinboard.in/v1/posts/all?auth_token=$PINBOARD_AUTH_TOKEN&format=json" > /tmp/pinboard_all.json
fi
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# Only fetch if cache doesn't exist or is stale
if [ ! -f /tmp/pinboard_all.json ]; then
  curl -s "https://api.pinboard.in/v1/posts/all?auth_token=$PINBOARD_AUTH_TOKEN&format=json" > /tmp/pinboard_all.json
fi
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# Only fetch if cache doesn't exist or is stale
if [ ! -f /tmp/pinboard_all.json ]; then
  curl -s "https://api.pinboard.in/v1/posts/all?auth_token=$PINBOARD_AUTH_TOKEN&format=json" > /tmp/pinboard_all.json
fi
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# Only fetch if cache doesn't exist or is stale
if [ ! -f /tmp/pinboard_all.json ]; then
  curl -s "https://api.pinboard.in/v1/posts/all?auth_token=$PINBOARD_AUTH_TOKEN&format=json" > /tmp/pinboard_all.json
fi
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# Only fetch if cache doesn't exist or is stale
if [ ! -f /tmp/pinboard_all.json ]; then
  curl -s "https://api.pinboard.in/v1/posts/all?auth_token=$PINBOARD_AUTH_TOKEN&format=json" > /tmp/pinboard_all.json
fi
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The skill sends each candidate bookmark URL to Jina Reader, a third-party service, and may also transmit page content derived from the user's private bookmark collection without any explicit privacy warning or consent gate. In the context of Pinboard management, bookmarked URLs can reveal sensitive interests, internal resources, work systems, or private notes context, so this data exposure is materially risky beyond normal API usage.

Static analysis

No suspicious patterns detected.