Skip to main content

Security & Validation Auditing

Functions for auditing security headers, detecting frameworks, checking DOM security, validating forms, and identifying potential vulnerabilities.

auditSecurityHeaders

Check security-related headers and meta tags visible from the client side.

window.__devtool.auditSecurityHeaders()

Returns:

{
headers: {
csp: {
present: true,
value: "default-src 'self'; script-src 'self' 'unsafe-inline'",
source: "meta-tag"
},
frameProtection: { present: true },
https: { present: true, protocol: "https:" },
mixedContent: {
present: false,
count: 0,
details: { scripts: [], stylesheets: [], images: [], iframes: [] }
},
referrerPolicy: { present: true, value: "strict-origin-when-cross-origin" }
},
issues: [
{
type: "missing-frame-protection",
severity: "info",
message: "No frame-ancestors directive in CSP",
fix: "Add frame-ancestors directive to prevent clickjacking"
}
],
recommendations: [...],
score: 85,
rating: "good",
timestamp: 1699999999999
}

Issues Detected:

TypeSeverityDescription
missing-cspwarningNo Content-Security-Policy meta tag
missing-frame-protectioninfoNo frame-ancestors in CSP
no-httpserrorPage served over HTTP (non-localhost)
mixed-content-activeerrorScripts/stylesheets loaded over HTTP
mixed-content-passivewarningImages/iframes loaded over HTTP

observeCSPViolations

Monitor Content Security Policy violations in real-time.

window.__devtool.observeCSPViolations(callback?)

Parameters:

  • callback (function): Called on each violation with violation object

Returns:

{
stop: function() { /* Returns { violations, count } */ },
getViolations: function() { /* Returns current violations array */ }
}

Violation Object:

{
blockedURI: "https://evil.com/script.js",
violatedDirective: "script-src",
originalPolicy: "default-src 'self'",
sourceFile: "https://example.com/page.html",
lineNumber: 42,
columnNumber: 15,
timestamp: 1699999999999
}

Example:

const observer = window.__devtool.observeCSPViolations(v => {
console.log('CSP violation:', v.violatedDirective, v.blockedURI)
})

// Later...
const results = observer.stop()
console.log(`Total violations: ${results.count}`)

auditDOMSecurity

Audit the DOM for security issues like inline scripts, event handlers, and dangerous patterns.

window.__devtool.auditDOMSecurity()

Returns:

{
issues: [
{
type: "inline-scripts",
severity: "warning",
message: "5 inline script(s) found",
fix: "Move scripts to external files and use strict CSP"
},
{
type: "javascript-urls",
severity: "error",
message: "2 javascript: URL(s) found",
fix: "Replace javascript: URLs with proper event handlers"
}
],
dangerousElements: {
inlineScripts: [
{ selector: "script:nth-of-type(3)", length: 1250, preview: "var config = {...}" }
],
inlineEventHandlers: [
{ selector: "button.submit", attribute: "onclick", value: "submitForm()" }
],
javascriptURLs: [
{ selector: "a.legacy-link", attribute: "href", value: "javascript:void(0)" }
],
dangerousAttributes: [
{ selector: "div.content", attribute: "srcdoc", length: 500 }
]
},
summary: {
inlineScripts: 5,
inlineEventHandlers: 12,
javascriptURLs: 2,
dangerousAttributes: 1,
total: 20
},
score: 65,
rating: "needs-improvement",
timestamp: 1699999999999
}

Issues Detected:

TypeSeverityDescription
inline-scriptswarningInline <script> tags (XSS vectors)
inline-event-handlerswarningonclick, onload, etc. attributes
javascript-urlserrorjavascript: URLs in href/src/action
dangerous-attributesinfosrcdoc, data-html attributes

detectFramework

Detect JavaScript frameworks and libraries used on the page.

window.__devtool.detectFramework()

Returns:

{
frameworks: [
{ name: "React", detected: true, version: "18.2.0", devToolsInstalled: true },
{ name: "Next.js", detected: true, buildId: "abc123" },
{ name: "jQuery", detected: true, version: "3.6.0" }
],
count: 3,
primary: "React",
timestamp: 1699999999999
}

Detected Frameworks:

FrameworkDetection Method
Reactwindow.React, [data-reactroot], DevTools hook
Vuewindow.Vue, [data-v-], window.__VUE__
Angularwindow.ng, [ng-version], [_nghost]
AngularJSwindow.angular (legacy)
Svelte[class*="svelte-"]
Next.jswindow.__NEXT_DATA__, #__next
Nuxtwindow.__NUXT__, #__nuxt
jQuerywindow.jQuery, window.$
Preactwindow.preact
Alpine.jswindow.Alpine
htmxwindow.htmx

auditFrameworkQuality

Audit framework-specific security and quality issues.

window.__devtool.auditFrameworkQuality()

Returns:

{
framework: { /* detectFramework() results */ },
issues: [
{
type: "react-dev-build",
severity: "error",
message: "React development build detected in production",
fix: "Use production build for better performance and security",
details: { src: "https://example.com/react.development.js" }
},
{
type: "vue-v-html",
severity: "warning",
message: "3 element(s) using v-html directive",
fix: "Sanitize content before using v-html or use v-text instead",
details: [".content", ".preview", ".description"]
},
{
type: "jquery-vulnerable",
severity: "warning",
message: "jQuery 3.4.1 has known XSS vulnerabilities",
fix: "Upgrade to jQuery 3.5.0 or later"
}
],
patterns: {
react: { devMode: true, strictMode: false },
vue: { devToolsEnabled: true },
jquery: { version: "3.4.1", modern: true }
},
recommendations: [...],
score: 72,
rating: "needs-improvement",
timestamp: 1699999999999
}

Framework-Specific Issues:

TypeFrameworkSeverityDescription
react-dev-buildReacterrorDevelopment build in production
vue-v-htmlVuewarningUsing v-html (potential XSS)
angularjs-legacyAngularJSwarningAngularJS 1.x is end of life
angularjs-bind-htmlAngularJSerrorng-bind-html usage
jquery-vulnerablejQuerywarningjQuery < 3.5.0 vulnerabilities

auditFormSecurity

Audit forms for security and validation issues.

window.__devtool.auditFormSecurity()

Returns:

{
forms: [
{
selector: "form#login",
action: "https://example.com/auth",
method: "post",
hasValidation: true,
hasCSRF: true,
autocomplete: "on",
fields: [
{ type: "email", name: "email", hasValidation: true },
{ type: "password", name: "password", hasValidation: true, isPassword: true }
]
}
],
issues: [
{
type: "missing-csrf",
severity: "warning",
message: "POST form without CSRF token",
fix: "Add CSRF token to prevent cross-site request forgery",
element: "form#contact"
},
{
type: "sensitive-autocomplete",
severity: "warning",
message: "Sensitive field \"credit_card\" should disable autocomplete",
fix: "Add autocomplete=\"off\" to sensitive fields",
element: "input#credit_card"
}
],
summary: {
total: 3,
withValidation: 2,
withAutocomplete: 3,
withCSRF: 2,
passwordFields: 1,
sensitiveFields: 1
},
score: 78,
rating: "needs-improvement",
timestamp: 1699999999999
}

Issues Detected:

TypeSeverityDescription
missing-csrfwarningPOST form without CSRF token
insecure-form-actionerrorForm submits to HTTP URL
password-autocompleteinfoPassword without specific autocomplete
sensitive-autocompletewarningSensitive field without autocomplete=off

auditExternalResources

Audit external scripts, iframes, and stylesheets for security issues.

window.__devtool.auditExternalResources()

Returns:

{
scripts: [
{
src: "https://cdn.example.com/lib.js",
isExternal: true,
hasIntegrity: true,
crossOrigin: "anonymous",
async: true,
defer: false
}
],
iframes: [
{
src: "https://embed.example.com/widget",
sandbox: "allow-scripts allow-same-origin",
allow: "fullscreen",
loading: "lazy"
}
],
stylesheets: [
{ href: "https://cdn.example.com/style.css", hasIntegrity: false }
],
issues: [
{
type: "missing-sri",
severity: "warning",
message: "External script without Subresource Integrity (SRI)",
fix: "Add integrity attribute with hash of script content",
resource: "https://cdn.example.com/analytics.js"
},
{
type: "unsandboxed-iframe",
severity: "warning",
message: "External iframe without sandbox attribute",
fix: "Add sandbox attribute to restrict iframe capabilities",
resource: "https://ads.example.com/banner"
}
],
summary: {
totalScripts: 8,
externalScripts: 3,
withIntegrity: 2,
crossOriginScripts: 3,
iframes: 2,
sandboxedIframes: 1
},
score: 76,
rating: "needs-improvement",
timestamp: 1699999999999
}

Issues Detected:

TypeSeverityDescription
missing-sriwarningExternal script without integrity hash
missing-sri-cssinfoExternal stylesheet without integrity
unsandboxed-iframewarningExternal iframe without sandbox

auditPrototypePollution

Check for prototype pollution vulnerabilities and best practices.

window.__devtool.auditPrototypePollution()

Returns:

{
vulnerable: false,
tests: [
{
name: "Object.prototype frozen",
passed: false,
message: "Prototype is not frozen"
}
],
issues: [
{
type: "prototype-not-frozen",
severity: "info",
message: "Object.prototype is not frozen",
fix: "Consider freezing prototypes: Object.freeze(Object.prototype)"
}
],
recommendations: [
"Use Object.create(null) for dictionary objects",
"Validate and sanitize all user input before using as object keys",
"Consider using Map instead of plain objects for dynamic keys",
"Freeze Object.prototype in security-critical applications"
],
timestamp: 1699999999999
}

auditSecurity

Comprehensive security audit combining all security checks.

window.__devtool.auditSecurity()

Returns:

{
headers: { /* auditSecurityHeaders results */ },
domSecurity: { /* auditDOMSecurity results */ },
framework: { /* auditFrameworkQuality results */ },
forms: { /* auditFormSecurity results */ },
resources: { /* auditExternalResources results */ },
prototype: { /* auditPrototypePollution results */ },
summary: {
frameworkDetected: "React",
totalIssues: 12,
criticalIssues: 2,
httpsEnabled: true,
cspEnabled: true
},
issues: [ /* all issues from all audits */ ],
criticalIssues: [ /* only error severity issues */ ],
overallScore: 75,
grade: "C", // A (90+), B (80-89), C (70-79), D (60-69), F (<60)
timestamp: 1699999999999
}

Score Weights:

ComponentWeight
Security Headers25%
DOM Security25%
Form Security20%
Framework Quality15%
External Resources15%

loadDOMPurify

Load DOMPurify library from CDN for HTML sanitization.

window.__devtool.loadDOMPurify()

Returns: Promise that resolves with the DOMPurify object.

Example:

window.__devtool.loadDOMPurify().then(DOMPurify => {
const clean = DOMPurify.sanitize('<img src=x onerror=alert(1)>')
console.log(clean) // '<img src="x">'
})

sanitizeHTML

Sanitize HTML using DOMPurify (loads on demand).

window.__devtool.sanitizeHTML(dirty, options?)

Parameters:

  • dirty (string): HTML string to sanitize
  • options (object): DOMPurify configuration options

Returns: Promise

{
clean: "<p>Safe content</p>",
removed: [{ element: "script", ... }],
timestamp: 1699999999999
}

Example:

window.__devtool.sanitizeHTML('<div onclick="alert(1)">Hello</div>')
.then(result => {
console.log(result.clean) // '<div>Hello</div>'
})

// With options
window.__devtool.sanitizeHTML(html, { ALLOWED_TAGS: ['b', 'i', 'em'] })

checkXSSRisk

Check if a string contains potential XSS patterns.

window.__devtool.checkXSSRisk(input)

Parameters:

  • input (string): String to check for XSS patterns

Returns:

{
input: "<script>alert(1)</script>...",
hasRisk: true,
risks: [
{ type: "script-tag", severity: "high", pattern: "/<script[\\s>]/i" }
],
highRisk: true,
timestamp: 1699999999999
}

Patterns Detected:

TypeSeverityDescription
script-taghigh<script> tags
event-handlerhighon*= event handlers
javascript-urlhighjavascript: URLs
data-urlmediumdata: URLs with base64
vbscript-urlhighvbscript: URLs
expressionmediumCSS expressions
evalhigheval() calls
document-writemediumdocument.write
innerHTMLmedium.innerHTML =
fromCharCodelowfromCharCode obfuscation
svg-onloadhigh<svg onload=...>
img-onerrorhigh<img onerror=...>
iframe-srcmedium<iframe src=...>

Common Patterns

Pre-Deploy Security Check

async function securityCheck() {
const audit = window.__devtool.auditSecurity()

const blockers = []

// Critical issues block deployment
if (audit.criticalIssues.length > 0) {
blockers.push(`${audit.criticalIssues.length} critical security issues`)
}

// No HTTPS in production
if (!audit.headers.headers.https.present) {
blockers.push('HTTPS not enabled')
}

// Dev build in production
if (audit.framework.issues.some(i => i.type === 'react-dev-build')) {
blockers.push('React development build detected')
}

return {
pass: blockers.length === 0,
grade: audit.grade,
score: audit.overallScore,
blockers: blockers
}
}

Monitor CSP During Development

// Start monitoring
const cspObserver = window.__devtool.observeCSPViolations(violation => {
console.error('CSP Violation:', {
blocked: violation.blockedURI,
directive: violation.violatedDirective,
location: `${violation.sourceFile}:${violation.lineNumber}`
})
})

// ... run your application ...

// Stop and get summary
const results = cspObserver.stop()
if (results.count > 0) {
console.warn(`CSP needs adjustment: ${results.count} violations`)
console.table(results.violations)
}

User Input Validation

function validateUserInput(input) {
// Check for XSS patterns
const xssCheck = window.__devtool.checkXSSRisk(input)

if (xssCheck.highRisk) {
return { valid: false, reason: 'Potentially malicious content detected' }
}

// Sanitize if medium risk
if (xssCheck.hasRisk) {
return window.__devtool.sanitizeHTML(input).then(result => ({
valid: true,
sanitized: result.clean,
removed: result.removed.length
}))
}

return { valid: true, value: input }
}

Framework Security Check

function checkFrameworkSecurity() {
const audit = window.__devtool.auditFrameworkQuality()

console.log(`Primary framework: ${audit.framework.primary}`)
console.log(`Security score: ${audit.score}/100 (${audit.rating})`)

// Check for specific issues
const devBuild = audit.issues.find(i => i.type.includes('dev-build'))
if (devBuild) {
console.error('DEV BUILD IN PRODUCTION:', devBuild.details)
}

const vulnerableLib = audit.issues.find(i => i.type.includes('vulnerable'))
if (vulnerableLib) {
console.warn('VULNERABLE LIBRARY:', vulnerableLib.message)
}

// Vue-specific: check v-html usage
const vHtml = audit.issues.find(i => i.type === 'vue-v-html')
if (vHtml) {
console.warn('v-html usage detected:', vHtml.details)
}

return audit.issues
}

Performance Notes

  • auditSecurityHeaders is fast (queries meta tags only)
  • auditDOMSecurity scans all elements - may be slow on large DOMs
  • auditExternalResources queries all script/iframe/link elements
  • auditSecurity runs all audits - use individual functions for targeted checks
  • loadDOMPurify loads ~25KB from CDN on first call (cached after)
  • sanitizeHTML is async (waits for DOMPurify to load)

Security Considerations

  • These audits detect client-side patterns only
  • Server-side headers (HSTS, X-Frame-Options) aren't visible to client JS
  • Some issues can only be detected through HTTP response headers
  • Use browser DevTools Network tab for complete header inspection
  • Consider server-side security scanning for comprehensive coverage

See Also