agentsclimarketplace

Vue state store security review

Skill Raishin/vanguard-frontier-agentic/skills/frontend/vue-state-store-security-review

Curated marketplace of AI skills, agents, and rules for cloud, zero-trust, and compliance-aware engineering - works with Claude Code, Codex, Cursor, Copilot, and more.

Install
npx -y skills add Raishin/vanguard-frontier-agentic --skill vue-state-store-security-review

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 18 stars18 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Statically review Pinia and legacy Vuex state stores for sensitive data persisted to localStorage/sessionStorage without scoping, untrusted server-payload hydration (window.__pinia/__INITIAL_STATE__) with un-escaped state serialization, SSR store-singleton cross-request pollution, store plugins/$subscribe/$onAction acting on untrusted payloads, client-held role flags used as an authorization source of truth, and devtools state exposure in production builds.

SKILL.md

11.0 KB, as published. Nobody here has run it

Vue State Store Security Review

Purpose

Review Pinia and legacy Vuex state-store code for the security-critical defect classes that are specific to state stores as a component — not general Vue architecture, not composable design, and not SSR hydration/injection issues that belong to vue-ssr-security-review. This skill exists to keep the review anchored to five documented defect classes: (a) sensitive data persisted client-side without scoping, (b) store hydration from an untrusted server payload with un-escaped serialization, (c) SSR store-singleton cross-request pollution, (d) store plugins/hooks acting on untrusted payloads and client-held flags used as an authorization source of truth, and (e) devtools state exposure in production. It does not re-litigate general reactivity/composable architecture, v-html/URL-injection review (covered by vue-ssr-security-review), or Composition API design quality (covered by vue-composition-api-architecture-review) in every response.

When to use

Use this skill when the user asks to:

  • review a Pinia store definition (defineStore) or a legacy Vuex module/store for security issues,
  • assess whether pinia-plugin-persistedstate / vuex-persistedstate configuration is safe (what gets persisted, and where),
  • review SSR store creation/hydration code (entry-server.js, a Nuxt server plugin, an Express/Node handler that constructs createPinia()/createStore()) for cross-request pollution risk,
  • review a store plugin, $subscribe/$onAction hook, or Vuex plugin that consumes mutation/action payloads,
  • investigate whether a client-side role/permission flag (isAdmin, role) is being trusted as an authorization boundary,
  • perform a pre-launch security review of a Pinia/Vuex-based application's state layer.

Do not use this skill for:

  • v-html/dynamic-URL injection review or SSR entry-point app/router creation — use vue-ssr-security-review for those; this skill covers the store specifically, not the broader SSR rendering surface (load both skills together if the review spans both),
  • Composition API/composable architecture quality with no security angle — use vue-composition-api-architecture-review instead,
  • a general "which state-management library should we pick" architecture decision with no security defect in scope — use state-management-decision-review instead,
  • a bug that requires live traffic reproduction (concurrent-request capture, a devtools screen-recording of production, live token exfiltration) to confirm exploitation — static analysis proves the structural risk, not that it has already been exploited.

Context7 Documentation Protocol

  • Resolve library IDs with resolve-library-id before citing any store-behavior claim. This skill's three grounding libraries: /vuejs/pinia (Pinia core — SSR hydration, plugins, $subscribe/$onAction), /prazdevs/pinia-plugin-persistedstate (persistence defaults and pick/storage config), /vuejs/vuex (legacy Vuex — state as function, devtools option, plugin/module API).
  • Use query-docs against /prazdevs/pinia-plugin-persistedstate to confirm persistence defaults before flagging a persistence config: storage defaults to localStorage when unset; pick (an array of dotted state-path strings) restricts persistence to named paths; with no pick, the entire state is persisted. Cite these as documentation-based.
  • Use query-docs against /vuejs/pinia to confirm SSR hydration mechanics before flagging a hydration finding: the documented client-side pattern is pinia.state.value = JSON.parse(window.__pinia), and Pinia's own SSR guide states escaping the serialized state is "VERY important if the content of the state can be changed by the user, which is almost always the case," recommending devalue (or equivalent) over naive JSON.stringify. Cite as documentation-based.
  • Use query-docs against /vuejs/pinia to confirm $subscribe/$onAction hook signatures (mutation object with type/storeId/payload; action object with name/store/args/ after/onError) before describing a plugin-hook finding — do not invent a hook name or argument Context7 does not confirm.
  • Use query-docs against /vuejs/vuex to confirm the state: () => ({...}) factory pattern (module reusability without shared state) and the devtools: boolean store option before citing either — do not assume Pinia has an equivalent devtools boolean on defineStore/ createPinia; Context7 does not confirm that API surface for Pinia, so any Pinia-devtools concern must be scoped to "a build-time devtools plugin explicitly force-enabled in production," not a Pinia store option, and labeled inference unless a repo-specific config is found.
  • Read package.json first to confirm which store library is in play (pinia, pinia-plugin-persistedstate, vuex, vuex-persistedstate) and its major version — API names and defaults differ between Pinia and Vuex and across Vuex 3/4; do not apply one library's API names to the other.
  • If Context7 is unavailable, fall back to the official_docs URLs in this skill's metadata.json and label the claim documentation-based, unverified against current release.

Lean operating rules

  • Findings in every defect class below default to HIGH severity: unscoped sensitive-data persistence, untrusted/un-escaped state hydration, SSR store-singleton pollution, untrusted payload handling in store plugins/hooks, client-side-flag-as-authorization, and production devtools exposure. Do not downgrade a structural finding to MEDIUM because it has not been observed exploited — the risk is in the structure.
  • Trace every finding to a concrete file:line and a concrete data-flow path. "This store might leak sensitive data" or "this hydration looks risky" without naming the specific persist/pick/storage config, the specific module-scope createPinia()/createStore() declaration, or the specific untraced payload sink is not a valid finding — it is a guess.
  • Before flagging a persistence config, read the full state() shape and the full persist config together. A persist: true (or persist: {}) with no pick/paths array persists the entire state — treat every sensitive field in that state as persisted unless a pick list demonstrably excludes it. A pick list that omits the sensitive field(s) clears the finding for those fields specifically (not for the whole store, if other sensitive fields remain unscoped).
  • Before flagging SSR store creation as cross-request pollution, confirm mutability/reachability the same way vue-ssr-security-review requires for app instances: is the createPinia()/ createStore() call inside the per-request handler, and does that handler close over any module-scope mutable/reactive reference? An immutable module-scope constant (a frozen config object, a static route table) is not the risk; a store instance or mutable cache is.
  • Do not approve a client-side role/permission flag (isAdmin, role, permissions) as an authorization boundary for a mutating action unless the review also confirms (via visible server-side code, or an explicit statement that server-side authorization is out of scope for this static review) that the actual mutation is re-checked server-side. A store flag gating only UI visibility (hiding a button) is not itself a finding; a store flag gating whether a mutating network call is made is a finding regardless of UI-layer intent, because the flag is client-writable.
  • Do not treat every $subscribe/$onAction/Vuex-plugin hook as risky. Only hooks that act on the payload with a side effect (write, external call, log of sensitive data, mutate another store) and lack payload validation are findings; read-only observation (e.g., analytics event naming) is not.
  • Never execute, build, or run application code, and never send live requests, as part of this review; this is a static-review skill (Read/Grep/Glob only).
  • Load only the reference needed for the concern in scope.

References

Load these only when needed:

  • Review workflow and findings contract — use for the step-by-step review procedure, the decision tree across all five defect classes, and the required output shape.
  • Client-side persistence and hydration — load when reviewing pinia-plugin-persistedstate/vuex-persistedstate configuration, SSR store creation/singleton risk, or server-payload hydration (window.__pinia/__INITIAL_STATE__).
  • Untrusted payloads and authorization — load when reviewing $subscribe/$onAction/Vuex-plugin hooks, client-held role/permission flags used for access control, or devtools production exposure.
  • Acceptance rubric — the enumerated defect/false-positive list this skill's rules were authored against; load if you need the underlying catch list rather than the operating rules derived from it.

Response minimum

Return, at minimum:

  • the store definition(s), persistence config, SSR entry point(s), and/or plugin/hook code in scope,
  • ranked findings with file:line evidence, defect category (persistence, hydration, ssr-pollution, untrusted-payload, client-auth-flag, or devtools-exposure), the concrete data-flow trace (state field → persist config, or server payload → hydration call, or module-scope declaration → per-request reachability, or payload → sink), and a fix sketch matching the grounding library's documented pattern,
  • for every persistence finding, an explicit statement of which state fields are covered by pick/paths (if any) and which are not,
  • for every client-side-flag finding, an explicit statement of whether a server-side authorization re-check was found, not found, or is out of scope for this static review,
  • evidence level per finding (repo evidence, documentation-based, or inference), with structural risk findings explicitly labeled as structural risk, not as confirmed-exploited,
  • verdict (approve / approve-with-notes / block),
  • open questions or scope the review could not cover (e.g., "confirming actual cross-request leakage requires concurrent-request load testing," or "v-html/URL-injection review of this same app is out of scope for this skill — see vue-ssr-security-review").

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.