Back to skill

Security audit

NotaryOS

Security checks for vulnerabilities and agentic risk

Overview

This skill is not clearly malicious, but it sends action payloads to an external service while overstating how well its sanitizer protects sensitive data.

Review before installing. Only use this skill if you are comfortable sending selected action payloads and metadata to NotaryOS, and do not rely on the included sanitizer as a full privacy control. Prefer manually allowlisting safe receipt fields, avoid raw message bodies, file contents, credentials, auth headers, health or financial data, and consider pinning/auditing the notaryos SDK version before 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)

T09 · Insecure Skill Coding Practices

Error
Location
sanitize.py:34
Finding
Incomplete denylist sanitizer can transmit sensitive payload data## Vulnerability Details **File Location**: `sanitize.py:34-86` **Vulnerability Type**: Sensitive data exposure caused by incomplete input sanitization **Risk Level**: High The documentation instructs users to sanitize payloads before transmitting them to the NotaryOS API and states that the helper automatically handles message bodies, file contents, health information, credentials, and financial information. The implementation only recognizes a limited set of sensitive field names and substrings. **Vulnerable code:** ```python # Field names that are stripped (case-insensitive exact match). _BLOCKED_FIELDS: Set[str] = { "passwd", "bearer", "credentials", "private_key", "signing_key", "cvv", "cvc", "expiry", "account_number", "routing_number", "iban", "swift", "bank_account", "ssn", "social_security", "national_id", "passport_number", "drivers_license", "dob", "date_of_birth", } # Substrings in field names that indicate sensitivity. _BLOCKED_SUBSTRINGS = ( "password", "secret", "token", "credential", "api_key", "apikey", ) def sanitize_payload( payload: Dict[str, Any], extra_fields: Optional[Set[str]] = None, redact: bool = False, ) -> Dict[str, Any]: """ Remove sensitive fields from a payload dict. Args: payload: Raw dict to sanitize. extra_fields: Additional field names to strip. redact: If True, replace values with "[REDACTED]" instead of removing. Returns: New dict with sensitive fields removed. Original is not modified. """ blocked = _BLOCKED_FIELDS | (extra_fields or set()) result: Dict[str, Any] = {} for key, value in payload.items(): lower = key.lower() if lower in blocked or any(p in lower for p in _BLOCKED_SUBSTRINGS): if redact: result[key] = "[REDACTED]" continue if isinstanc ...[truncated 2809 chars]
Remediation
## Remediation Suggestions 1. Replace the denylist-only approach with action-specific allowlists. Only documented, non-sensitive metadata such as public identifiers, counts, timestamps, and approved paths should be retained. 2. Explicitly block all sensitive fields identified in the documentation, including message-body, file-content, health-data, authorization-header, cookie, session, and payment-card variants. 3. Normalize `extra_fields` to lowercase before comparison so custom filtering remains case-insensitive. 4. Recursively inspect all supported containers, including nested lists and tuples. Reject unsupported object types rather than copying them unchanged. 5. Consider rejecting payloads that contain unapproved keys instead of attempting to infer sensitivity from their names. 6. Add unit tests for `body`, `content`, `file_content`, `authorization`, `cookie`, `card_number`, health-data fields, mixed-case field names, and sensitive scalar list entries. 7. Revise the documentation to describe the filter as best-effort unless comprehensive enforcement is implemented. Require explicit user approval before transmitting payloads that may contain user data.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:10
Finding
Unpinned third-party SDK installation creates a supply-chain risk## Vulnerability Details **File Location**: `SKILL.md:10-15` and `SKILL.md:59-62` **Vulnerability Type**: Unpinned executable dependency **Risk Level**: Medium The skill installs the `notaryos` package without an exact version constraint or an integrity hash. **Vulnerable installation manifest:** ```yaml files: - "sanitize.py" install: - kind: uv package: notaryos bins: [] ``` **Vulnerable manual installation instruction:** ```bash pip install notaryos ``` ### Technical Analysis Both installation mechanisms resolve the latest package version available from the configured package index. The effective SDK code is therefore external to the audited project and can change after this skill has been reviewed. An exact package version, lock file, artifact hash, or included audited SDK source is not provided. Consequently, installation is not reproducible and cannot guarantee that users receive the version intended by the skill author. This finding establishes an unsafe dependency-management condition; it does not establish that the current `notaryos` package is malicious. ### Attack Path 1. The upstream publisher account, package repository, release process, or package-index delivery path is compromised, or a future release introduces malicious behavior. 2. A user installs the skill or runs `pip install notaryos`. 3. The package manager resolves and installs the compromised or unsafe latest release because no exact version is required. 4. The workflow imports and invokes that package through `NotaryClient`. 5. Malicious package code executes with the permissions of the Python process and can alter payload handling, contact undisclosed endpoints, or access resources available to that user. Exploitation depends on compromise or unsafe modification of the external dependency; no such compromise was demonstrated in the audited files. ### Impact Assessment A malicious dependency could execu ...[truncated 452 chars]
Remediation
## Remediation Suggestions 1. Pin the SDK to an exact version in both the installation manifest and user-facing command, such as `notaryos==X.Y.Z`, after auditing that release. 2. Use a lock file with cryptographic hashes or install from a verified immutable artifact. 3. Ensure the declared skill version and audited SDK version are maintained together through a controlled update process. 4. Review the dependency source before each upgrade and automate dependency provenance and vulnerability checks. 5. Where feasible, vendor the minimal required SDK code or include its audited source in the artifact. 6. Independently enforce an allowlist of permitted network destinations so a modified SDK cannot silently contact arbitrary endpoints. 7. Run the SDK with least privilege and avoid exposing unrelated environment variables, files, or credentials to its process.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (4)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill claims to provide cryptographic sealing, verification, and proof of omitted actions, but the described local file content mainly supplies documentation and a sanitization helper while delegating core security guarantees to a remote SDK/service. This mismatch can cause operators to rely on security properties that are not implemented or auditable within the skill itself, creating false assurance around integrity, non-repudiation, and privacy.

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill advertises shell-related usage and installation behavior but does not declare an explicit tool scope such as allowed-tools or permissions. In an agent environment, missing scope declarations weaken policy enforcement and can let a seemingly documentation-only skill be used alongside shell execution without clear guardrails or user consent.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The documentation says there is no telemetry, analytics, or tracking, yet it also states that action metadata and sometimes raw payloads are transmitted to a remote API. That contradiction can mislead users into disclosing sensitive operational data under a false privacy expectation, especially because the skill recommends sealing commands, config changes, and access events.

Context-Inappropriate Capability

Medium
Confidence
92% confidence
Finding
The manifest description frames the skill as a narrowly scoped cryptographic receipt tool for agent actions. However, the guidance explicitly normalizes use on high-risk operational and sensitive contexts such as shell commands, system configuration, data access, email, and API calls, which are not necessary to justify the core sealing/verification purpose and expand the skill into broad activity logging of sensitive operations.

Static analysis

No suspicious patterns detected.