All skills
openai avatar

/security-best-practices

@5c8f1e2 official
by openaiopenai/skills28k stars
1,891

Perform language and framework specific security best-practice reviews and suggest improvements. Trigger only when the user explicitly requests security best practices guidance, a security review/report, or secure-by-default coding help. Trigger only for supported languages (python, javascript/typescript, go). Do not trigger for general code review, debugging, or non-security tasks.

Use this Skill: https://skilld.dev/gh/openai/skills/security-best-practices

This session only. Nothing lands on disk.

referencesjavascript-typescript-vue-web-frontend-security.md

≈7.9k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Vue.js Web Security Spec (Vue 3.x, TypeScript/JavaScript, common tooling: Vite)

This document is designed as a security spec that supports:

  1. Secure-by-default code generation for new Vue code.
  2. Security review / vulnerability hunting in existing Vue code (passive “notice issues while working” and active “scan the repo and report findings”).

It is intentionally written as a set of normative requirements (“MUST/SHOULD/MAY”) plus audit rules (what bad patterns look like, how to detect them, and how to fix/mitigate them).


0) Safety, boundaries, and anti-abuse constraints (MUST FOLLOW)

  • MUST NOT request, output, log, or commit secrets (API keys, passwords, private keys, session cookies, auth tokens).
  • MUST NOT “fix” security by disabling protections (e.g., weakening CSP, turning on unsafe template compilation, using v-html as a shortcut, bypassing backend auth, or “just store the token in localStorage”).
  • MUST provide evidence-based findings during audits: cite file paths, code snippets, and configuration values that justify the claim.
  • MUST treat uncertainty honestly: if a protection might exist at the edge (CDN, reverse proxy, WAF, server headers), report it as “not visible in repo; verify runtime/infra config”.
  • MUST remember the frontend trust model: any code shipped to browsers is attacker-readable and attacker-modifiable. Secrets and “security enforcement” cannot rely on frontend-only logic.

1) Operating modes

1.1 Generation mode (default)

When asked to write new Vue code or modify existing code:

  • MUST follow every MUST requirement in this spec.
  • SHOULD follow every SHOULD requirement unless the user explicitly says otherwise.
  • MUST prefer safe-by-default framework features and proven libraries over custom security code.
  • MUST avoid introducing new risky sinks (runtime template compilation, v-html / innerHTML, unsafe URL navigation, dynamic script injection, etc.). (Vue.js)

1.2 Passive review mode (always on while editing)

While working anywhere in a Vue repo (even if the user did not ask for a security scan):

  • MUST “notice” violations of this spec in touched/nearby code.
  • SHOULD mention issues as they come up, with a brief explanation + safe fix.

1.3 Active audit mode (explicit scan request)

When the user asks to “scan”, “audit”, or “hunt for vulns”:

  • MUST systematically search the codebase for violations of this spec.
  • MUST output findings in a structured format (see §2.3).

Recommended audit order:

  1. Build/deploy entrypoints and hosting config (Docker, CI, static hosting, SSR server).
  2. Secrets exposure (env usage, .env*, hard-coded keys). (vitejs)
  3. XSS surface: templates, v-html / innerHTML, URL/style injection, DOM APIs. (Vue.js)
  4. Auth/session handling in the browser (token storage, credentialed requests, CSRF integration). (Vue.js)
  5. Routing/navigation (open redirects, “return_to/next”, unsafe external navigation). (Vue.js)
  6. Third-party scripts and content (CDN assets, analytics, widgets, iframes). (Vue.js)
  7. Security headers and browser hardening expectations (CSP, clickjacking). (Vue.js)
  8. SSR-specific concerns (state serialization, template boundaries) when applicable. (Vue.js)

2) Definitions and review guidance

2.1 Untrusted input (treat as attacker-controlled unless proven otherwise)

In a Vue app, untrusted input includes (non-exhaustive):

  • Anything from APIs: fetch, axios, GraphQL responses, webhooks, third-party SDKs.
  • Router-controlled data: route.params, route.query, route.hash, and anything derived from window.location.
  • User-controlled persisted content: DB-backed content displayed in the UI (comments, profiles, CMS content).
  • Browser-controlled storage: localStorage, sessionStorage, IndexedDB.
  • Cross-window messages: postMessage inputs.
  • Anything that can be influenced by an attacker through DOM clobbering or injected HTML (especially if Vue is mounted onto non-sterile DOM). (Vue.js)

2.2 State-changing action (frontend perspective)

An action is state-changing if it can:

  • Create/update/delete data via API calls.
  • Change authentication/session state (login, logout, refresh token).
  • Trigger privileged operations (payments, admin actions).
  • Cause side effects (sending emails, triggering webhooks, changing account settings).

2.3 Required audit finding format

For each issue found, output:

  • Rule ID:
  • Severity: Critical / High / Medium / Low
  • Location: file path + component/function + line(s)
  • Evidence: the exact code/config snippet
  • Impact: what could go wrong, who can exploit it
  • Fix: safe change (prefer minimal diff)
  • Mitigation: defense-in-depth if immediate fix is hard
  • False positive notes: what to verify if uncertain

3) Secure baseline: minimum production configuration (MUST in production)

This is the smallest “production baseline” that prevents common Vue/front-end misconfigurations.

  • MUST ship a production build (not a development build or dev server). (Vue.js)
  • MUST NOT ship secrets in frontend bundles; treat all client-exposed env variables as public. (vitejs)
  • MUST NOT render non-trusted templates or allow user-provided Vue templates (equivalent to arbitrary JS execution). (Vue.js)
  • SHOULD avoid raw HTML injection (v-html, innerHTML) unless content is trusted or strongly sandboxed. (Vue.js)
  • SHOULD deploy baseline security headers (especially CSP and clickjacking defenses) at the server/CDN layer. (OWASP Cheat Sheet Series)
  • SHOULD use safe auth patterns (prefer HttpOnly cookies for session tokens; coordinate with backend on CSRF). (Vue.js)

4) Rules (generation + audit)

Each rule contains: required practice, insecure patterns, detection hints, and remediation.

VUE-DEPLOY-001: Do not run dev/preview servers in production

Severity: High

Required:

  • MUST NOT deploy the Vite/Vue dev server (vite, npm run dev, HMR) as the production server.
  • MUST NOT use vite preview as a production server. (vitejs)
  • MUST build (vite build) and serve the built assets using a production-grade static server/CDN, or a production SSR server if you are doing SSR. (vitejs)

Insecure patterns:

  • Docker/Procfile/systemd running vite, npm run dev, or vite preview as the production entrypoint.
  • Publicly exposed HMR endpoints.

Detection hints:

  • Search: vite, npm run dev, pnpm dev, yarn dev, vite preview, vue-cli-service serve.
  • Check Docker CMD, ENTRYPOINT, CI deploy scripts, platform config.

Fix:

  • Build artifacts with vite build.
  • Serve dist/ with hardened hosting (CDN/static server) or integrate into your backend server as static assets.

Notes:

  • Using dev/preview servers locally is fine; only flag if it is the production entrypoint.

VUE-DEPLOY-002: Use Vue production builds and keep devtools off in production

Severity: Medium (High if production devtools/debug hooks are enabled)

Required:

  • If loading Vue from CDN/self-host without a bundler, MUST use the .prod.js builds in production. (Vue.js)
  • SHOULD ensure production bundles do not enable Vue devtools in production builds, and SHOULD not intentionally enable production devtools flags. (Vue.js)

Insecure patterns:

  • Production includes development build artifacts.
  • Explicitly enabling production devtools/diagnostic hooks.

Detection hints:

  • Search HTML for vue.global.js / non-.prod.js variants when using CDN builds.
  • Search build config for Vue feature flags like __VUE_PROD_DEVTOOLS__. (Vue.js)

Fix:

  • Switch to production build artifacts and ensure compile-time flags are configured for production.

VUE-SECRETS-001: Never ship secrets in frontend code or env variables

Severity: High (Critical if real credentials are exposed)

Required:

  • MUST treat all frontend code and configuration as public.

  • MUST NOT embed secrets in:

    • source code
    • .env files committed to repo
    • import.meta.env.* variables included in the bundle
  • MUST assume any env var that ends up in the client bundle is attacker-readable. (vitejs)

Insecure patterns:

  • VITE_API_KEY=... containing a true secret (not just a public identifier).
  • Hard-coded API keys, private tokens, service credentials, signing keys in JS/TS.

Detection hints:

  • Search: VITE_, import.meta.env, .env, .env.production, .env.*.local.
  • Grep for API_KEY, SECRET, TOKEN, PRIVATE_KEY, BEGIN, sk-, AKIA, etc.

Fix:

  • Move secrets to backend/edge functions.
  • Use backend-minted short-lived tokens for the browser when needed.

Notes:

  • Vite specifically warns that .env.*.local should be gitignored and that VITE_* vars end up in the client bundle, so they must not contain sensitive info. (vitejs)

VUE-SECRETS-002: Do not broaden Vite env exposure

Severity: High

Required:

  • MUST NOT configure Vite to expose all environment variables to the client.
  • SHOULD keep envPrefix strict and explicit.

Insecure patterns:

  • Setting envPrefix to overly broad values (or '') to “make env vars work”.
  • Custom scripts that inject server secrets into global variables in HTML at build time.

Detection hints:

  • Check vite.config.* for envPrefix.
  • Look for define: { 'process.env': ... } or manual injection into window.__CONFIG__.

Fix:

  • Keep secrets server-side.
  • Only expose non-sensitive values intentionally designed to be public.

Notes:

  • Vite’s docs explain that only prefixed variables are exposed and that exposed variables land in the client bundle. (vitejs)

VUE-XSS-001: Prefer Vue’s default escaping; avoid raw HTML injection

Severity: High

Required:

  • MUST rely on Vue’s automatic escaping for text interpolation and attribute binding where possible. (Vue.js)

  • MUST NOT render user-provided HTML via:

    • v-html
    • innerHTML in render functions / JSX
    • direct DOM APIs (element.innerHTML, insertAdjacentHTML) unless the HTML is trusted or robustly sanitized and the risk is explicitly accepted. (Vue.js)

Insecure patterns:

  • <div v-html="userProvidedHtml"></div>
  • h('div', { innerHTML: userProvidedHtml })
  • <div innerHTML={userProvidedHtml}></div>
  • el.innerHTML = untrusted

Detection hints:

  • Search: v-html, innerHTML, insertAdjacentHTML, DOMParser, document.write.

Fix:

  • Render untrusted content as text (interpolation).
  • If HTML rendering is required (e.g., Markdown), sanitize with a well-maintained HTML sanitizer and apply defense-in-depth (CSP, Trusted Types). (Vue.js)

Notes:

  • Vue’s docs explicitly warn that user-provided HTML is never “100% safe” unless sandboxed or strictly self-only exposure. (Vue.js)

VUE-XSS-002: Never use non-trusted templates (client-side template/code injection)

Severity: Critical

Required:

  • MUST NOT use non-trusted content as a Vue component template.
  • MUST treat “user can write a Vue template” as “user can execute arbitrary JavaScript in your app”, and potentially in SSR contexts too. (Vue.js)
  • SHOULD prefer the runtime-only build (templates compiled at build time) and avoid shipping the runtime compiler unless you have a vetted need.

Insecure patterns:

  • createApp({ template: '<div>' + userProvidedString + '</div>' }).mount(...)
  • Storing templates in DB and compiling/rendering them in the browser.
  • Admin/CMS features that allow entering Vue template syntax.

Detection hints:

  • Search: template: where the value is not a static string.
  • Search: @vue/compiler-dom, compile(, “runtime compiler” build selection, dynamic SFC compilation.
  • Search for “template editor”, “custom template”, “theme HTML” features.

Fix:

  • Treat templates as code: keep them developer-controlled.
  • If end-user customization is required, use a safe format (restricted Markdown subset) rendered via a sanitizer, or isolate in a sandboxed iframe.

VUE-XSS-003: Do not mount Vue onto DOM that may contain user-provided server-rendered HTML

Severity: Medium

Required:

  • MUST NOT mount Vue on nodes that may contain server-rendered and user-provided content (because attacker-controlled HTML that is “safe as HTML” may become unsafe as a Vue template). (Vue.js)
  • SHOULD mount Vue into a “sterile” root element and render the app’s DOM from Vue-controlled templates/components.

Insecure patterns:

  • Server renders user content into #app, then Vue mounts on #app and compiles/interprets that DOM as a template.
  • “Sprinkling Vue” on large server-rendered pages that include user-generated content.

Detection hints:

  • Check server templates (e.g., Rails/Django/Express templates) for user HTML inserted inside the Vue mount root.
  • Look for mount('#app') where #app includes server-rendered UGC.

Fix:

  • Move user-rendered HTML outside the Vue mount root, or render it in a safe way (text/sanitized HTML) from Vue components.

VUE-XSS-004: Prevent URL injection in bindings and navigations

Severity: High

Required:

  • MUST validate/sanitize any user-influenced URL before binding to navigation sinks (href, src, action, window.location, window.open, router navigation to external).
  • MUST specifically prevent javascript: URL execution in bindings like <a :href="userProvidedUrl">. (Vue.js)
  • SHOULD validate protocol and destination (allowlist https: and expected hosts; allow mailto:/tel: only if intended).

Insecure patterns:

  • <iframe :src="userProvidedUrl">
  • window.location = route.query.next
  • window.open(userProvidedUrl)

Detection hints:

  • Search: :href=, :src=, window.location, location.href, window.open, router.push( with untrusted input.
  • Look for next, return_to, redirect query params.

Fix:

  • Prefer internal navigation via route names/paths you control.
  • For external URLs: parse with new URL(...), allowlist protocol/host, reject javascript: and other dangerous schemes.
  • Sanitize and validate on the backend before storing user URLs (Vue docs explicitly recommend backend sanitization). (Vue.js)

VUE-XSS-005: Prevent style/CSS injection and UI redress

Severity: Low

Required:

  • MUST NOT bind attacker-controlled CSS strings broadly (e.g., :style="userProvidedStyles").
  • SHOULD use Vue’s style object syntax and only allow safe, specific properties if user customization is needed. (Vue.js)
  • SHOULD isolate “user can control layout/CSS” features inside sandboxed iframes.

Insecure patterns:

  • :style="userProvidedStyles" where styles are attacker-controlled.
  • Rendering user-provided <style> content (even if Vue blocks some patterns, don’t try to work around it).

Detection hints:

  • Search: :style=" bound to non-constant variables that originate from API/user content.
  • Search for “custom CSS”, “theme editor”, “profile CSS”.

Fix:

  • Allowlist properties and values; avoid raw style strings.
  • Use sandboxed iframes for rich user customization.

VUE-XSS-006: Never bind user-provided JavaScript into event handler attributes

Severity: Critical

Required:

  • MUST NOT bind attacker-provided strings into event handler attributes (e.g., onclick, onfocus, etc.).
  • MUST treat “user-provided JS” as unsafe unless sandboxed and self-only exposure is guaranteed. (Vue.js)

Insecure patterns:

  • <div :onclick="userProvidedString">
  • <a :onmouseenter="userProvidedString">

Detection hints:

  • Search: :on followed by event attribute names (:onclick, :onload, etc.).
  • Search for setAttribute('on patterns.

Fix:

  • Use real event listeners with developer-controlled handlers.
  • If you truly need user scripting, isolate it (sandboxed iframe + strict boundaries).

VUE-ROUTER-001: Do not treat client-side route guards as authorization

Severity: High

Required:

  • MUST NOT rely on Vue Router guards, UI hiding, or client-side checks to enforce authorization.
  • MUST enforce authorization on the backend for every privileged action and sensitive data response. (OWASP Cheat Sheet Series)

Insecure patterns:

  • “Admin route is protected because beforeEach checks user.isAdmin.”
  • Sensitive API endpoints that assume “the frontend won’t call this unless allowed.”

Detection hints:

  • Search router.beforeEach for role-based gating and see if the backend is also enforcing.
  • Look for “security by route meta” patterns (meta.requiresAdmin) with no server corroboration.

Fix:

  • Keep route guards as UX only (reduce accidental access), but enforce real checks server-side.

VUE-ROUTER-002: Prevent open redirects and unsafe “return_to/next” handling

Severity: Low

Required:

  • MUST validate redirect destinations derived from untrusted input (next, return_to, redirect).
  • SHOULD allow only same-site relative paths or an explicit allowlist of destinations.
  • MUST NOT allow non http / https protos (such as javascript:)

Insecure patterns:

  • router.push(route.query.next as string)
  • window.location.href = route.query.redirect

Detection hints:

  • Search for route.query.next, route.query.redirect, return_to, continue, callback.
  • Trace the value into router/window navigation sinks.

Fix:

  • Allow only relative paths starting with / (and reject //host, javascript:, etc.).
  • Prefer redirecting to named routes you control.

Notes:

  • Even Vue’s docs note that sanitized URLs still may not guarantee safe destinations. (Vue.js)

VUE-AUTH-001: Token storage must assume XSS is possible

Severity: Low

Required:

  • MUST assume any token accessible to JavaScript can be stolen via XSS.
  • SHOULD prefer HttpOnly cookies (set by the backend) for session tokens, combined with CSRF protections where relevant. (Vue.js)
  • SHOULD avoid storing long-lived tokens (especially refresh tokens) in localStorage/sessionStorage.

Insecure patterns:

  • localStorage.setItem('token', ...) for long-lived bearer tokens.
  • Storing refresh tokens in JS-accessible storage.

Detection hints:

  • Search: localStorage, sessionStorage, indexedDB, persist, pinia-plugin-persistedstate.
  • Identify whether stored values are auth/session material.

Fix:

  • Prefer backend-managed sessions via HttpOnly cookies.
  • If bearer tokens are unavoidable, keep them short-lived, stored in memory, and rotate frequently; combine with strong XSS mitigations (CSP, Trusted Types, strict sanitization). (OWASP Cheat Sheet Series)

VUE-CSRF-001: Coordinate with the backend for CSRF when using cookies

Severity: High (for cookie-authenticated state-changing requests)

NOTE: If the application is not using cookie based authentication (for example if it passes an Authorization header), then CSRF is not a concern

Required:

  • If API requests include cookies (credentials: 'include' / withCredentials: true) and cookies authenticate the user, MUST include CSRF protections coordinated with the backend (token/header patterns, Origin checks, SameSite cookies as defense-in-depth). (Vue.js)
  • MUST NOT “solve CORS/CSRF errors” by disabling protections on the backend or using mode: 'no-cors' on the frontend.

Insecure patterns:

  • fetch(url, { credentials: 'include', method: 'POST', body: ... }) with no CSRF token/header usage anywhere.
  • Enabling cross-origin credentialed requests without strict origin allowlists (backend-side).

Detection hints:

  • Search: credentials: 'include', withCredentials, xsrf, csrf, X-CSRF-Token, X-XSRF-TOKEN.
  • Look at API wrapper modules for headers and cookie settings.

Fix:

  • Implement backend-issued CSRF tokens and require them on state-changing requests.
  • Keep cookies SameSite=Lax/Strict where compatible and verify Origin/Referer where appropriate (backend-driven). (OWASP Cheat Sheet Series)

Notes:

  • Vue’s docs explicitly say CSRF is primarily backend-addressed but recommends coordinating on CSRF token submission. (Vue.js)

VUE-HTTP-001: Do not put secrets in URLs; avoid leaking sensitive data in navigation/logs

Severity: Medium

Required:

  • MUST NOT place tokens/secrets in query strings or fragments (they leak via logs, referrers, browser history).
  • SHOULD avoid logging sensitive values to console in production.

Insecure patterns:

  • /?token=..., /#access_token=... used beyond short-lived OAuth handoff.
  • console.log(userSession) that includes tokens/PII.

Detection hints:

  • Search for token= in router parsing, auth callback handlers, and analytics logs.
  • Search for console.log( around auth code.

Fix:

  • Use Authorization headers or HttpOnly cookies.
  • Scrub logs; gate debug logs behind dev-only checks.

VUE-HEADERS-001: Require security headers at the deployment layer

Severity: Medium

Required:

  • SHOULD deploy a CSP (Content-Security-Policy) suitable for your Vue app.
  • SHOULD deploy clickjacking defenses (CSP frame-ancestors and/or X-Frame-Options) unless intentional embedding is required.
  • SHOULD deploy X-Content-Type-Options: nosniff, plus other headers as appropriate (Referrer-Policy, Permissions-Policy). (OWASP Cheat Sheet Series)

Insecure patterns:

  • No evidence of headers in server/CDN config for an app with UGC or rich HTML rendering.
  • CSP includes unsafe-inline/unsafe-eval without strong justification.

Detection hints:

  • Look for hosting config: nginx, Netlify/Vercel headers config, CloudFront/Cloudflare rules.
  • If absent in repo, flag as “verify at edge”.

Fix:

  • Set headers at the edge or in the server. Start with a conservative CSP and tighten.

VUE-CSP-001: Use Trusted Types and DOM XSS hardening when feasible

Severity: Low

Required:

  • For apps with significant DOM injection surface (rich text, plugins, v-html), SHOULD consider enabling Trusted Types to reduce DOM XSS risk. (web.dev)
  • SHOULD treat Trusted Types as defense-in-depth, not a replacement for sanitization.

Insecure patterns:

  • Frequent use of innerHTML/v-html without sanitization or CSP hardening.

Detection hints:

  • Search: v-html, innerHTML, insertAdjacentHTML.
  • Check CSP for require-trusted-types-for 'script' usage (if headers are in repo).

Fix:

  • Reduce/centralize HTML injection, sanitize inputs, and add Trusted Types policies where appropriate.

VUE-THIRDPARTY-001: Avoid dynamic third-party script injection; prefer static, vetted loading

Severity: Low

Required:

  • MUST NOT inject <script src="..."> where the URL is user-controlled.
  • SHOULD treat third-party widgets/analytics as supply-chain risk; load only from vetted, pinned sources.

Insecure patterns:

  • const s=document.createElement('script'); s.src = userProvidedUrl; ...
  • “Plugin marketplace” that loads arbitrary remote scripts.

Detection hints:

  • Search: createElement('script'), .src =, appendChild(script).
  • Search for “loadExternalScript”, “injectScript”, “cdnUrl”.

Fix:

  • Bundle dependencies, or allowlist strict origins and enforce integrity (see SRI rule).
  • Consider sandboxed iframes for untrusted third-party UI.

VUE-SRI-001: Use Subresource Integrity for CDN-hosted scripts/styles

Severity: Low

Required:

  • If loading scripts/styles from a CDN, SHOULD use Subresource Integrity (integrity attribute) with appropriate crossorigin configuration. (MDN Web Docs)
  • SHOULD prefer self-hosting or bundling over runtime CDN dependencies for security-critical code.

Insecure patterns:

  • <script src="https://cdn.example/..."> with no integrity.
  • Remote script URLs that can change content without version pinning.

Detection hints:

  • Search index.html and server templates for https:// script/style tags.
  • Check for integrity=.

Fix:

  • Add SRI hashes (and pin versions), or bundle assets with your build.

VUE-SUPPLY-001: Dependency and patch hygiene is mandatory

Severity: Low

Required:

  • SHOULD keep Vue and official companion libraries updated; Vue explicitly recommends using latest versions to remain as secure as possible. (Vue.js)
  • MUST respond to security advisories promptly.
  • SHOULD pin dependencies and keep lockfiles committed (to reduce drift in production artifacts).

Insecure patterns:

  • Outdated major versions with known CVEs.
  • No lockfile in repo; wide semver ranges for critical deps.
  • Ignoring advisories for template/rendering/compiler packages.

Detection hints:

  • Inspect package.json, lockfiles, CI install commands.
  • Search for npm audit disabled, “ignore vulnerabilities” scripts.

Fix:

  • Upgrade dependencies and add regression tests around the impacted behavior.
  • Add dependency scanning in CI.

VUE-SSR-001: SSR adds additional trust boundaries; treat state injection as XSS-sensitive

Severity: Medium

Required:

  • When using SSR, MUST treat anything injected into the HTML document (initial state, serialized data, inline scripts) as XSS-sensitive.
  • MUST keep the “trusted templates only” rule even stricter, because unsafe templates can lead to server-side execution during rendering. (Vue.js)
  • SHOULD follow Vue SSR documentation and best practices for SSR security. (Vue.js)

Insecure patterns:

  • Concatenating untrusted strings into SSR templates.
  • Injecting JSON into <script> blocks without robust escaping/serialization controls.

Detection hints:

  • Search server code for __INITIAL_STATE__, window.__*STATE__, template concatenation, and SSR render pipelines.
  • Trace untrusted data into those sinks.

Fix:

  • Use safe serialization patterns recommended by your SSR stack.
  • Avoid rendering untrusted HTML; sanitize or isolate.

5) Practical scanning heuristics (how to “hunt”)

When actively scanning, use these high-signal patterns:

  • Dev/preview servers in production:

    • npm run dev, vite, vite preview, vue-cli-service serve (vitejs)
  • Secrets exposure:

    • .env, .env.production, .env.*.local, VITE_, import.meta.env, hard-coded API_KEY / SECRET (vitejs)
  • XSS sinks:

    • v-html, innerHTML, insertAdjacentHTML, DOMParser, document.write (Vue.js)
  • Client-side template injection:

    • template: concatenation, compile(, runtime compiler usage, mounting on non-sterile DOM (Vue.js)
  • URL injection / open redirects:

    • :href="..." / :src="..." from user data
    • javascript: occurrences
    • route.query.next / redirect / return_to flowing into router.push or window.location (Vue.js)
  • Style injection:

    • :style="userProvidedStyles" or user-driven theme CSS (Vue.js)
  • Token storage:

    • localStorage.setItem('token'...), persisted auth stores, refresh tokens in JS-accessible storage
  • CSRF integration red flags:

    • credentials: 'include' / withCredentials: true without any CSRF header/token handling (Vue.js)
  • Third-party scripts:

    • dynamic script injection (createElement('script')), CDN scripts without SRI (MDN Web Docs)
  • External links security:

    • target="_blank" without rel="noopener"/noreferrer (still recommended for legacy and explicitness) (MDN Web Docs)

Always try to confirm:

  • data origin (untrusted vs trusted)
  • sink type (HTML/DOM insertion, template compilation, URL navigation, style injection, script injection)
  • protective controls present (sanitization, allowlists, CSP/Trusted Types, backend validation)

6) Sources (accessed 2026-01-27)

Primary Vue documentation:

  • Vue Docs: Security — https://vuejs.org/guide/best-practices/security (Vue.js)
  • Vue Docs: Template Syntax (security warning about in-DOM templates) — https://vuejs.org/guide/essentials/template-syntax (Vue.js)
  • Vue Docs: Production Deployment — https://vuejs.org/guide/best-practices/production-deployment (Vue.js)
  • Vue Docs: Feature Flags — https://link.vuejs.org/feature-flags (Vue.js)

Vite documentation (common Vue tooling):

  • Vite Docs: Env Variables and Modes (VITE_* exposure + security notes) — https://vite.dev/guide/env-and-mode (vitejs)
  • Vite Docs: CLI (vite preview not designed for production) — https://vite.dev/guide/cli (vitejs)
  • Vite Docs: Server Options (server.host can listen on public addresses) — https://vite.dev/config/server-options (vitejs)

OWASP and web platform hardening references:

  • OWASP Cheat Sheet Series: XSS Prevention — https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html (Vue.js)
  • OWASP Cheat Sheet Series: CSRF Prevention — https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html (OWASP Cheat Sheet Series)
  • OWASP Cheat Sheet Series: Authorization — https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html (OWASP Cheat Sheet Series)
  • OWASP Cheat Sheet Series: HTTP Headers — https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html (OWASP Cheat Sheet Series)
  • HTML5 Security Cheat Sheet (referenced by Vue) — https://html5sec.org/ (Vue.js)

Browser/platform references:

  • MDN: rel="noopener" — https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/rel/noopener (MDN Web Docs)
  • MDN: Subresource Integrity — https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity (MDN Web Docs)
  • web.dev: Trusted Types — https://web.dev/trusted-types/ (web.dev)

Source: SKILL.md on GitHub

1 alert17d5 checks · Risk SAFE
  • Gen Agent Trust Hub17d

    This skill provides security best practices and auditing guidance for various programming languages and frameworks. It is designed to assist developers in writing secure-by-default code and identifying vulnerabilities in existing projects. The skill functions as a comprehensive knowledge base and does not perform any risky actions or command executions.

  • Socket17d

    No alerts

  • Snyk17d

    Risk: LOW · No issues

  • Runlayer7mo

    12/13 files flagged

  • ZeroLeaks5mo

    1 finding · Score: 86/100

Signed by skilld at 5c8f1e2. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Activeupdated 8 months ago

README badge

README badge for openai/skills/security-best-practices

Identifies languages and frameworks in a codebase, loads language-specific security guidance from bundled references, and either writes secure code by default, passively flags vulnerabilities, or generates a prioritized security report with remediation steps. Supports Python, JavaScript/TypeScript, and Go; does not trigger for general code review or debugging.

Generated from the current SKILL.md.

What languages and frameworks does this skill support?
The skill supports Python, JavaScript/TypeScript, and Go. It checks a references directory for language and framework-specific security guidance files, and can also apply general security best practices if no specific guidance exists.
When should I trigger this skill?
Trigger it only when explicitly requested for security best practices guidance, a security review or report, or secure-by-default coding help. Do not trigger for general code review, debugging, or non-security tasks.
Can this skill generate a security report?
Yes. It can produce a prioritized markdown report organized by severity, with findings numbered for reference, line numbers for code locations, and an executive summary. After the report is written, you can ask it to begin fixing individual findings one at a time.
Does this skill check both frontend and backend code?
Yes. For web applications with both frontend and backend, it identifies and checks security guidance for both. If the frontend framework is unspecified, it can reference general JavaScript frontend security guidance.
Can I override security best practices in my project?
Yes. If your project documentation or prompts require overriding a best practice, the skill will respect that, though it may report the override and suggest documenting why the deviation is necessary.

Generated from the current SKILL.md. These answers refresh after source changes.