Back to skill

Security audit

Bluesky

Security checks for vulnerabilities and agentic risk

Overview

This Bluesky skill is purpose-aligned but needs review because it can authenticate and perform public account actions without clearly documented confirmation or tight endpoint/dependency controls.

Install only for a Bluesky account where an agent is allowed to post, reply, upload media, bookmark, and potentially change engagement state. Use a revocable app password, verify BSKY_PDS is a trusted HTTPS endpoint, add your own confirmation step before public writes, and consider pinning the atproto dependency before production use.

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

T08 · Insecure Dependencies

Warning
Location
SKILL.md:13
Finding
Unpinned AT Protocol Dependency Creates a Supply-Chain Risk## Vulnerability Details **File Location**: `SKILL.md:13-16` **Vulnerability Type**: Unpinned third-party dependency **Risk Level**: Medium **Vulnerable Code**: ```json { "id": "python-atproto", "kind": "pip", "package": "atproto", "label": "Install AT Protocol Python SDK" } ``` The setup instructions at `SKILL.md:35` also use an unpinned installation command: ```bash pip install atproto ``` ### Technical Analysis The Skill installs `atproto` without specifying a reviewed version, lock file, or package integrity hash. Consequently, installation resolves whichever compatible package and transitive dependencies are available from the configured Python package index at installation time. This does not establish that the current `atproto` package is malicious. However, it makes the audited artifact non-reproducible and allows its effective executable dependency set to change after review. A compromised future release, compromised package-index account, or malicious package served through an unsafe package-index configuration could execute installation or import-time code with the privileges of the Agent process. Because `lib/bluesky_agent.py` imports this dependency directly, malicious code in the package could run when the module is imported: ```python from atproto import Client, client_utils, models ``` ### Attack Path 1. An attacker compromises the upstream package, a transitive dependency, a package publisher account, or the package index used by the deployment. 2. The attacker publishes or serves a malicious version that still satisfies the unrestricted `atproto` requirement. 3. A user installs the Skill dependency with the declared installation configuration or `pip install atproto`. 4. The malicious package executes during installation or when `bluesky_agent.py` imports it. 5. The package acts with the permissions of the installation or Agent process and may access data available to t ...[truncated 530 chars]
Remediation
## Remediation Suggestions 1. Pin `atproto` to a specifically reviewed version, such as an exact `==` version rather than an unrestricted package name. 2. Generate and commit a lock file that fixes all transitive dependency versions. 3. Require package hashes during installation, for example through a hash-locked requirements file and `pip install --require-hashes`. 4. Install only from an explicitly configured, trusted package index. 5. Use automated dependency monitoring, but review updates before modifying the pinned version. 6. Run dependency installation and the Skill with least privilege in an isolated virtual environment or container. 7. Record the reviewed package versions and hashes in the release documentation so installations are reproducible.

T09 · Insecure Skill Coding Practices

Warning
Location
lib/bluesky_agent.py:4
Finding
Authentication Credentials Can Be Sent to an Unvalidated PDS Endpoint## Vulnerability Details **File Location**: `lib/bluesky_agent.py:4-9` **Vulnerability Type**: Insufficient validation of a credential-receiving network destination **Risk Level**: Medium **Vulnerable Code**: ```python class BlueskyAgent: def __init__(self, pds_url="https://bsky.social"): self.client = Client(base_url=pds_url) def login(self, identifier, app_password): """Authenticates using an App Password.""" self.client.login(identifier, app_password) return self.client.get_profile(actor=identifier) ``` ### Technical Analysis The constructor accepts an unrestricted `pds_url` and passes it directly to the third-party AT Protocol client. The `login` method subsequently supplies the account identifier and app password to that client. The Skill does not independently verify that the endpoint uses HTTPS, belongs to an intended PDS, or has been explicitly approved before authentication. The documented default, `https://bsky.social`, is an expected HTTPS destination. Custom PDS support can also be legitimate. The vulnerability arises because configuration tampering or user error can change the destination without a scheme restriction, host allowlist, or confirmation boundary. If the underlying SDK accepts a cleartext or attacker-controlled URL, credentials could be disclosed to that endpoint. No hardcoded credential or direct credential logging was found. The risk is specifically the absence of destination validation before forwarding authentication material. ### Attack Path 1. An attacker gains influence over the value passed as `pds_url`, such as by modifying deployment configuration or persuading an operator to use a malicious custom PDS. 2. The Agent constructs `BlueskyAgent` with the attacker-controlled endpoint. 3. The user or orchestration layer calls `login(identifier, app_password)`. 4. The AT Protocol client sends an authentication request to the configured destinat ...[truncated 858 chars]
Remediation
## Remediation Suggestions 1. Parse `pds_url` before constructing the client and reject every scheme other than `https`. 2. Reject URLs containing embedded user information, malformed hostnames, unexpected fragments, or ambiguous encodings. 3. Use an allowlist containing `bsky.social` when custom PDS operation is not required. 4. If custom PDS instances are required, maintain an explicit trusted-host configuration and require operator confirmation before credentials are sent to a new host. 5. Consider blocking loopback, link-local, and private-network destinations unless local PDS access is an intentional and documented deployment mode. 6. Preserve TLS certificate verification and do not expose options that silently disable it. 7. Display or log the selected PDS hostname before authentication without ever logging the app password. 8. Document immediate app-password revocation and rotation procedures for suspected endpoint misconfiguration.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (7)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The skill documentation and declared capabilities do not fully align with the described behavior, especially around authentication, profile retrieval, and handle resolution. In an authenticated social-media skill, such mismatches can mislead users and reviewers about what account actions occur and what data is accessed, reducing informed consent and making unsafe use more likely.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
This skill can perform authenticated write actions on a user's Bluesky account, but the description does not clearly warn users that invoking it may post, reply, like, repost, bookmark, or otherwise modify account state. That omission increases the risk of unintended account actions and weakens user awareness in a sensitive authenticated context.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill transmits user-provided text, metadata, and potentially media uploads to external Bluesky/AT Protocol services, but it does not prominently disclose that privacy implication. In a social-posting skill, undisclosed outbound transmission can expose sensitive content or files to third-party infrastructure and public posting surfaces.

Missing User Warnings

Medium
Confidence
83% confidence
Finding
The login method accepts an identifier and app password and immediately authenticates with the remote Bluesky service. While the docstring notes that an app password is used, there is no confirmation prompt, visible logging/print, or other user-facing disclosure in the code about transmitting credentials to an external service.

Cloud Storage Exfiltration

Medium
Category
Data Exfiltration
Content
def upload_image(self, image_bytes, alt_text, mimetype="image/jpeg"):
        """Uploads an image blob and returns the reference."""
        return self.client.upload_blob(image_bytes, encoding=mimetype)

    def bookmark(self, uri, cid):
        """Private bookmarking."""
Confidence
55% confidence
Finding
Data is uploaded to cloud storage (S3 / GCS / Azure Blob). This may be a legitimate backup or exfiltration to an external bucket. Manual review is recommended.

Missing User Warnings

Low
Confidence
71% confidence
Finding
The post method transmits provided text and reply metadata to a remote service via send_post. The code contains no confirmation prompt, print/log disclosure, or inline comment/docstring warning that user content will be published externally.

Missing User Warnings

Low
Confidence
76% confidence
Finding
The upload_image method uploads raw image bytes to Bluesky using upload_blob. Although the docstring says it uploads an image blob, there is no user-facing disclosure or confirmation indicating that local content will be sent to an external network service.

Static analysis

No suspicious patterns detected.