Back to skill

Security audit

artsonia-api

Security checks for vulnerabilities and agentic risk

Overview

This Markdown skill is not hidden malware, but it gives broad Artsonia account access and private student-art download guidance without enough safeguards.

Install only if you are authorized to access the Artsonia accounts and student content involved. Avoid the unauthenticated private-image path, do not bulk-download or redistribute student artwork without consent, and do not use the write recipes unless you intend real account changes or invite emails. If used, keep cookies and temporary HTML in a private 700/600 directory, clean them afterward, and run any parser only from a verified pinned source in a sandbox.

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

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:27
Finding
Session credential stored without restrictive file permissions<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 27-32 **Vulnerability Type**: Insecure storage of an authenticated session cookie **Risk Level**: Medium ### Vulnerable Code ```sh export ARTSONIA_USERNAME=you@example.com export ARTSONIA_PASSWORD='your-password' # or: op read "op://Private/Artsonia/password" JAR=~/.cache/artsonia-cookies.txt mkdir -p ~/.cache # ensure the jar's directory exists on a fresh box : > "$JAR" # fresh jar ``` ### Technical Analysis The cookie jar receives the authenticated Artsonia session cookie but is created using ordinary shell redirection. Neither the cache directory nor the cookie file is explicitly assigned restrictive permissions. The effective permissions therefore depend on the existing directory configuration and the user's `umask`. A session cookie is a bearer credential. Anyone able to read it may authenticate to Artsonia without knowing the account password until the session expires or is revoked. Although the network transmission of credentials to the declared Artsonia login endpoint is necessary for the Skill's stated functionality, leaving the resulting credential insufficiently protected exceeds the minimum local exposure necessary. ### Attack Path 1. A victim follows the documented setup and login procedure. 2. Artsonia writes an authenticated session cookie into `~/.cache/artsonia-cookies.txt`. 3. The victim's `umask`, cache directory permissions, backup configuration, or another local service makes the file readable by an unintended local account or process. 4. An attacker copies the cookie jar. 5. The attacker supplies the stolen cookie to `curl` or another HTTP client. 6. The attacker accesses authenticated Artsonia member endpoints as the victim until the session expires or is invalidated. ### Impact Assessment Successful exploitation permits session impersonation within the privileges of the affected Artsonia account. This can expose profile information, student portfolios, ...[truncated 427 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Create both the cache directory and cookie jar with explicit restrictive permissions, rather than relying on the ambient `umask`: ```sh umask 077 JAR="$HOME/.cache/artsonia-cookies.txt" install -d -m 700 "$HOME/.cache" install -m 600 /dev/null "$JAR" ``` Additional hardening should include: - Verify the cookie file is owned by the current user before every use. - Refuse to use a symbolic link as the cookie-jar path. - Delete the cookie jar when the operation finishes if persistent sessions are unnecessary. - Document how to invalidate the server-side session. - Avoid including the cookie jar in backups, synchronization tools, logs, or source-control repositories. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:39
Finding
Authenticated responses written to predictable shared temporary files<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 39-48 and 66-68; `references/endpoints.md`, including lines 29, 118, 201-202, 241, and 253 **Vulnerability Type**: Unsafe predictable temporary-file handling **Risk Level**: Medium ### Vulnerable Code Examples from `SKILL.md`: ```sh printf '%s' "$ARTSONIA_PASSWORD" | curl -s -c "$JAR" -b "$JAR" -L \ --data-urlencode "Username=$ARTSONIA_USERNAME" \ --data-urlencode "Password@-" \ --data-urlencode "TargetUrl=/members/" \ --data-urlencode "Action=login" \ -o /tmp/artsonia-login.html -w '%{http_code} %{url_effective}\n' \ https://www.artsonia.com/members/login.asp ``` ```sh curl -s -b "$JAR" -c "$JAR" 'https://www.artsonia.com/members/' -o /tmp/dash.html ``` Examples from `references/endpoints.md`: ```sh curl -s -b "$JAR" -c "$JAR" 'https://www.artsonia.com/members/profile/' -o /tmp/profile.html ``` ```sh curl -s -b "$JAR" -c "$JAR" -o /tmp/invite-result.html -w '%{http_code}\n' \ --data-urlencode "MemberType=fan" \ --data-urlencode "RelationshipID=<relationship-id-from-the-live-Add-Fans-form>" \ --data-urlencode "FirstName=Test" \ --data-urlencode "LastName=Fan" \ --data-urlencode "EmailAddress=test@example.com" \ --data-urlencode "ArtistID=$ID" \ "https://www.artsonia.com/members/fanclub/add.asp?artist=$ID" ``` ### Technical Analysis The documented commands repeatedly write authenticated HTTP responses to fixed names under the globally shared `/tmp` directory. Examples include `/tmp/artsonia-login.html`, `/tmp/dash.html`, `/tmp/profile.html`, and `/tmp/invite-result.html`. Predictable temporary paths introduce two related risks: 1. **Symlink or file-replacement attacks:** Another local user can pre-create a symbolic link or otherwise manipulate a predictable path before the command runs. Depending on platform protections and file ownership, `curl` may write through the path and overwrite an unintended file accessible to the victim. 2. **Sensitive-data discl ...[truncated 1954 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Use a private, randomly named working directory and clean it automatically: ```sh umask 077 WORKDIR="$(mktemp -d "${TMPDIR:-/tmp}/artsonia.XXXXXXXX")" || exit 1 trap 'rm -rf -- "$WORKDIR"' EXIT HUP INT TERM LOGIN_HTML="$WORKDIR/login.html" DASH_HTML="$WORKDIR/dashboard.html" PROFILE_HTML="$WORKDIR/profile.html" ``` Then replace every fixed `/tmp` output with a path inside `$WORKDIR`, for example: ```sh curl -s -b "$JAR" -c "$JAR" \ 'https://www.artsonia.com/members/profile/' \ -o "$PROFILE_HTML" ``` Further hardening should include: - Set the private directory to mode `700` and files to mode `600`. - Validate that the working directory and output files are not symbolic links. - Remove temporary data on normal completion and on signals. - Store only the minimum response content needed for parsing. - Prefer in-memory pipelines where practical. - Avoid placing authentication responses and profile pages in shared temporary storage. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:78
Finding
Execution of unpinned dependencies and build scripts from an unspecified external checkout<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 78-89; `references/endpoints.md`, lines 3-5 **Vulnerability Type**: Unverified third-party dependency and build execution **Risk Level**: Medium ### Vulnerable Code From `SKILL.md`: ```sh For the full structured fields (name, school, stats, notifications, awards, …) don't re-derive selectors by hand — this repo already ships a live-verified `node-html-parser` scraper (`src/parse.ts` → built `dist/parse.js`) with one function per page. Build it once, then import it in a one-liner and pipe the JSON to `jq`: ```sh cd ~/git/artsonia-mcp && npm install && npm run build # once, if dist/ is missing node --input-type=module -e " import { readFileSync } from 'node:fs'; import { parseStudents } from '$(pwd)/dist/parse.js'; console.log(JSON.stringify(parseStudents(readFileSync('/tmp/dash.html', 'utf8')))); " | jq '.' ``` ``` From `references/endpoints.md`: ```text All parsing functions below are the MCP's own live-verified `src/parse.ts` (built to `dist/parse.js`) — build once with `npm install && npm run build` in the repo, then reuse the `node --input-type=module` one-liner shown per endpoint. ``` ### Technical Analysis The Skill instructs users to run `npm install`, execute the repository's build script, and import generated JavaScript from an external local checkout. The audited project does not include that parser repository, identify a verified source URL or commit, or establish the expected integrity of its package manifest, lockfile, dependencies, lifecycle scripts, build scripts, or generated output. `npm install` can execute dependency lifecycle scripts such as `preinstall`, `install`, and `postinstall`. `npm run build` directly executes commands defined by the external repository. The subsequent dynamic import executes the generated `dist/parse.js` with the user's operating-system permissions. Consequently, replacing or compromising the checkout or one of its dependencies can turn ...[truncated 1763 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Use a reviewed and reproducible dependency process: 1. Include the required parser implementation in the audited Skill package, or specify an authoritative repository URL and pin it to a reviewed immutable commit. 2. Include a committed npm lockfile and use: ```sh npm ci ``` rather than an unconstrained `npm install`. 3. Where compatible, suppress lifecycle scripts: ```sh npm ci --ignore-scripts ``` 4. If a build script is required, audit its complete command chain and all invoked tools before execution. 5. Verify the repository commit and lockfile against published checksums or signed release metadata. 6. Pin dependency versions and use integrity hashes. 7. Run installation and parsing in a sandbox with: - No access to unrelated credentials or home-directory files. - Restricted network access. - Read-only source inputs. - A disposable working directory. 8. Do not import a pre-existing `dist/parse.js` unless its provenance and integrity have been verified. 9. Prefer a small, locally audited parser or the documented regex-only path when only identifiers are required. ]]>
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • 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 (9)

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
This section goes beyond authenticated member-data access and teaches retrieval of full-resolution private artwork without login. In a skill centered on student portfolios and family/member access, that materially increases the chance of privacy abuse, scraping, and unauthorized disclosure of student content.

Missing User Warnings

High
Confidence
96% confidence
Finding
Stating that full-resolution images are accessible 'even for private pieces' without any cautionary language effectively advertises a privacy bypass. For student artwork, this creates a clear misuse path by encouraging access to content that users likely expect to remain protected.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The skill handles potentially sensitive student and account information, including portfolios, comments, fans, and teacher feedback, but provides no privacy, consent, retention, or authorized-use warning. That omission can normalize casual extraction of student-related data and increase the risk of mishandling or overcollection.

Session Persistence

Medium
Category
Rogue Agent
Content
export ARTSONIA_USERNAME=you@example.com
export ARTSONIA_PASSWORD='your-password'   # or: op read "op://Private/Artsonia/password"
JAR=~/.cache/artsonia-cookies.txt
mkdir -p ~/.cache   # ensure the jar's directory exists on a fresh box
: > "$JAR"   # fresh jar
```
Confidence
77% confidence
Finding
The skill stores session cookies in a persistent file under ~/.cache, which may remain on disk after use and could be reused by someone with local access to the account or machine. Although this is standard shell practice, the documentation does not mention file permissions, cleanup, or ephemeral storage, increasing the risk of session leakage.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The skill explicitly documents that full-resolution artwork images for 'private pieces' can be retrieved from a public CDN without authentication. That exposes student-associated content outside the authenticated access model described elsewhere in the skill, enabling unauthorized viewing or redistribution of private artwork if an ID is known or discovered.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The profile endpoint exposes and supports modification of personal data such as first name, last name, email, mobile number, and notification preferences, but the documentation lacks a clear privacy and data-handling warning. In a student-art portfolio context, this increases the risk of inappropriate collection, display, logging, or modification of sensitive account information.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The skill’s stated purpose is read-oriented Artsonia data access, but this file additionally documents authenticated state-changing actions such as posting comments, inviting fans, marking feedback read, and modifying profile notification settings. That mismatch expands the effective capability surface of the skill and can mislead users or downstream tooling into granting or using broader privileges than expected.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
The documented fan-invite flow can send real invitation emails to third parties and is not necessary for the advertised goal of accessing portfolio data. This introduces an external-action capability that could be abused for unsolicited contact, social engineering, or spam from a trusted account context.

Missing User Warnings

Low
Confidence
80% confidence
Finding
The bulk-download instructions make it easy to retrieve large sets of student artwork from the public CDN without any warning about sensitivity, consent, or retention. Even if CDN objects are publicly fetchable by ID, operationalizing bulk collection can magnify privacy harm and facilitate unauthorized archiving or redistribution of children’s content.

Static analysis

No suspicious patterns detected.