Vue.js Web Security Spec (Vue 3.x, TypeScript/JavaScript, common tooling: Vite)
This document is designed as a security spec that supports:
- Secure-by-default code generation for new Vue code.
- 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-htmlas 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:
- Build/deploy entrypoints and hosting config (Docker, CI, static hosting, SSR server).
- Secrets exposure (env usage,
.env*, hard-coded keys). (vitejs) - XSS surface: templates,
v-html/innerHTML, URL/style injection, DOM APIs. (Vue.js) - Auth/session handling in the browser (token storage, credentialed requests, CSRF integration). (Vue.js)
- Routing/navigation (open redirects, “return_to/next”, unsafe external navigation). (Vue.js)
- Third-party scripts and content (CDN assets, analytics, widgets, iframes). (Vue.js)
- Security headers and browser hardening expectations (CSP, clickjacking). (Vue.js)
- 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 fromwindow.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:
postMessageinputs. - 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 previewas 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, orvite previewas 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.jsbuilds 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.jsvariants 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
.envfiles committed to repoimport.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.*.localshould be gitignored and thatVITE_*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
envPrefixstrict and explicit.
Insecure patterns:
- Setting
envPrefixto 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.*forenvPrefix. - Look for
define: { 'process.env': ... }or manual injection intowindow.__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-htmlinnerHTMLin 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#appand 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#appincludes 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; allowmailto:/tel:only if intended).
Insecure patterns:
<iframe :src="userProvidedUrl">window.location = route.query.nextwindow.open(userProvidedUrl)
Detection hints:
- Search:
:href=,:src=,window.location,location.href,window.open,router.push(with untrusted input. - Look for
next,return_to,redirectquery params.
Fix:
- Prefer internal navigation via route names/paths you control.
- For external URLs: parse with
new URL(...), allowlist protocol/host, rejectjavascript: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:
:onfollowed by event attribute names (:onclick,:onload, etc.). - Search for
setAttribute('onpatterns.
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
beforeEachchecksuser.isAdmin.” - Sensitive API endpoints that assume “the frontend won’t call this unless allowed.”
Detection hints:
- Search
router.beforeEachfor 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/httpsprotos (such asjavascript:)
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/Strictwhere 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-ancestorsand/orX-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-evalwithout 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-htmlwithout 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 (
integrityattribute) with appropriatecrossoriginconfiguration. (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 nointegrity.- Remote script URLs that can change content without version pinning.
Detection hints:
- Search
index.htmland server templates forhttps://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 auditdisabled, “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-codedAPI_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 datajavascript:occurrencesroute.query.next/redirect/return_toflowing intorouter.pushorwindow.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: truewithout any CSRF header/token handling (Vue.js)
Third-party scripts:
- dynamic script injection (
createElement('script')), CDN scripts without SRI (MDN Web Docs)
- dynamic script injection (
External links security:
target="_blank"withoutrel="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 previewnot designed for production) —https://vite.dev/guide/cli(vitejs) - Vite Docs: Server Options (
server.hostcan 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)