Versioned security assessment

Report ID: SA-F654828A

7/5/2026, 1:56:11 AM

tasknotes security assessment v7

Skill Security Certification Report

Audit History
Audit model: codex Historical report
Skill name
tasknotes
Version
v7
Maintainer
ArtemXTech
Coverage
2 Files scanned · 447 Lines analyzed
Policy version
Unavailable

Highest confirmed finding severity

High

2 confirmed security findings require attention.

Installation context

Historical evidence

This report may not describe the currently installable artifact. Open the current Skill page for install guidance.

Open current Skill page

This report does not block or authorize the manifest or ZIP.

The skill is a legitimate Obsidian TaskNotes CLI, but it has real security surface: it loads a vault-root .env, reads API credentials, and sends HTTP requests to a local API that can create, update, and delete tasks. Most markdown backtick detections are false positives, and no prompt injection text was found. The main unresolved risk is unvalidated TASKNOTES_API_PORT, which can affect the parsed request host when an Authorization header is present.

Report position

Historical report

Open audit history before using this report to install.

Audit attestation

Not attestable

The required immutable binding is incomplete.

Human verification

Not verified

No human verification is recorded for this report.

Coverage

2 Files scanned · 447 Lines analyzed

25 items shown for review

Limitations

This report does not claim runtime or sandbox execution and does not prove the absence of side effects.

Evidence chain

Follow the evidence from source binding to the install contract. Available evidence supports verification; it is not a safety guarantee.

  1. Source

    Binding unavailable

  2. Artifact

    Identity incomplete

  3. Audit

    Complete

  4. Install contract

    Open manifest to verify

    Open manifest

Capabilities observed

Observed means this report recorded supporting evidence. Not recorded does not prove that a capability is absent.

Contains scripts

May execute code included with the Skill.

Not recorded by this audit

Network access

May connect to external services.

Observed in 12 evidence locations

Filesystem access

May read or write local files.

Not recorded by this audit

Env variables

May read values from the process environment.

Observed in 9 evidence locations

External commands

May invoke commands or programs outside the Skill.

Observed in 26 evidence locations

Capability review items (23)
High
dotenv library
load_dotenv(VAULT_ROOT / ".env")
The script loads a .env file from the vault root before making API requests. This is intended configuration, but it broadens access to local secret material.
High
Python dotenv loader
load_dotenv(VAULT_ROOT / ".env")
The script loads a .env file from the vault root before making API requests. This is intended configuration, but it broadens access to local secret material.
High
Generic API/secret keys
API_KEY = os.getenv("TASKNOTES_API_KEY")
The script reads TASKNOTES_API_KEY from the environment. This is a legitimate local auth token, but it is still sensitive credential access.
High
Generic API/secret keys
if API_KEY:
The conditional controls whether the configured API key is sent in request headers. It is part of a real credential handling path.
High
Generic API/secret keys
headers["Authorization"] = f"Bearer {API_KEY}"
The script places TASKNOTES_API_KEY into an Authorization bearer header. This is intended auth behavior, but it creates a credential transmission path.
Medium
Ruby/shell backtick execution
```bash
The markdown section contains bash examples that run uv with scripts/tasks.py. The command is expected, but it still instructs external command execution.
Medium
Ruby/shell backtick execution
```bash
The markdown section contains bash examples that run uv with scripts/tasks.py. The command is expected, but it still instructs external command execution.
Medium
Ruby/shell backtick execution
```bash
The markdown section contains bash examples that run uv with scripts/tasks.py. The command is expected, but it still instructs external command execution.
Low
HTTP client library
def api_request(method: str, endpoint: str, params: dict = None, data: dict = None):
The script performs HTTP requests against the local TaskNotes API. The target is documented as localhost, but the network capability is real.
Low
HTTP client library
response = requests.request(
The script performs HTTP requests against the local TaskNotes API. The target is documented as localhost, but the network capability is real.
Low
HTTP client library
result = api_request("GET", "/tasks", params=params)
The script performs HTTP requests against the local TaskNotes API. The target is documented as localhost, but the network capability is real.
Low
HTTP client library
result = api_request("POST", "/tasks", data=data)
The script sends mutating requests to the local TaskNotes API. This is intended behavior, but it can change local task records.
Low
HTTP client library
result = api_request("PUT", f"/tasks/{task_id}", data=data)
The script sends mutating requests to the local TaskNotes API. This is intended behavior, but it can change local task records.
Low
HTTP client library
result = api_request("DELETE", f"/tasks/{task_id}")
The script sends a DELETE request to the local TaskNotes API. This is intended behavior, but it can remove local task records.
Low
HTTP client library
result = api_request("GET", "/stats")
The script performs HTTP requests against the local TaskNotes API. The target is documented as localhost, but the network capability is real.
Low
HTTP client library
result = api_request("GET", "/filter-options")
The script performs HTTP requests against the local TaskNotes API. The target is documented as localhost, but the network capability is real.
Low
Python HTTP libraries
response = requests.request(
The script performs HTTP requests against the local TaskNotes API. The target is documented as localhost, but the network capability is real.
Low
Hardcoded URL
BASE_URL = f"http://localhost:{API_PORT}/api"
The code builds a local HTTP API base URL for TaskNotes. The localhost target is documented, but it is still real network behavior.
Low
Python getenv function
API_KEY = os.getenv("TASKNOTES_API_KEY")
The script reads TASKNOTES_API_KEY from the environment for TaskNotes authentication. This is expected, but it is still credential access.
Low
Python getenv function
API_PORT = os.getenv("TASKNOTES_API_PORT", "8080")
The script reads TASKNOTES_API_PORT from the environment to configure the local API endpoint. This is legitimate configuration access but affects request construction.
Low
getenv function call
API_KEY = os.getenv("TASKNOTES_API_KEY")
The script reads TASKNOTES_API_KEY from the environment for TaskNotes authentication. This is expected, but it is still credential access.
Low
getenv function call
API_PORT = os.getenv("TASKNOTES_API_PORT", "8080")
The script reads TASKNOTES_API_PORT from the environment to configure the local API endpoint. This is legitimate configuration access but affects request construction.
Low
Hardcoded URL
Base URL: `http://localhost:8080/api`
The documentation discloses a localhost TaskNotes API endpoint. This is expected for the skill, but it confirms the network dependency.

Risk findings

Confirmed security concerns are separated from items that still need review.

Confirmed security concerns (2)

RISK-001 High
Environment file access
load_dotenv(VAULT_ROOT / ".env")
The code explicitly loads a vault-root .env file. This is real sensitive-file access even though the intended use is TaskNotes configuration.
RISK-002 High
Unvalidated Local API Port Can Change Request Host
TASKNOTES_API_PORT is inserted into the URL without numeric validation. A crafted port value can change the parsed host and send the Authorization header away from localhost.
The code builds BASE_URL with an unvalidated environment value and passes headers containing the API key to requests.request. URL userinfo parsing makes host confusion possible if the port value is crafted.

Remediation

Suggested fixes recorded by this audit. Applying them is the maintainer’s responsibility.

  1. FIX-001
    High
    Unvalidated TASKNOTES_API_PORT is interpolated into the request URL.
    Parse TASKNOTES_API_PORT as an integer from 1 to 65535 before constructing BASE_URL, and reject nonnumeric values.
  2. FIX-002
    High
    The script loads a vault-root .env file before making API requests.
    Load only TaskNotes-specific settings from a dedicated config file, or document that the vault .env must not contain unrelated secrets.
  3. FIX-003
    Medium
    The CLI can update and delete local TaskNotes records.
    Require explicit user confirmation before destructive actions, and show the task path before delete operations.
  4. FIX-004
    Medium
    Documentation instructs agents to run uv commands from the skill directory.
    Keep command arguments constrained by argparse, avoid shell interpolation, and document the local network and credential behavior clearly.

Expert evidence

Immutable subject identity, scanner metadata, dismissed matches, and source-level evidence.

Artifact subject

Marketplace commit
Unavailable
Content hash
Unavailable
Tree hash
Unavailable
Skill path
Unavailable
Audit payload hash
Unavailable

Analysis metadata

Audit model: codex

Analysis state: Complete

Scope is limited to the recorded files, lines, methods, and evidence. No runtime or sandbox execution is claimed.

Verify and export

The manifest and lockfile bind install artifacts to cryptographic hashes. This integrity claim is separate from the security assessment.

Audit attestation: not_attestable