instance-security

Instance Security for ServiceNow

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "instance-security" with this command: npx skills add groeimetai/snow-flow/groeimetai-snow-flow-instance-security

Instance Security for ServiceNow

Instance Security covers authentication, authorization, and security hardening.

Security Layers

Network Security ↓ Authentication (SSO, MFA) ↓ Session Management ↓ Authorization (ACLs, Roles) ↓ Data Protection ↓ Audit & Logging

Key Tables

Table Purpose

sys_user

User accounts

sys_user_role

Roles

sys_security_acl

Access controls

sysevent_log

Security events

sys_properties

Security settings

Authentication Security (ES5)

Password Policy Configuration

// Check password strength (ES5 ONLY!) function validatePasswordStrength(password) { var issues = []

// Minimum length var minLength = parseInt(gs.getProperty("glide.security.password.min_length", "8"), 10) if (password.length < minLength) { issues.push("Password must be at least " + minLength + " characters") }

// Complexity requirements if (!/[A-Z]/.test(password)) { issues.push("Password must contain uppercase letter") } if (!/[a-z]/.test(password)) { issues.push("Password must contain lowercase letter") } if (!/[0-9]/.test(password)) { issues.push("Password must contain number") } if (!/[!@#$%^&*(),.?":{}|<>]/.test(password)) { issues.push("Password must contain special character") }

return { valid: issues.length === 0, issues: issues, } }

Session Security

// Check session validity (ES5 ONLY!) function isSessionSecure() { var session = gs.getSession()

// Check session age var maxAge = parseInt(gs.getProperty("glide.security.session.timeout", "60"), 10) var sessionAge = session.getSessionAge() / 60000 // Convert to minutes

if (sessionAge > maxAge) { return { valid: false, reason: "Session expired" } }

// Check for session fixation var clientIP = gs.getSession().getClientIP() var originalIP = session.getValue("original_ip")

if (originalIP && clientIP !== originalIP) { return { valid: false, reason: "IP address changed" } }

return { valid: true } }

// Force re-authentication function requireReauthentication(reason) { gs.getSession().invalidate() gs.addErrorMessage(reason) // Redirect to login response.sendRedirect("/login.do") }

MFA Implementation (ES5)

Check MFA Status

// Check if user has MFA enabled (ES5 ONLY!) function hasMFAEnabled(userSysId) { var user = new GlideRecord("sys_user") if (!user.get(userSysId)) { return false }

// Check MFA settings var mfa = new GlideRecord("sys_user_mfa") mfa.addQuery("user", userSysId) mfa.addQuery("active", true) mfa.query()

return mfa.hasNext() }

// Enforce MFA for sensitive operations function requireMFA(operation) { var userId = gs.getUserID()

if (!hasMFAEnabled(userId)) { gs.addErrorMessage("MFA required for " + operation) return false }

// Check if MFA verified this session var session = gs.getSession() var mfaVerified = session.getValue("mfa_verified")

if (mfaVerified !== "true") { // Trigger MFA challenge gs.eventQueue("user.mfa.challenge", null, userId, operation) return false }

return true }

Input Validation (ES5)

XSS Prevention

// Sanitize user input (ES5 ONLY!) function sanitizeInput(input) { if (!input) return ""

// Encode HTML entities var sanitized = input .toString() .replace(/&/g, "&amp;") .replace(/</g, "&lt;") .replace(/>/g, "&gt;") .replace(/"/g, "&quot;") .replace(/'/g, "&#x27;")

return sanitized }

// Validate and sanitize before storage function validateUserInput(tableName, fieldName, value) { // Check field type var dict = new GlideRecord("sys_dictionary") dict.addQuery("name", tableName) dict.addQuery("element", fieldName) dict.query()

if (!dict.next()) { return { valid: false, error: "Field not found" } }

var fieldType = dict.getValue("internal_type")

// Validate based on type if (fieldType === "string" || fieldType === "html") { // Check for script injection if (/<script/i.test(value)) { return { valid: false, error: "Script tags not allowed" } } // Check for event handlers if (/on\w+\s*=/i.test(value)) { return { valid: false, error: "Event handlers not allowed" } } }

return { valid: true, sanitized: sanitizeInput(value) } }

SQL Injection Prevention

// Safe query building (ES5 ONLY!) // NEVER concatenate user input directly into queries

// BAD - Vulnerable to injection // gr.addEncodedQuery('name=' + userInput);

// GOOD - Use parameterized queries function safeQuery(tableName, fieldName, value) { var gr = new GlideRecord(tableName)

// GlideRecord methods handle escaping gr.addQuery(fieldName, value) gr.query()

return gr }

// For encoded queries, validate input function safeEncodedQuery(tableName, userQuery) { // Whitelist allowed fields var allowedFields = ["number", "short_description", "state", "priority"]

// Parse and validate query var parts = userQuery.split("^") var safeQuery = []

for (var i = 0; i < parts.length; i++) { var part = parts[i] var match = part.match(/^(\w+)(=|!=|LIKE|CONTAINS)(.+)$/)

if (match) {
  var field = match[1]
  if (allowedFields.indexOf(field) !== -1) {
    safeQuery.push(part)
  }
}

}

var gr = new GlideRecord(tableName) if (safeQuery.length > 0) { gr.addEncodedQuery(safeQuery.join("^")) } gr.query()

return gr }

Security Properties (ES5)

Key Security Settings

// Get security-related properties (ES5 ONLY!) function getSecuritySettings() { return { // Session settings session_timeout: gs.getProperty("glide.security.session.timeout"), session_cookie_secure: gs.getProperty("glide.security.session.cookie.secure"),

// Password settings
password_min_length: gs.getProperty("glide.security.password.min_length"),
password_history: gs.getProperty("glide.security.password.history"),
password_expiry: gs.getProperty("glide.security.password.expiry"),

// Login settings
max_failed_logins: gs.getProperty("glide.security.password.max_failed_logins"),
lockout_duration: gs.getProperty("glide.security.password.lockout_duration"),

// General security
csrf_protection: gs.getProperty("glide.security.csrf.strict_validation"),
xss_protection: gs.getProperty("glide.security.xss.strict"),

} }

// Update security property function setSecurityProperty(name, value, requireRestart) { gs.setProperty(name, value)

if (requireRestart) { gs.warn("Security property changed: " + name + ". Restart may be required.") }

// Log security change gs.eventQueue("security.property.changed", null, name, value) }

Security Auditing (ES5)

Log Security Events

// Log security event (ES5 ONLY!) function logSecurityEvent(eventType, details) { var log = new GlideRecord("syslog") log.initialize()

log.setValue("level", "warning") log.setValue("source", "Security") log.setValue("message", eventType + ": " + JSON.stringify(details))

log.insert()

// Also queue for security monitoring gs.eventQueue("security.event", null, eventType, JSON.stringify(details)) }

// Track failed login attempts function trackFailedLogin(username, ipAddress) { logSecurityEvent("failed_login", { username: username, ip: ipAddress, timestamp: new GlideDateTime().getDisplayValue(), })

// Check for brute force var recentFailures = countRecentFailures(username, 5) // Last 5 minutes var maxFailures = parseInt(gs.getProperty("glide.security.password.max_failed_logins", "5"), 10)

if (recentFailures >= maxFailures) { lockAccount(username) logSecurityEvent("account_locked", { username: username, reason: "Too many failed login attempts", failures: recentFailures, }) } }

Security Health Check

// Check instance security health (ES5 ONLY!) function securityHealthCheck() { var issues = []

// Check for default admin password var admin = new GlideRecord("sys_user") if (admin.get("user_name", "admin")) { if (admin.getValue("password") === gs.getProperty("glide.security.default.admin.password")) { issues.push({ severity: "critical", issue: "Default admin password not changed" }) } }

// Check session timeout var timeout = parseInt(gs.getProperty("glide.security.session.timeout", "0"), 10) if (timeout === 0 || timeout > 60) { issues.push({ severity: "high", issue: "Session timeout too long or disabled" }) }

// Check password policy var minLength = parseInt(gs.getProperty("glide.security.password.min_length", "0"), 10) if (minLength < 12) { issues.push({ severity: "medium", issue: "Password minimum length less than 12" }) }

// Check HTTPS enforcement if (gs.getProperty("glide.security.session.cookie.secure") !== "true") { issues.push({ severity: "high", issue: "Secure cookies not enforced" }) }

return { healthy: issues.length === 0, issues: issues, } }

MCP Tool Integration

Available Tools

Tool Purpose

snow_property_get

Check security properties

snow_execute_script_with_output

Test security scripts

snow_review_access_control

Review ACLs

Example Workflow

// 1. Check security properties await snow_property_get({ name: "glide.security.session.timeout", })

// 2. Run security health check await snow_execute_script_with_output({ script: var health = securityHealthCheck(); gs.info(JSON.stringify(health)); , })

// 3. Review access controls await snow_query_table({ table: "sys_security_acl", query: "active=true^admin_overrides=true", fields: "name,operation,type,script", })

Best Practices

  • Strong Passwords - Enforce complexity

  • MFA - Enable for privileged users

  • Session Timeout - 15-30 minutes

  • Input Validation - Sanitize everything

  • Least Privilege - Minimal roles

  • Audit Logging - Log security events

  • Regular Reviews - Security assessments

  • ES5 Only - No modern JavaScript syntax

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Security

acl-security

No summary provided by upstream source.

Repository SourceNeeds Review
Security

security-operations

No summary provided by upstream source.

Repository SourceNeeds Review
General

predictive-intelligence

No summary provided by upstream source.

Repository SourceNeeds Review