Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
207 changes: 207 additions & 0 deletions .github/workflows/security-nclc-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
name: Security NCLC Review
permissions:
pull-requests: write # Needed for leaving PR comments
contents: read
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
security:
runs-on: ubuntu-latest
timeout-minutes: 10
if: github.event.pull_request.draft == false
env:
SLACK_WEBHOOK_URL: ${{ secrets.SAST_SECURITY_SLACK_WEBHOOK }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
PR_URL: ${{ github.event.pull_request.html_url }}
PR_CREATOR: ${{ github.event.pull_request.user.login }}
PR_HEAD_COMMIT_URL: ${{ github.event.pull_request.html_url }}/commits/${{ github.event.pull_request.head.sha }}
WORKFLOW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
GITHUB_SENDER: ${{ github.event.sender.login }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
fetch-depth: 2
- name: Generate Custom Instruction File
run: |
cat <<EOF > custom_instruction.md
You are a Principal Application Security Engineer performing a security-focused code review. Analyze all changes in this PR for security vulnerabilities and provide actionable feedback.
## Review Scope & Priority
### CRITICAL - Block PR if found:
- Hardcoded secrets, API keys, passwords, tokens
- SQL injection vulnerabilities
- Remote Code Execution (RCE) risks
- Path traversal vulnerabilities
- Unsafe deserialization
- Missing authentication/authorization on sensitive endpoints
- Exposed sensitive data in logs/responses
### HIGH - Require immediate fix:
- Cross-Site Scripting (XSS) vulnerabilities
- Server-Side Request Forgery (SSRF)
- Insecure Direct Object References (IDOR)
- Cross-Site Request Forgery (CSRF) missing protections
- XML External Entity (XXE) injection
- Weak cryptography or hashing algorithms
- Race conditions in security controls
### MEDIUM - Fix before production:
- Missing input validation/sanitization
- Overly permissive CORS policies
- Missing security headers
- Insufficient logging for security events
- Missing rate limiting
- Dependency vulnerabilities (outdated packages)
## Technology-Specific Checks
### JavaScript/TypeScript Frontend:
```javascript
// DOM Manipulation & XSS Prevention:
- innerHTML/outerHTML/document.write() with user input
- dangerouslySetInnerHTML with unsanitized user input
- html-react-parser() without DOMPurify or sanitization
- $.html(), $.append(), $.after() with unsanitized data
- Unescaped user data in JSX expressions
- template literals with user input in HTML context

// Code Execution Risks:
- eval(), new Function(), setTimeout/setInterval with string arguments
- Dynamic imports from untrusted sources
- postMessage without targetOrigin validation
- window.open() with user-controlled URLs

// React-Specific Security:
- dangerouslySetInnerHTML usage (always requires justification)
- Props spreading (...props) potentially exposing sensitive attributes
- useEffect/useState with untrusted external data
- Component injection via dynamic imports without validation
- Context API exposing sensitive data (tokens, credentials)
- Ref manipulation allowing XSS

// Data Storage & Exposure:
- localStorage/sessionStorage storing tokens, passwords, PII
- Sensitive data in console.log/console.error/console.debug
- API keys, secrets, or credentials in frontend code
- Tokens or sensitive data in URL query parameters
- Session data persisting after logout

// Cryptography & Encoding:
- crypto-js using weak algorithms (MD5, SHA1 for passwords)
- Hardcoded encryption keys or initialization vectors
- Base64 encoding used as security measure
- Math.random() for security-sensitive operations
- Client-side-only password validation

// API & WebSocket Security:
- API responses used without validation/sanitization
- Credentials transmitted over unencrypted WebSocket

// Navigation & Redirects:
- window.location/location.href with user input
- history.pushState/replaceState with untrusted data
- Open redirects (redirect parameter not validated)
- <a href> with javascript: protocol
- target="_blank" without rel="noopener noreferrer"

// Configuration & Build:
- .env files committed to repository
- Webpack exposing sensitive environment variables to frontend
- Debug/development mode enabled in production
- Source maps exposed in production builds
- Missing Subresource Integrity (SRI) on CDN resources
- CSP headers missing or overly permissive

// Deserialization & Parsing:
- JSON.parse() without try-catch or validation
- js-yaml.load() without safeLoad (allows code execution)
- XML parsing without XXE protection
- User-controlled data in eval-like functions

// Additional Frontend Risks:
- CORS policies too permissive (allowing * origin)
- Clickjacking (missing X-Frame-Options/CSP frame-ancestors)
- MIME type sniffing (missing X-Content-Type-Options)
- Reflected XSS in error messages
- DOM-based XSS via URL fragments (#)
- Prototype pollution via Object.assign, merge functions
- ReDoS (Regex Denial of Service) patterns
- Missing CSRF tokens on state-changing operations
```
## Review Output Format
For each finding, provide:
```
:red_circle: CRITICAL | :large_yellow_circle: HIGH | :large_orange_circle: MEDIUM | :large_blue_circle: LOW
**Issue:** [Vulnerability type]
**Location:** [File:Line]
**Risk:** [Brief explanation of potential exploit]
**Fix:**
```[Secure code example]```
**Reference:** [OWASP/CWE ID if applicable]
```
## Additional Checks
1. **Dependencies:**
- Run security audit on package.json
- Check for known CVEs in dependencies
- Verify dependency sources are trusted
2. **Secrets Detection:**
- Scan for patterns: API keys, passwords, tokens, certificates
- Check .env files are gitignored
- Verify no sensitive data in comments
3. **Configuration:**
- Ensure secure defaults (fail closed)
- Verify least privilege principle
- Check for defense-in-depth implementation
4. **Data Flow:**
- Trace user input from entry to processing
- Verify all boundaries have validation
- Ensure proper encoding at each layer
## Summary Requirements
At the end of review, provide:
1. Security score: PASS :white_check_mark: | FAIL :x:
2. Count by severity: Critical(X), High(X), Medium(X), Low(X)
3. Must-fix items before merge
4. Recommended improvements
5. Positive security practices observed
## Review Principles
- Assume all input is malicious
- Verify trust boundaries
- Check fail-safe defaults
- Validate defense-in-depth
- Ensure least privilege
- Confirm secure communication
- Verify proper error handling
- Check audit logging presence
Focus only on security. Do not comment on code style, performance, or non-security bugs unless they have security implications.
EOF
- uses: anthropics/claude-code-security-review@68982a6bf10d545e94dd0390af08306d94ef684c
with:
comment-pr: true
claude-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
run-every-commit: true
custom-security-scan-instructions: custom_instruction.md
claude-model: ${{ vars.CLAUDE_MODEL || 'claude-opus-4-5-20251101' }}
- name: Send Failure Notification to Slack
if: failure()
uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001
with:
# For posting a rich message using Block Kit
payload: |
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": ":red-alert: *Security NCLC Review Checks Failed*"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "`Workflow Run:` ${{ env.WORKFLOW_RUN_URL }}\n\n`Pull Request:` ${{ env.PR_URL }}\n\n`Head Commit:` ${{ env.PR_HEAD_COMMIT_URL }}\n\n`PR Creator:` *${{ env.PR_CREATOR }}*\n\n`Latest Committer:` *${{ env.GITHUB_SENDER }}*\n\n"
}
}
]
}
Loading