Security Scanner
The Security Scanner is an advanced input sanitization and threat detection module for protecting your forms from malicious input. It detects multiple attack vectors including SQL Injection, XSS, NoSQL Injection, Path Traversal, and sensitive token leakage.
Overview
The Scanner class provides comprehensive protection by:
- Normalizing obfuscated input - Removes encoding layers that hide malicious code
- Detecting obfuscation attempts - Flags suspicious invisible characters
- Pattern-based threat detection - Identifies 5 major threat categories
- Customizable rules - Extend with organization-specific patterns
- Performance tuning - Early termination and targeted scanning options
Key Features
✅ Multi-Layer Normalization — Defeats URL encoding, HTML entities, JavaScript escapes, zero-width characters
✅ 5 Threat Categories — SQL Injection, NoSQL Injection, XSS, Path Traversal, Token Leakage
✅ Configurable Strictness — Adjust threat classification to match your security requirements
✅ HTML Context Awareness — Allows safe tags while blocking dangerous ones
✅ Detailed Recommendations — Actionable remediation advice for each threat
✅ Performance Optimized — Optional early termination and async scanning
✅ Zero Dependencies — Pure TypeScript/JavaScript, no external libraries
const { Scanner } = require('@gd3v/veli');
Quick Start
// Create a scanner with default settings (safe & balanced)
const scanner = new Scanner();
// Scan fields for all threat types
const result = scanner.scanAll([
{ name: 'username', value: 'john_doe', type: 'text' },
{ name: 'bio', value: '<p>Hello world</p>', type: 'html', allowedTags: ['p', 'br'] },
{ name: 'comment', value: "'; DROP TABLE users; --", type: 'text' }
]);
if (result.passed) {
console.log('All fields are secure!');
} else {
console.log('Security threats detected:', result.result);
}
Configuration
Creating a Scanner with Options
const scanner = new Scanner({
strictMode: false, // default: false
stopOnFirstThreat: false, // default: false
includeValueInResponse: false, // default: false
customPatterns: {} // default: {}
});
Configuration Parameters
strictMode (boolean, default: false)
Controls threat classification strictness.
- When
false: MEDIUM severity threats are reported as-is - When
true: MEDIUM severity threats are elevated to HIGH severity
Use cases:
- Set to
truefor high-security contexts (admin panels, financial data, healthcare) - Set to
falsefor user-generated content that needs flexibility (comments, bios)
Impact on scanning:
- Increases threat detection sensitivity
- May reduce false negatives but increases false positives
- Affects security score calculations
// High-security context
const adminScanner = new Scanner({ strictMode: true });
// User-generated content context
const userScanner = new Scanner({ strictMode: false });
stopOnFirstThreat (boolean, default: false)
Enables early termination on first threat detection.
- When
false: Scans all fields and collects all threats - When
true: Stops scanning after detecting the first threat
Use cases:
- Set to
truefor performance-critical APIs or real-time validation - Set to
falsefor comprehensive security reports showing all issues
Impact on scanning:
- Significantly improves performance when threats exist
- Reduces response time for high-volume form submissions
- Trade-off: Users see one threat at a time instead of all issues
Performance comparison:
// Fast: stops at first threat
const fastScanner = new Scanner({ stopOnFirstThreat: true });
// Result time: ~2-5ms for input with threats
// Thorough: collects all threats
const thoroughScanner = new Scanner({ stopOnFirstThreat: false });
// Result time: ~10-20ms for same input
includeValueInResponse (boolean, default: false)
Includes scanned field values in the response.
- When
false: Response contains only threat metadata - When
true: Response includes original field values
Use cases:
- Set to
truefor detailed logging and audit trails - Set to
falsefor privacy-sensitive deployments - Never enable in untrusted client-side code
Security considerations:
- Enables detailed debugging and incident analysis
- Increases response payload size (20-50% larger)
- Be cautious in production; sensitive data may be logged
// For logging and audit trails
const auditScanner = new Scanner({ includeValueInResponse: true });
// Response includes: { name: 'email', value: 'test@example.com', threats: [...] }
// For privacy (default)
const privateScanner = new Scanner({ includeValueInResponse: false });
// Response includes: { name: 'email', threats: [...] } (no value)
customPatterns (Record<ScannerType, Pattern[]>, default: {})
Extends or overrides threat detection patterns.
Allows adding organization-specific threat patterns or domain-specific rules without losing built-in patterns.
Supported scanner types:
"sqlInjection"- SQL injection patterns"noSqlInjection"- NoSQL/MongoDB injection patterns"xss"- Cross-Site Scripting patterns"pathTraversal"- Directory traversal patterns"tokenLeakage"- Sensitive credential patterns
Pattern structure:
interface Pattern {
pattern: RegExp; // Regex to match threats
type: string; // Unique threat identifier
severity: "HIGH" | "MEDIUM" | "LOW";
}
Examples:
// Add custom XSS pattern
const scanner = new Scanner({
customPatterns: {
xss: [
{
pattern: /myCustomFramework\.render\(/gi,
type: 'FRAMEWORK_EXEC',
severity: 'HIGH'
}
]
}
});
// Add custom SQL injection pattern
const scanner = new Scanner({
customPatterns: {
sqlInjection: [
{
pattern: /\bEXEC\b.*\bsp_/gi,
type: 'STORED_PROCEDURE_EXEC',
severity: 'HIGH'
}
]
}
});
// Multiple custom patterns
const scanner = new Scanner({
customPatterns: {
xss: [
{ pattern: /javascript:eval/gi, type: 'EVAL_EXEC', severity: 'HIGH' }
],
pathTraversal: [
{ pattern: /\.\.\./, type: 'TRIPLE_DOT', severity: 'MEDIUM' }
]
}
});
Threat Categories
1. SQL Injection
Detects: UNION SELECT, OR/AND conditions, stacked queries, time-based attacks, SQL comments
const result = scanner.scan([
{ name: 'query', value: "'; UNION SELECT * FROM users; --" }
], 'sqlInjection');
Detected patterns:
UNION SELECTjoinsOR 1=1conditions- SQL comments (
--,#,/* */) - Stacked queries (
;DROP TABLE) - Time-based delays (
SLEEP,BENCHMARK) - Schema probing (
information_schema)
2. NoSQL Injection
Detects: MongoDB operators, function injection, array injection, operator injection
const result = scanner.scan([
{ name: 'filter', value: '{"$where": "1==1"}' }
], 'noSqlInjection');
Detected patterns:
- MongoDB operators (
$where,$ne,$regex, etc.) - Function definitions in queries
- Object/array constructor abuse
3. Cross-Site Scripting (XSS)
Detects: Script tags, event handlers, javascript: protocol, data URIs, SVG attacks
const result = scanner.scan([
{ name: 'comment', value: '<img src=x onerror="alert(1)">', type: 'html' }
], 'xss');
Detected patterns:
- Script tags:
<script>, space-separated<s c r i p t>, nested variants - Event handlers:
onerror=,onclick=,onload=, etc. - Protocols:
javascript:,vbscript:,data: - Dangerous tags:
<iframe>,<embed>,<object>,<svg>, etc. - Encoded attempts:
%3Cscript,<script
4. Path Traversal
Detects: Directory traversal sequences, encoded variants, absolute paths
const result = scanner.scan([
{ name: 'file', value: '../../etc/passwd' }
], 'pathTraversal');
Detected patterns:
- Directory traversal:
../,..\, multiple levels - Encoded variants:
%2e%2e,%c0%af(Unicode normalization) - Absolute paths:
/etc/,/var/,C:\Windows\ - Null byte injection:
%00,\0
5. Token Leakage
Detects: JWT tokens, API keys, AWS credentials, private keys, database connections
const result = scanner.scan([
{ name: 'header', value: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' }
], 'tokenLeakage');
Detected patterns:
- JWT tokens:
eyJ...patterns - AWS credentials:
AKIAprefix keys,aws_secret_access_key - GitHub tokens:
ghp_,gho_prefixes - Stripe keys:
sk_live_,pk_live_ - API keys: Generic
api_key=patterns - Private keys: PEM formatted keys
- Database URIs: Connection strings
API Methods
scanAll(fields) - Comprehensive Security Scan
Scans fields against all threat types for complete security analysis.
const result = scanner.scanAll([
{ name: 'email', value: 'user@example.com', type: 'email' },
{
name: 'bio',
value: '<p>Developer</p>',
type: 'html',
allowedTags: ['p', 'br']
}
]);
Parameters:
fields(FieldInput[]): Array of fields to scan
Returns: ScanResult - Comprehensive results with security scores
When to use:
- Initial security analysis requiring all threat types
- General-purpose form validation
- When you don't know which threats are most likely
scan(fields, scannerType) - Targeted Threat Detection
Scans fields for a specific threat type to optimize performance.
// Check only for XSS threats
const result = scanner.scan(fields, 'xss');
// Check only for SQL injection
const result = scanner.scan(fields, 'sqlInjection');
// Check only for token leakage
const result = scanner.scan(fields, 'tokenLeakage');
Parameters:
fields(FieldInput[]): Array of fields to scanscannerType(ScannerType): One of:'sqlInjection''noSqlInjection''xss''pathTraversal''tokenLeakage'
Returns: ScanResult - Scan result using only the specified scanner
Use cases:
- Validate user comments for XSS only:
scan(comments, 'xss') - Check file uploads for path traversal:
scan(uploads, 'pathTraversal') - Scan database queries for SQL injection:
scan(queries, 'sqlInjection')
Throws:
Errorif scannerType is invalid
scanMultiple(fields, scannerTypes) - Multi-Type Threat Detection
NEW - Scans fields against multiple specified threat types for flexible security control.
// Check only for XSS and SQL injection (skip others)
const result = scanner.scanMultiple(fields, ['xss', 'sqlInjection']);
console.log(`Security Score: ${result.securityScore}`);
Parameters:
fields(FieldInput[]): Array of fields to scanscannerTypes(ScannerType[]): Array of threat types to check:'sqlInjection'- SQL injection detection'noSqlInjection'- NoSQL injection detection'xss'- Cross-Site Scripting detection'pathTraversal'- Directory traversal detection'tokenLeakage'- Credential leakage detection
Returns: ScanResult - Results with scanner property set to "multiple"
When to use:
- Check specific threats relevant to your business logic
- Optimize performance by excluding irrelevant categories
- Context-aware scanning (different threats for different fields)
- Reduce false positives from unused scanner types
Examples:
const scanner = new Scanner();
// Check for injection attacks only
const result = scanner.scanMultiple(fields, ['sqlInjection', 'noSqlInjection']);
if (!result.passed) {
result.result.forEach(field => {
if (field.threats.length > 0) {
console.log(`${field.name}: ${field.threats[0].type}`);
}
});
}
// API-specific scanning: SQL and path traversal (skip XSS/tokens)
const apiFields = [
{ name: 'query', value: userQuery, type: 'text' },
{ name: 'filepath', value: userPath, type: 'text' }
];
const result = scanner.scanMultiple(apiFields, ['sqlInjection', 'pathTraversal']);
// HTML content: only check relevant threats
const htmlContent = userBio;
const result = scanner.scanMultiple(
[{ name: 'bio', value: htmlContent, type: 'html' }],
['xss', 'tokenLeakage']
);
Throws:
TypeErrorifscannerTypesis not an array or is emptyErrorif any scanner type in the array is invalid
scanAsync(fields) - Asynchronous Scanning
Non-blocking version of scanAll() using Promises, ideal for large datasets.
// With async/await
const result = await scanner.scanAsync(largeFieldArray);
console.log(`Scan completed in ${result.duration}ms`);
// With .then()
scanner.scanAsync(fields)
.then(result => console.log('Scan complete:', result))
.catch(error => console.error('Scan error:', error));
Parameters:
fields(FieldInput[]): Array of fields to scan
Returns: Promise<ScanResult> - Resolves to scan results
When to use:
- Scanning 1000+ fields
- Background security checks
- Real-time validation in UI threads
- API endpoints with multiple form submissions
Complete Response Structures
Every Scanner method returns structured data. Here's the complete breakdown of all response types.
ScanResult (Top-Level Response)
The main response object returned by all scanning methods.
interface ScanResult {
securityScore: number; // 0-1 scale (0 = compromised, 1 = secure)
scanner: "all" | "multiple" | ScannerType; // Which scan method was used
passed: boolean; // true if no threats detected
duration: number; // Milliseconds taken to scan
result: FieldResult[]; // Per-field results
}
Example:
{
securityScore: 0.85,
scanner: "all",
passed: false,
duration: 12,
result: [
// FieldResult objects
]
}
Property descriptions:
-
securityScore: Normalized score from 0 to 11.0= No threats detected, completely secure0.7-0.9= Minor issues (LOW severity threats)0.3-0.6= Moderate issues (MEDIUM/HIGH mix)0.0-0.3= Critical threats (multiple HIGH)0.0= Multiple critical threats, severely compromised
-
scanner: Indicates which scanning method was used"all"=scanAll()was used (all 5 threat types)"multiple"=scanMultiple()was used with specific types"sqlInjection","xss", etc. =scan()was used with specific type
-
passed: Quick boolean to check if validation succeededtrue= No threats detected in any fieldfalse= At least one threat was found
-
duration: Useful for monitoring scanning performance- Time in milliseconds from start to finish
- Helps identify performance bottlenecks
-
result: Array of per-field analysis- One FieldResult object per input field
- Even if field has no threats, an entry exists
FieldResult (Per-Field Response)
Detailed results for each field scanned.
interface FieldResult {
name: string; // Field name/identifier
value?: string; // Original value (only if includeValueInResponse: true)
securityScore: number; // 0-1 score for this field
passed: boolean; // true if no threats in this field
threats: Threat[]; // Array of detected threats
}
Example:
{
name: "email",
securityScore: 1.0,
passed: true,
threats: [],
value: "user@example.com" // Only included if includeValueInResponse: true
}
Property descriptions:
-
name: Matches thenameproperty from input FieldInput- Used to identify which field has issues
- Must be unique within batch for clarity
-
value: Original scanned value (for debugging/logging)- Only included if
includeValueInResponse: truein config - Useful for audit trails and detailed logging
- Security note: Be careful logging sensitive data
- Only included if
-
securityScore: Field-specific security score (0-1)- Calculated independently from other fields
- Penalties applied for detected threats
- See Security Score Calculation
-
passed: Shortcut to check if field is secure- Equivalent to
threats.length === 0 - Quick way to filter clean vs problematic fields
- Equivalent to
-
threats: Array of Threat objects (empty if passed)- Each object describes a detected security issue
- Multiple threats possible in single field
- See Threat structure below
Threat (Individual Threat Details)
Information about each detected security threat.
interface Threat {
type: string; // Threat identifier (e.g., "SCRIPT_TAG")
severity: "HIGH" | "MEDIUM" | "LOW"; // Risk level
pattern: string; // Regex pattern that matched
matched: string; // Exact matched string from input
position: number; // Index position in normalized input
recommendation: string; // How to fix this threat
}
Example:
{
type: "SCRIPT_TAG",
severity: "HIGH",
pattern: "/<\\s*s\\s*[^\\S\\r\\n]*\\s*c.../",
matched: "<script>",
position: 15,
recommendation: "Remove script tags or encode HTML entities; sanitize input"
}
Property descriptions:
-
type: Threat classification for identification- Examples:
"SCRIPT_TAG","UNION_SELECT","JWT_TOKEN" - Used to categorize and handle threats programmatically
- Threat types list available in each threat category section
- Examples:
-
severity: Risk level classification"HIGH"= Critical threat, must be fixed (elevated in strictMode)"MEDIUM"= Important threat, should be fixed (elevated to HIGH in strictMode)"LOW"= Minor threat, nice to fix but not critical- Affects security score calculation
-
pattern: The regex pattern that detected this threat- Useful for understanding why it matched
- Can be used for custom filtering
- Shown as string representation
-
matched: The actual substring that triggered the threat detection- Helpful for pinpointing the issue in user input
- May be percent-decoded or normalized version
- Can be highlighted in error messages to user
-
position: Character position in the normalized input where threat was found- Useful for highlighting errors to users
- Based on normalized (not original) input
- First character is position 0
-
recommendation: Actionable advice for remediating this specific threat- Different recommendations for different threat types
- Helps developers fix the underlying issue
- Examples:
- For SQL: "Use parameterized queries or prepared statements"
- For XSS: "Remove script tags or encode HTML entities; sanitize input"
- For Path Traversal: "Use basename() or validate against whitelist"
FieldInput (Input Format)
The format required when passing fields to Scanner methods.
interface FieldInput {
name: string; // Unique field identifier
value: string; // Content to scan
type?: string; // Field context (optional)
allowedTags?: string[]; // Allowed HTML tags (optional, for type: 'html')
}
Example:
[
{
name: "email",
value: "user@example.com",
type: "email"
},
{
name: "bio",
value: "<p>Developer</p>",
type: "html",
allowedTags: ["p", "strong", "em", "br"]
},
{
name: "comment",
value: "Nice article!",
type: "text"
}
]
Property descriptions:
-
name(required): Unique identifier for the field- Used in response to identify which field has threats
- Examples:
"email","comment","bio" - Should be unique within a batch to prevent confusion
-
value(required): The actual content to scan- Any string, including empty strings
- Will be normalized before pattern matching
- Should contain user input or untrusted content
-
type(optional): Context about the field"text"- Plain text (most common)"email"- Email address"html"- HTML content (enables allowedTags)"password"- Password field"url"- URL/URI- Others:
"textarea","tel","number", etc. - Used to make scanning context-aware
-
allowedTags(optional): HTML tags to allow- Only effective when
type: "html" - Examples:
["p", "strong", "em", "br", "a"] - Script and event handlers are NEVER allowed, even if listed
- Use to permit safe tags while blocking dangerous ones
- Only effective when
ScannerConfig (Configuration Options)
Configuration passed to the Scanner constructor.
interface ScannerConfig {
strictMode?: boolean;
stopOnFirstThreat?: boolean;
includeValueInResponse?: boolean;
customPatterns?: Partial<Record<ScannerType, Pattern[]>>;
}
All properties with defaults:
{
strictMode: false, // default
stopOnFirstThreat: false, // default
includeValueInResponse: false, // default
customPatterns: {} // default
}
See the Configuration section above for detailed parameter explanations.
Pattern (Custom Pattern Format)
Format for defining custom threat detection patterns.
interface Pattern {
pattern: RegExp; // Regex to match threats
type: string; // Unique threat identifier
severity: "HIGH" | "MEDIUM" | "LOW";
}
Example:
{
pattern: /myCustomFramework\.render\(/gi,
type: "FRAMEWORK_EXEC",
severity: "HIGH"
}
Property descriptions:
-
pattern: Regular expression to match- Uses JavaScript RegExp syntax
- Should use
g(global) flag to find all matches - Should use
i(case-insensitive) for most patterns - More specific patterns = fewer false positives
-
type: Identifier for this specific threat- Used in Threat responses to identify the threat
- Should be descriptive and unique
- Examples:
"FRAMEWORK_EXEC","CUSTOM_XSS","API_KEY_LEAK"
-
severity: Risk classification"HIGH"= Critical, block immediately"MEDIUM"= Important, should address"LOW"= Minor, nice to know
Response Examples
Example 1: Clean Input
All fields pass validation:
const result = scanner.scanAll([
{ name: "email", value: "user@example.com", type: "email" },
{ name: "comment", value: "Great article!", type: "text" }
]);
// Response:
{
securityScore: 1.0,
scanner: "all",
passed: true,
duration: 5,
result: [
{
name: "email",
securityScore: 1.0,
passed: true,
threats: []
},
{
name: "comment",
securityScore: 1.0,
passed: true,
threats: []
}
]
}
Example 2: XSS Detected
One field contains XSS:
const result = scanner.scanAll([
{
name: "comment",
value: "<img src=x onerror='alert(1)'>",
type: "html",
allowedTags: ["p", "br"]
}
]);
// Response:
{
securityScore: 0.4,
scanner: "all",
passed: false,
duration: 8,
result: [
{
name: "comment",
securityScore: 0.6,
passed: false,
threats: [
{
type: "EVENT_HANDLER",
severity: "HIGH",
pattern: "/\\bon\\w+\\s*=\\s*(\".*?\"|'.*?'|[^\\s>]+)/gi",
matched: "onerror='alert(1)'",
position: 10,
recommendation: "Remove inline event handlers or sanitize attributes"
}
]
}
]
}
Example 3: Multiple Threats in One Field
Field with multiple issues:
const result = scanner.scanAll([
{
name: "query",
value: "'; DROP TABLE users; -- <script>alert(1)</script>",
type: "text"
}
]);
// Response:
{
securityScore: 0.0,
scanner: "all",
passed: false,
duration: 12,
result: [
{
name: "query",
securityScore: 0.0,
passed: false,
threats: [
{
type: "STACKED_QUERY",
severity: "HIGH",
pattern: "/;\\s*(DROP|DELETE|UPDATE|INSERT|ALTER|CREATE)\\b/gi",
matched: "; DROP",
position: 1,
recommendation: "Disable multiple statement execution"
},
{
type: "SCRIPT_TAG",
severity: "HIGH",
pattern: "/<\\s*s\\s*c\\s*r\\s*i\\s*p\\s*t[^>]*>[\\s\\S]*?<\\/script>/gi",
matched: "<script>alert(1)</script>",
position: 30,
recommendation: "Remove script tags or encode HTML entities; sanitize input"
}
]
}
]
}
Example 4: Using Targeted scan()
Scanning only for SQL injection:
const result = scanner.scan(
[{ name: "query", value: "SELECT * FROM users WHERE id=1 OR 1=1" }],
"sqlInjection"
);
// Response:
{
securityScore: 0.4,
scanner: "sqlInjection",
passed: false,
duration: 6,
result: [
{
name: "query",
securityScore: 0.6,
passed: false,
threats: [
{
type: "OR_CONDITION",
severity: "HIGH",
pattern: "/(\\bOR\\b\\s+['\"]*(\\d+)['\"]*(\\s*=\\s*)['\"]*(\\d+))/gi",
matched: "OR 1=1",
position: 38,
recommendation: "Validate input and use parameterized queries"
}
]
}
]
}
Example 5: Using scanMultiple()
Scanning for specific threats only:
const result = scanner.scanMultiple(
[
{ name: "file", value: "../../etc/passwd" },
{ name: "jwt", value: "eyJhbGciOiJIUzI1NiJ9..." }
],
["pathTraversal", "tokenLeakage"]
);
// Response:
{
securityScore: 0.2,
scanner: "multiple",
passed: false,
duration: 9,
result: [
{
name: "file",
securityScore: 0.4,
passed: false,
threats: [
{
type: "DIRECTORY_TRAVERSAL",
severity: "HIGH",
pattern: "/\\.\\.[\\/\\\\]/g",
matched: "../",
position: 0,
recommendation: "Use basename() or validate against whitelist"
}
]
},
{
name: "jwt",
securityScore: 0.4,
passed: false,
threats: [
{
type: "JWT_TOKEN",
severity: "HIGH",
pattern: "/eyJ[A-Za-z0-9_-]{10,}\\.[A-Za-z0-9_-]{10,}\\.[A-Za-z0-9_-]{10,}/g",
matched: "eyJhbGciOiJIUzI1NiJ9...",
position: 0,
recommendation: "Remove JWT token from input"
}
]
}
]
}
Input Normalization
The scanner applies a 8-step normalization pipeline to defeat obfuscation:
- Trim - Remove leading/trailing whitespace
- Remove invisible characters - Zero-width, soft hyphens, BOMs, RTL markers
- Percent-decode - Convert
%XXsequences to characters - HTML entity decode - Convert
&#XX;and<to characters - JavaScript escape decode - Convert
\uXXXXand\xXXto characters - Null byte removal - Remove
\0,%00,�variants - Tag whitespace normalization - Convert
< s c r i p t >to<script> - Whitespace collapse - Convert multiple spaces to single space
Example - Multi-layer obfuscation:
Input: "%3C%73%63%72%69%70%74%3E%20%61%6C%65%72%74%28%31%29%20%3C%2F%73%63%72%69%70%74%3E"
Step 1: "%3C%73%63%72%69%70%74%3E%20alert(1)%20%3C%2F%73%63%72%69%70%74%3E"
Step 2: "<script> alert(1) </script>"
Step 3: (HTML entities - no change)
Step 4: (JS escapes - no change)
Step 5: "<script>alert(1)</script>"
Result: Detected as XSS!
Characters removed (invisible):
- Soft hyphen:
\u00AD - Zero-width space:
\u200B - Zero-width joiner:
\u200D - Zero-width non-joiner:
\u200C - Word joiner:
\u2060 - Byte order mark:
\uFEFF - And 30+ other formatting characters
Security Score Calculation
Scores are calculated on a scale of 0 (compromised) to 1.0 (secure).
Penalty per threat:
- HIGH severity: -0.4
- MEDIUM severity: -0.2
- LOW severity: -0.1
Examples:
// 1 HIGH threat: 1.0 - 0.4 = 0.6
// 2 MEDIUM threats: 1.0 - (0.2 × 2) = 0.6
// 1 HIGH + 2 MEDIUM: 1.0 - 0.4 - 0.4 = 0.2
// 3 HIGH threats: 1.0 - (0.4 × 3) = -0.2 → capped at 0.0
Interpreting scores:
1.0- Completely secure, no threats0.7-0.9- Minor issues detected (LOW threats)0.3-0.6- Moderate threats (MEDIUM/HIGH mix)0.0-0.3- Critical threats (multiple HIGH)0.0- Severe compromise, multiple critical threats
Best Practices
- Choose appropriate strictness - Balance security vs. false positives
- Use targeted scanning when possible - Improves performance
- Validate on server side - Never rely solely on client-side scanning
- Log threats for audit trails - Enable
includeValueInResponsefor detailed logging - Keep patterns updated - Review custom patterns quarterly
- Handle false positives gracefully - Provide clear error messages
- Combine with other defenses - Scanner is one layer in defense-in-depth
- Test with real attack payloads - Verify your configuration actually blocks threats
Common Questions
Q: Can I use Scanner on the client side?
A: Yes, but it's not a complete solution. Client-side scanning is easily bypassed. Always validate on the server side too.
Q: Should I enable strictMode for user comments?
A: No, it causes false positives. Reserve strictMode: true for admin areas and sensitive operations.
Q: How do I add custom threat patterns?
A: Use the customPatterns config option. Create regex patterns matching your specific threats.
Q: Is the Scanner encoding-aware?
A: Yes! It decodes URL encoding, HTML entities, JavaScript escapes, and removes zero-width characters before pattern matching.
Q: Does Scanner protect against all XSS attacks?
A: It catches common XSS patterns, but isn't foolproof. Always sanitize output with libraries like DOMPurify on the frontend.
Q: What's the difference between scan(), scanAll(), and scanMultiple()?
A: scan() checks one threat type, scanAll() checks all five, scanMultiple() checks a specific subset you choose.
Q: When should I use scanMultiple()?
A: Use it when you know which threats are relevant (e.g., only SQL for database queries, only XSS for HTML content).
See Also
- API Reference - Complete API documentation
- Getting Started - Form validation setup
- Field Types - Validation field options