code-review
Skill41 starsChanged 6 days agoApache-2.0View on GitHub
Review ServiceNow code for security vulnerabilities, performance issues, and platform best practices
We split this skill into the rules it gives an agent
7 rules. 0 are common, 7 are distinctive, and 0 are very specific to this project.
0
Common
Most of the 184 edited versions we read keep these.
7
Distinctive
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 38
When to use: Before deploying new scripts to production, during code review processes, when troubleshooting performance issues, or when …
- Distinctive: line 392
Test fixes in sub-production: Never apply code fixes directly to production
- Distinctive: line 393
Document exceptions: If a known anti-pattern is intentional, add a comment explaining why
- Distinctive: line 394
Review ACLs alongside scripts: Ensure ACLs complement business rule security checks
- Distinctive: line 396
Validate error handling: Every GlideRecord.get() should check for null results
- Distinctive: line 397
Review update sets: Check that scripts are captured in proper update sets before promoting
- Distinctive: line 405
Solution: Verify role assignment:
“Common” is measured: kept by at least 6 in 10 of the 184 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
ServiceNow Code Review
Overview
This skill covers systematic code review for ServiceNow scripts to identify and remediate:
- Security vulnerabilities (injection, XSS, privilege escalation, data exposure)
- Performance anti-patterns (unnecessary queries, N+1 problems, missing query limits)
- Platform best practice violations (API misuse, scope issues, deprecated methods)
- Maintainability concerns (naming, documentation, complexity, dead code)
- Concurrency and transaction safety issues
- Client-side performance and UX problems
When to use: Before deploying new scripts to production, during code review processes, when troubleshooting performance issues, or when auditing existing scripts for security compliance.
Prerequisites
- Roles:
admin,security_admin, or developer with read access to script tables - Access: sys_script, sys_script_include, sys_ui_script, sys_script_client tables
- Knowledge: ServiceNow scripting APIs, OWASP security principles, JavaScript best practices
- Related Skills: Complete
development/code-assistfor code generation context
Procedure
Step 1: Retrieve Scripts for Review
Query business rules for a specific table:
MCP Approach:
Tool: SN-Query-Table
Parameters:
table_name: sys_script
query: collection=incident^active=true
fields: sys_id,name,collection,when,script,filter_condition,order
limit: 50REST Alternative:
curl -u "$SN_USER:$SN_PASS" \
"$SN_INSTANCE/api/now/table/sys_script?sysparm_query=collection=incident^active=true&sysparm_fields=sys_id,name,collection,when,script,filter_condition,order&sysparm_limit=50" \
-H "Accept: application/json"Query script includes:
MCP Approach:
Tool: SN-Query-Table
Parameters:
table_name: sys_script_include
query: active=true^sys_updated_on>=javascript:gs.daysAgo(30)
fields: sys_id,name,script,client_callable,access,api_name
limit: 50Query client scripts:
MCP Approach:
Tool: SN-Query-Table
Parameters:
table_name: sys_script_client
query: table=incident^active=true
fields: sys_id,name,table,type,fieldname,script,ui_type
limit: 50Step 2: Security Review Checklist
Review each script against these critical security patterns:
2a. SQL/GlideRecord Injection:
VULNERABILITY: Unsanitized user input in queries
BAD:
gr.addEncodedQuery(current.variables.user_input);
gr.addQuery('name', request.getParameter('name'));
GOOD:
// Validate and sanitize input
var sanitized = GlideStringUtil.escapeHTML(input);
// Use parameterized queries
gr.addQuery('name', sanitizedName);
// Validate against allowlist
var validFields = ['name', 'number', 'state'];
if (validFields.indexOf(fieldName) === -1) return;2b. Cross-Site Scripting (XSS):
VULNERABILITY: Unescaped output in UI scripts or HTML fields
BAD:
element.innerHTML = current.short_description;
gs.getMessage(userInput);
GOOD:
element.textContent = current.short_description;
var escaped = GlideStringUtil.escapeHTML(current.short_description);2c. Privilege Escalation:
VULNERABILITY: Missing role checks or using setWorkflow(false) inappropriately
BAD:
current.setWorkflow(false); // Bypasses business rules and ACLs
current.autoSysFields(false); // Hides audit trail
GOOD:
// Only bypass when absolutely necessary and documented
if (gs.hasRole('admin')) {
current.setWorkflow(false); // REASON: Bulk import requires bypass
}2d. Sensitive Data Exposure:
VULNERABILITY: Logging or returning sensitive data
BAD:
gs.log('User password: ' + password);
gs.log('SSN: ' + current.social_security_number);
GOOD:
gs.log('Authentication attempted for user: ' + username);
// Never log PII, credentials, or tokensStep 3: Performance Review Checklist
3a. Unbounded GlideRecord Queries:
ANTI-PATTERN: Query without limit
BAD:
var gr = new GlideRecord('incident');
gr.addQuery('active', true);
gr.query(); // Could return millions of records
GOOD:
var gr = new GlideRecord('incident');
gr.addQuery('active', true);
gr.setLimit(1000); // Always set a reasonable limit
gr.query();3b. N+1 Query Pattern:
ANTI-PATTERN: Query inside a loop
BAD:
var incidents = new GlideRecord('incident');
incidents.query();
while (incidents.next()) {
var user = new GlideRecord('sys_user');
user.get(incidents.caller_id); // Query per iteration!
// process...
}
GOOD:
// Use dot-walking or join queries
var incidents = new GlideRecord('incident');
incidents.addQuery('active', true);
incidents.query();
while (incidents.next()) {
var callerName = incidents.caller_id.getDisplayValue(); // Dot-walk
// process...
}
// Or use GlideAggregate for counts
var ga = new GlideAggregate('incident');
ga.addQuery('active', true);
ga.groupBy('assignment_group');
ga.addAggregate('COUNT');
ga.query();3c. Synchronous GlideRecord in Client Scripts:
ANTI-PATTERN: Synchronous server calls from client
BAD:
var gr = new GlideRecord('sys_user');
gr.addQuery('sys_id', userId);
gr.query(); // Synchronous - blocks browser!
if (gr.next()) { ... }
GOOD:
// Use GlideAjax for async server calls
var ga = new GlideAjax('MyScriptInclude');
ga.addParam('sysparm_name', 'getUserInfo');
ga.addParam('sysparm_user_id', userId);
ga.getXMLAnswer(function(answer) {
// Process response asynchronously
});3d. Unnecessary Field Retrieval:
ANTI-PATTERN: Selecting all fields when only a few are needed
BAD:
var gr = new GlideRecord('incident');
gr.query(); // Returns ALL fields
GOOD:
var gr = new GlideRecord('incident');
gr.addQuery('active', true);
gr.chooseWindow(0, 100);
gr.setFields('sys_id,number,short_description,state');
gr.query();Step 4: Platform Best Practices Review
4a. Deprecated API Usage:
DEPRECATED: Avoid these methods
BAD:
current.getDisplayValue(); // Without field name - ambiguous
gs.log(); // Use gs.info/warn/error instead
Packages.java.lang.*; // Direct Java calls - unsupported
GOOD:
current.getDisplayValue('short_description');
gs.info('Message: {0}', current.number);4b. Scope Violations:
ANTI-PATTERN: Accessing global scope from scoped app
BAD:
// In scoped app, directly calling global
var result = new IncidentUtils(); // Global script include
GOOD:
// Use scoped API or cross-scope access
var si = new global.IncidentUtils(); // Explicit scope prefix
// Or use sn_ws for REST-based cross-scope communication4c. Business Rule Ordering:
BEST PRACTICE: Proper ordering
- 100: Data defaults and initialization
- 200: Validation rules
- 300: Data transformation
- 400: Cross-table updates (after rules)
- 500+: Notifications and integrations (after rules)4d. GlideRecord getValue vs Direct Access:
ANTI-PATTERN: Direct field access for comparisons
BAD:
if (current.state == 6) { ... } // Returns GlideElement, not value
GOOD:
if (current.getValue('state') == '6') { ... }
// Or use typed comparison
if (current.state.changesTo(6)) { ... }Step 5: Client Script Review
5a. DOM Manipulation:
ANTI-PATTERN: Direct DOM manipulation
BAD:
document.getElementById('incident.short_description').style.color = 'red';
$('incident.state').value = '6';
GOOD:
g_form.setMandatory('short_description', true);
g_form.addDecoration('short_description', 'color_red');
g_form.setValue('state', '6');5b. Missing isLoading Check:
ANTI-PATTERN: onChange without isLoading guard
BAD:
function onChange(control, oldValue, newValue, isLoading) {
// Fires on every form load, causing unnecessary processing
callServer(newValue);
}
GOOD:
function onChange(control, oldValue, newValue, isLoading) {
if (isLoading || newValue === '') {
return;
}
callServer(newValue);
}Step 6: Generate Review Report
Compile findings into a structured review report:
Code Review Report
================================================
Script: [Script Name]
Table: [Table Name]
Type: [Business Rule / Client Script / Script Include]
Reviewer: [AI-Assisted Review]
Date: [Current Date]
CRITICAL ISSUES:
[C1] Security - SQL Injection in line X
[C2] Security - XSS vulnerability in line Y
HIGH ISSUES:
[H1] Performance - N+1 query pattern in line Z
[H2] Performance - Unbounded GlideRecord query
MEDIUM ISSUES:
[M1] Best Practice - Deprecated API usage
[M2] Best Practice - Missing error handling
LOW ISSUES:
[L1] Maintainability - Missing JSDoc comments
[L2] Maintainability - Variable naming inconsistency
RECOMMENDATIONS:
1. [Specific fix for C1]
2. [Specific fix for C2]
3. [Specific fix for H1]Step 7: Apply Fixes
Update script with fixes:
MCP Approach:
Tool: SN-Update-Record
Parameters:
table_name: sys_script
sys_id: [script_sys_id]
data:
script: |
// [Updated script with fixes applied]REST Alternative:
curl -u "$SN_USER:$SN_PASS" \
"$SN_INSTANCE/api/now/table/sys_script/[script_sys_id]" \
-H "Content-Type: application/json" \
-X PATCH \
-d '{"script": "// Updated script content"}'Tool Usage
| Action | MCP Tool | REST Endpoint |
| Query business rules | SN-Query-Table | GET /api/now/table/sys_script |
| Query client scripts | SN-Query-Table | GET /api/now/table/sys_script_client |
| Query script includes | SN-Query-Table | GET /api/now/table/sys_script_include |
| Query UI scripts | SN-Query-Table | GET /api/now/table/sys_ui_script |
| Get single script | SN-Get-Record | GET /api/now/table/{table}/{sys_id} |
| Update fixed script | SN-Update-Record | PATCH /api/now/table/{table}/{sys_id} |
Best Practices
- Review in layers: Security first, then performance, then best practices, then maintainability
- Automate recurring checks: Build scanning scripts for common anti-patterns
- Check all script types together: Business rules, client scripts, and script includes often interact
- Test fixes in sub-production: Never apply code fixes directly to production
- Document exceptions: If a known anti-pattern is intentional, add a comment explaining why
- Review ACLs alongside scripts: Ensure ACLs complement business rule security checks
- Check for dead code: Inactive scripts still count against instance performance during upgrades
- Validate error handling: Every GlideRecord.get() should check for null results
- Review update sets: Check that scripts are captured in proper update sets before promoting
Troubleshooting
Cannot Access Script Tables
Symptom: Permission denied when querying sys_script Cause: Missing admin or script-related roles Solution: Verify role assignment:
Tool: SN-Query-Table
Parameters:
table_name: sys_user_has_role
query: user=[user_sys_id]^role.name=admin
fields: sys_id,role,userScript Too Large to Retrieve
Symptom: Script field truncated in API response Cause: API field size limits Solution: Get the specific record directly:
Tool: SN-Get-Record
Parameters:
table_name: sys_script
sys_id: [script_sys_id]
fields: scriptFinding All Scripts Modified Recently
Symptom: Need to review all recent changes Solution:
Tool: SN-Query-Table
Parameters:
table_name: sys_script
query: sys_updated_on>=javascript:gs.daysAgo(7)^active=true
fields: sys_id,name,collection,when,sys_updated_by,sys_updated_on
limit: 100Identifying Duplicate or Conflicting Rules
Symptom: Unexpected behavior from multiple rules on same table Solution:
Tool: SN-Query-Table
Parameters:
table_name: sys_script
query: collection=incident^active=true^when=before
fields: sys_id,name,order,filter_condition,action_insert,action_update
limit: 100Examples
Example 1: Full Security Audit of Incident Business Rules
# Step 1: Get all active business rules for incident table
Tool: SN-Query-Table
Parameters:
table_name: sys_script
query: collection=incident^active=true
fields: sys_id,name,when,script,order
limit: 100
# Step 2: For each script, check for security patterns
# Look for: addEncodedQuery with user input, setWorkflow(false),
# gs.log with sensitive data, eval() usage, Packages.* calls
# Step 3: Get client scripts for incident
Tool: SN-Query-Table
Parameters:
table_name: sys_script_client
query: table=incident^active=true
fields: sys_id,name,type,script
limit: 50
# Step 4: Check for synchronous GlideRecord in client scripts
# Look for: GlideRecord().query() without callback, direct DOM accessExample 2: Performance Review of Script Includes
# Get all active script includes with recent updates
Tool: SN-Query-Table
Parameters:
table_name: sys_script_include
query: active=true^sys_updated_on>=javascript:gs.daysAgo(90)
fields: sys_id,name,script,api_name
limit: 100
# For each script include, check for:
# - GlideRecord queries without setLimit()
# - Nested loops with queries (N+1)
# - Missing null checks after .get()
# - Large string concatenation in loopsExample 3: Review Recently Deployed Code
# Get scripts from the latest update set
Tool: SN-Query-Table
Parameters:
table_name: sys_update_xml
query: update_set=[update_set_sys_id]^nameLIKEsys_script
fields: sys_id,name,action,target_name
limit: 50
# Then retrieve each script for review
Tool: SN-Get-Record
Parameters:
table_name: sys_script
sys_id: [script_sys_id]
fields: name,script,collection,whenRelated Skills
development/code-assist- AI-assisted code generationsecurity/acl-management- Access control list managementadmin/update-set-management- Update set handling for deploymentssecurity/audit-compliance- Security hardening guidelines
Other versions194 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 194
- mattpocock/skills★ 309ksame name
- TheAlgorithms/Python★ 226ksame name
- microsoft/vscode★ 194ksame name
- github/spec-kit★ 145ksame name
- ggml-org/llama.cpp★ 133ksame name
- shareAI-lab/learn-claude-code★ 80ksame name
- shareAI-lab/analysis_claude_code★ 78ksame name
- vectorize-io/hindsight★ 57ksame name
- dbeaver/dbeaver★ 52ksame name
- roboflow/supervision★ 51ksame name
184 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
Used alongsideProjects with it also use add-new-model, azsdk-common-sdk-breaking-change and 9 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
PydanticSkilladd-new-model
Add support for a newly-released language or image generation model in pydantic-ai (e.g. openai:gpt-5.6, anthropic:claude-sonnet-5, openai:gpt-image-2). Use when a provider ships a new model id and you need to wire literals, profile flags, adapters, and tests to recognize it. Handles SDK-lag, gateway list conventions, capability probing, and direct image-model geometry.
Also in 9 projects that use this
Microsoft AzureSkillazsdk-common-sdk-breaking-change
Detect and mitigate SDK Breaking changes for an SDK package which is generated from TypeSpec. WHEN: "Detect SDK breaking changes for a service", "Detect SDK breaking changes for an SDK package", "Detect and mitigate SDK breaking changes for a service", "Detect and mitigate SDK breaking changes for an SDK package". INVOKES: skill: azsdk-common-generate-sdk-locally; MCP tools: azure-sdk-mcp:azsdk_customized_code_update, azure-sdk-mcp:azsdk_package_detect_breaking_change.
Also in 4 projects that use this
ww-w-aiSkillbkend-auth
bkend.ai authentication guide. Signup, login, JWT tokens, sessions, role-based access control, and password management with bkend.ai BaaS. Triggers: bkend auth, bkend login, bkend signup, JWT, session, RBAC, password, bkend 인증, 로그인, 회원가입, bkend認証, ログイン, 新規登録, bkend认证, 登录, 注册, autenticacion bkend, authentification bkend, bkend-Auth Do NOT use for: data operations (use $bkend-data), file storage (use $bkend-storage).
Also in 4 projects that use this
ww-w-aiSkillbkend-cookbook
bkend.ai cookbook with step-by-step tutorials and example projects. Build a todo app, blog, e-commerce store, and more with bkend.ai BaaS. Triggers: bkend cookbook, bkend tutorial, bkend example, todo app, blog app, bkend 쿡북, bkend 튜토리얼, 예제 프로젝트, bkendクックブック, チュートリアル, bkend教程, 示例项目, tutorial bkend, tutoriel bkend, bkend-Tutorial, ricettario Do NOT use for: initial setup (use $bkend-quickstart), specific features (use $bkend-data/auth/storage).
Also in 4 projects that use this
dzhngSkillclose-spec
When a spec under specs/<feature>/ is done shipping (a write-spec build, or any planned task that produced a spec), archive it to specs/done/ and rewrite it from a build-plan into a durable rationale — the why, the principles, the invariants — pointing back to the real code for the how. Use when implementation has landed and the plan no longer matches what shipped, or the user says a feature/spec is finished. Pairs with [write-spec](../write-spec/SKILL.md) (the plan this closes) and [review](../review/SKILL.md) (run before closing).
Also in 4 projects that use this
dzhngSkilldesign-with-images
Explore UI and visual design with image generation, then iterate the real implementation against the user-selected concept. Use when brainstorming visual directions, offering mockup variants, or implementing an approved generated design; do not stop at the mockups or the first code approximation.
Also in 4 projects that use this
- +5 more from ww-w-ai
In this repository184 other files it gives its agents.
- happy-platform-skillsSkill
- application-scopeSkill
- batch-operationsSkill
- configuration-validationSkill
- deployment-workflowSkill
- generic-crud-operationsSkill
- instance-managementSkill
- schema-discoverySkill
- script-executionSkill
- script-syncSkill
- smart-assessmentSkill
- task-analysisSkill
- task-summarizationSkill
- update-set-managementSkill
- user-provisioningSkill
- workflow-creationSkill
- workspace-insightsSkill
- approval-summarizationSkill
- approval-workflowsSkill
- catalog-builder-aiSkill
- catalog-item-generationSkill
- item-creationSkill
- multi-turn-orderingSkill
- request-fulfillmentSkill
- ui-policiesSkill
- variable-managementSkill
- ci-discoverySkill
- cmdb-search-analysisSkill
- data-qualitySkill
- impact-analysisSkill
- relationship-mappingSkill
- service-graph-diagnosisSkill
- activity-responseSkill
- csm-case-summarizationSkill
- chat-recommendationSkill
- email-recommendationSkill
- csm-kb-generationSkill
- resolution-notesSkill
- csm-sentiment-analysisSkill
- csm-sidebar-summarizationSkill
- csm-suggested-stepsSkill
- trending-topicsSkill
- automated-testingSkill
- business-rulesSkill
- client-scriptsSkill
- code-assistSkill
- data-importSkill
- debugging-techniquesSkill
- fluent-sdkSkill
- glide-api-referenceSkill
- mcp-server-installationSkill
- mcp-serverSkill
- notificationsSkill
- performance-optimizationSkill
- scheduled-jobsSkill
- scripted-rest-apisSkill
- script-includesSkill
- servicenow-docs-mcpSkill
- test-generationSkill
- ui-actionsSkill
- The first 60 shown.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

