Back to skill

Security audit

Instatic CMS

Security checks for vulnerabilities and agentic risk

Overview

This is a pure-documentation skill for operating a self-hosted CMS, with broad but disclosed admin capabilities that match its purpose.

Install only if you intend to let an agent help operate your own Instatic instance. Treat CMS credentials, PATs, provider keys, and step-up passwords as sensitive, confirm destructive or public-facing changes before execution, and keep backups before schema, import, plugin, user, or publish operations.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (17)

Tool Parameter Abuse

High
Category
Tool Misuse
Content
- POST /login {email,password}; POST /logout; POST /auth/logout-all
- GET /me; PATCH /me (displayName,email); PATCH /me/password
- POST /auth/step-up {password} (opens window, default 15 min; PATCH /me/security/step-up sets 5/15/30/60)
- GET /auth/sessions; DELETE /auth/sessions/:id
- POST /auth/mfa/verify; POST /me/mfa/totp/start; POST /me/mfa/totp/enable; DELETE /me/mfa/totp; POST /me/mfa/recovery-codes
- GET /auth/activity (login attempts; lockout diagnosis)
- /me/preferences/:key (catalog-driven editor prefs); POST /me/avatar; DELETE /me/avatar
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
- GET /me; PATCH /me (displayName,email); PATCH /me/password
- POST /auth/step-up {password} (opens window, default 15 min; PATCH /me/security/step-up sets 5/15/30/60)
- GET /auth/sessions; DELETE /auth/sessions/:id
- POST /auth/mfa/verify; POST /me/mfa/totp/start; POST /me/mfa/totp/enable; DELETE /me/mfa/totp; POST /me/mfa/recovery-codes
- GET /auth/activity (login attempts; lockout diagnosis)
- /me/preferences/:key (catalog-driven editor prefs); POST /me/avatar; DELETE /me/avatar
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
- GET /auth/sessions; DELETE /auth/sessions/:id
- POST /auth/mfa/verify; POST /me/mfa/totp/start; POST /me/mfa/totp/enable; DELETE /me/mfa/totp; POST /me/mfa/recovery-codes
- GET /auth/activity (login attempts; lockout diagnosis)
- /me/preferences/:key (catalog-driven editor prefs); POST /me/avatar; DELETE /me/avatar

## Users and roles (users.manage / roles.manage; mutations step-up-gated per handler source)
- GET /users; POST /users {email,password,displayName?,roleId,status?} (create rejects role=owner; guards stop you removing the last active owner)
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
## Users and roles (users.manage / roles.manage; mutations step-up-gated per handler source)
- GET /users; POST /users {email,password,displayName?,roleId,status?} (create rejects role=owner; guards stop you removing the last active owner)
- PATCH /users/:id (email/displayName/password/roleId/status); DELETE /users/:id (soft)
- GET|POST /roles; PATCH|DELETE /roles/:id (custom roles only; built-ins resync at boot)

## Data: tables and rows
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
## Users and roles (users.manage / roles.manage; mutations step-up-gated per handler source)
- GET /users; POST /users {email,password,displayName?,roleId,status?} (create rejects role=owner; guards stop you removing the last active owner)
- PATCH /users/:id (email/displayName/password/roleId/status); DELETE /users/:id (soft)
- GET|POST /roles; PATCH|DELETE /roles/:id (custom roles only; built-ins resync at boot)

## Data: tables and rows
Tables (writes content.manage; create/patch/delete additionally step-up-gated, live-verified on create):
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
Tables (writes content.manage; create/patch/delete additionally step-up-gated, live-verified on create):
- GET /data/tables (list with row counts, optional query + limit); POST /data/tables -> 201 {table}
- Create semantics: kind coerces to postType|data (system tables are not creatable); slug from pluralLabel, pluralLabel from name, singularLabel from name minus trailing s; supplied fields win on id collision; omitting fields entirely gets the canonical six postType built-ins; mandatory title+slug are auto-prepended when missing; non-empty routeBase gives published rows public URLs
- GET /data/tables/:id -> {table} (full stored schema; the readback for computed flags); PATCH/DELETE /data/tables/:id (system tables frozen; step-up)
- GET /data/tables/:id/rows; POST /data/tables/:id/rows (draft row); GET /data/tables/:id/loop-preview
Rows:
- GET|PATCH|DELETE /data/rows/:id (PATCH saves draft cells; DELETE soft)
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
- GET /data/tables/:id -> {table} (full stored schema; the readback for computed flags); PATCH/DELETE /data/tables/:id (system tables frozen; step-up)
- GET /data/tables/:id/rows; POST /data/tables/:id/rows (draft row); GET /data/tables/:id/loop-preview
Rows:
- GET|PATCH|DELETE /data/rows/:id (PATCH saves draft cells; DELETE soft)
- POST /data/rows/:id/publish (content.publish.own / .any); PATCH /data/rows/:id/status (draft<->unpublished)
- POST|DELETE /data/rows/:id/schedule (scheduled publish); PATCH /data/rows/:id/author; PATCH /data/rows/:id/table (data.rows.move)
- POST /data/rows/:id/preview; GET /data/rows/:id/versions; POST /data/rows/:id/versions/:versionId/restore
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
Rows:
- GET|PATCH|DELETE /data/rows/:id (PATCH saves draft cells; DELETE soft)
- POST /data/rows/:id/publish (content.publish.own / .any); PATCH /data/rows/:id/status (draft<->unpublished)
- POST|DELETE /data/rows/:id/schedule (scheduled publish); PATCH /data/rows/:id/author; PATCH /data/rows/:id/table (data.rows.move)
- POST /data/rows/:id/preview; GET /data/rows/:id/versions; POST /data/rows/:id/versions/:versionId/restore
- GET /data/authors; GET /data/search?query=&limit=
- GET /data/_meta -> {meta:{tables:[{id,slug,name,kind,singularLabel,pluralLabel,primaryFieldId,routable,versioned,fields}]}} (nested under `meta`; the compact schema view)
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
## Media
- GET /media (list); POST /media (multipart `file` part + metadata; size + magic-byte validation; image variants generated) (media.write)
- PATCH|DELETE /media/:id (metadata / soft delete); POST /media/:id/restore; POST /media/:id/replace (media.replace); POST /media/:id/folders
- GET|POST /media/folders; PATCH|DELETE /media/folders/:id (cascade children + assets)
- Storage adapters: GET /media/storage; POST /media/storage/elect | /delegate | /verify/:id | /migrate (storage.elect / storage.migrate)
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
## Media
- GET /media (list); POST /media (multipart `file` part + metadata; size + magic-byte validation; image variants generated) (media.write)
- PATCH|DELETE /media/:id (metadata / soft delete); POST /media/:id/restore; POST /media/:id/replace (media.replace); POST /media/:id/folders
- GET|POST /media/folders; PATCH|DELETE /media/folders/:id (cascade children + assets)
- Storage adapters: GET /media/storage; POST /media/storage/elect | /delegate | /verify/:id | /migrate (storage.elect / storage.migrate)

## Fonts
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
- Storage adapters: GET /media/storage; POST /media/storage/elect | /delegate | /verify/:id | /migrate (storage.elect / storage.migrate)

## Fonts
- GET /fonts/google (bundled directory, no CDN hit); POST /fonts/estimate; POST /fonts/install (woff2 download); POST /fonts/custom (from uploaded media); DELETE /fonts/family/:family

## Branches (site.branches.create / .manage)
- GET|POST /branches (list / fork); PATCH|DELETE /branches/:id (rename / delete)
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
- GET /fonts/google (bundled directory, no CDN hit); POST /fonts/estimate; POST /fonts/install (woff2 download); POST /fonts/custom (from uploaded media); DELETE /fonts/family/:family

## Branches (site.branches.create / .manage)
- GET|POST /branches (list / fork); PATCH|DELETE /branches/:id (rename / delete)
- GET|POST|DELETE /branches/:id/preview (active link / issue / revoke)
- GET /branches/:id/merge then POST (plan then execute, manage + step-up); POST /branches/:id/merge/undo; same pair for update
- GET /branches/:id/review; POST .../review/request|withdraw|decline; POST .../review/comments; GET .../review/render (page as main vs branch). Main is the live site and never a source to merge from
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
## Branches (site.branches.create / .manage)
- GET|POST /branches (list / fork); PATCH|DELETE /branches/:id (rename / delete)
- GET|POST|DELETE /branches/:id/preview (active link / issue / revoke)
- GET /branches/:id/merge then POST (plan then execute, manage + step-up); POST /branches/:id/merge/undo; same pair for update
- GET /branches/:id/review; POST .../review/request|withdraw|decline; POST .../review/comments; GET .../review/render (page as main vs branch). Main is the live site and never a source to merge from
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
## Plugins (plugins.read/install/configure/lifecycle)
- GET|POST /plugins (list / manifest JSON install); POST /plugins/inspect-package; POST /plugins/package (zip install/upgrade)
- PATCH|DELETE /plugins/:id (enable/disable; uninstall with ?force=true deletes assets); POST /plugins/:id/restart; POST /plugins/:id/pack/install
- GET|PUT /plugins/:id/settings (schema + masked values)
- GET|POST /plugins/:id/resources/:rid/records; PATCH|DELETE .../records/:recId
- GET /plugins/:id/schedules; POST .../schedules/:sid/run-now|pause|resume; GET /plugins/events (SSE)
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Credential Access

High
Category
Privilege Escalation
Content
- POST /admin/api/ai/chat/site|content opens an NDJSON stream; browser-bridged tool results relay to POST /admin/api/ai/tool-result; /admin/api/ai/oauth/authorize for OAuth providers

## MCP
- Endpoint /_instatic/mcp; OAuth aux /_instatic/oauth/register + /_instatic/oauth/token; personal access tokens use the imcp_pat_ prefix (server/ai/mcp/connectors/token.ts)

## Audit and dashboard (audit.read / dashboard.read)
- GET /audit (latest events, reverse-chronological; publish, user/role/plugin/data mutations recorded)
Confidence
90% confidence
Finding
The skill exposes highly sensitive authentication details for the MCP surface, including the OAuth token endpoints and the personal access token prefix `imcp_pat_`. In an agent-skill context, publishing token formats and auth endpoints materially helps downstream agents or users identify, request, store, or mishandle bearer credentials, increasing the chance of credential theft or unsafe automated use.

Credential Access

High
Category
Privilege Escalation
Content
- Providers: Anthropic, OpenAI, OpenRouter, Ollama, or any OpenAI-compatible endpoint; keys encrypted at rest with INSTATIC_SECRET_KEY. Gates: ai.chat streams, ai.tools.write allows writes.

## 3. MCP server (outside clients driving Instatic)
- Endpoint /_instatic/mcp. Personal access tokens (imcp_pat_ prefix) are created after step-up, shown once, capability-scoped, revocable. Hosted OAuth (authorization code + S256 PKCE; 1h access tokens, rotating refresh, 90-day grant) serves remote MCP clients; hosted clients need an HTTPS canonical origin, they cannot reach localhost or HTTP installs.
- Same tool allow-list gate as the in-app agent; an MCP token grants nothing wider than its capabilities.

## 4. Plugins
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Missing User Warnings

Low
Confidence
78% confidence
Finding
This markdown file instructs the operator to submit `POST /auth/step-up {password}` but does not include any warning about entering or transmitting sensitive credentials. Under the markdown-specific warning criterion, actions affecting privacy or credential handling should be disclosed clearly to the user.

Static analysis

No suspicious patterns detected.