Setup Static Application Security Scanning in GitLab CI using NJSScan & Semgrep
Overview
Static Application Security Testing (SAST) implementation using NJSScan and Semgrep to identify security vulnerabilities in source code before deployment. This provides automated code-level security analysis directly in the CI/CD pipeline.
Technologies Used
GitLab CI/CD: Pipeline automation
NJSScan: JavaScript/Node.js security scanner
Semgrep: Multi-language semantic code analysis
Python: Runtime environment for scanning tools
What is SAST?
Static Application Security Testing analyzes source code without executing it to find:
Security vulnerabilities (XSS, SQL injection, code injection)
Insecure coding patterns
Hardcoded secrets
Authentication/authorization flaws
Input validation issues
Architecture
Pipeline Configuration
Created .gitlab-ci.yml:
stages:
- security
# SAST: NJSScan for JavaScript/Node.js
njsscan:
stage: security
image: python:3.12-slim
before_script:
- pip install --no-cache-dir njsscan
script:
- njsscan --sarif --output njsscan-report.sarif . || true
- njsscan --exit-warning .
artifacts:
paths:
- njsscan-report.sarif
expire_in: 1 week
allow_failure: false
# SAST: Semgrep for multi-language scanning
semgrep:
stage: security
image: semgrep/semgrep:latest
script:
- semgrep scan --config=auto --sarif --output=semgrep-report.sarif .
artifacts:
paths:
- semgrep-report.sarif
expire_in: 1 week
allow_failure: false
Scanning Tools
NJSScan
Purpose: JavaScript/Node.js specific security scanner
Detection Capabilities:
Pattern matching (13 security rules)
Semantic grep analysis (4 advanced rules)
Common JS vulnerabilities (XSS, prototype pollution, etc.)
Scan Types:
Pattern-based detection for known vulnerable code
AST-based semantic analysis for logic flaws
NJSScan Scan Results
Scan Summary:
Pattern Match Rules: 13
Semantic Grep Rules: 4
Vulnerabilities Found: 0
Status: ✅ Passed
Semgrep
Purpose: Multi-language semantic code scanner
Detection Capabilities:
Supports 30+ programming languages
Custom rule creation
Context-aware vulnerability detection
OWASP Top 10 coverage
Configuration: Uses --config=auto to automatically detect languages and apply appropriate rulesets
Semgrep Scan Results
Pipeline Overview
Key Differences: NJSScan vs Semgrep
| Feature | NJSScan | Semgrep |
|---|---|---|
| Language Support | JavaScript/Node.js only | 30+ languages |
| Rule Count | 17 built-in rules | Thousands of community rules |
| Customization | Limited | Highly customizable |
| Performance | Fast, focused | Slower, comprehensive |
| Best For | JS-specific vulnerabilities | Broad multi-language coverage |
Security Issues Detected
Both scans completed successfully with zero vulnerabilities detected in the codebase.
Key Learnings
Complementary Tools: NJSScan provides focused JS scanning while Semgrep offers broader coverage
Early Detection: SAST catches vulnerabilities before code review or deployment
Python Version Matters: Using Python 3.12 avoided dependency compilation issues (pydantic-core incompatibility with Python 3.14)
Artifact Storage: SARIF format enables integration with security dashboards and reporting tools
Common Issues & Solutions
Issue: pydantic-core build failure
Solution: Use python:3.12-slim image instead of latest python image
Issue: No artifact uploaded
Solution: Generate report files explicitly with --sarif or --json flags
Issue: Pipeline fails on warnings
Solution: Use || true after report generation, then run separate command with --exit-warning for enforcement
Next Steps
Integrate with GitLab Security Dashboard for centralized reporting
Add custom Semgrep rules for organization-specific security policies
Implement DAST (Dynamic Application Security Testing) for runtime vulnerability detection
Add dependency scanning (SCA) for third-party library vulnerabilities
Access Project: https://gitlab.com/sang-david-devsecops-projects/project-2



