Skip to content
Closed
Show file tree
Hide file tree
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
71 changes: 71 additions & 0 deletions .github/workflows/claude.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Claude Code Assistant Workflow
# This GitHub Actions workflow uses the Claude Code Action to review pull requests.
name: Claude Code Assistant

on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]

jobs:
claude-assistant:
# Only run on PR-related events that contain @claude
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest

permissions:
contents: read
pull-requests: write
issues: write
id-token: write
actions: read

# Cancel older runs when new commits arrive on the same PR
concurrency:
group: pr-${{ github.event.pull_request.number }}
cancel-in-progress: true

steps:
- name: Verify user
uses: 'deriv-com/shared-actions/.github/actions/verify_user_in_organization@v3'

Check warning

Code scanning / CodeQL

Unpinned tag for a non-immutable Action in workflow Medium

Unpinned 3rd party Action 'Claude Code Assistant' step
Uses Step
uses 'deriv-com/shared-actions/.github/actions/verify_user_in_organization' with ref 'v3', not a pinned commit hash
with:
username: ${{ github.event.pull_request.user.login }}
token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}

# Ensure we have a real git repo at the PR HEAD (works for forks)
- name: Checkout PR head
uses: actions/checkout@v4
with:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.event.pull_request.head.ref }}
fetch-depth: 20
token: ${{ secrets.GITHUB_TOKEN }}

# Sanity check (helps diagnose if anything goes wrong)
- name: Verify git workspace

Check warning

Code scanning / CodeQL

Checkout of untrusted code in trusted context Medium

Potential unsafe checkout of untrusted pull request on privileged workflow.
run: |
pwd
git rev-parse --is-inside-work-tree
git log -1 --oneline

- name: Run Claude Code Action
uses: anthropics/claude-code-action@v1

Check warning

Code scanning / CodeQL

Unpinned tag for a non-immutable Action in workflow Medium

Unpinned 3rd party Action 'Claude Code Assistant' step
Uses Step
uses 'anthropics/claude-code-action' with ref 'v1', not a pinned commit hash
timeout-minutes: 60
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
track_progress: true
prompt: |
REPO: ${{ github.repository }}
PR NUMBER: ${{ github.event.pull_request.number }}

Please review this pull request with a focus on:
- Correctness, regressions, and edge cases
- Code quality & readability (React + TypeScript best practices)
- Performance (render cost, memoization, effects)
- Security (XSS, auth flows, secrets)
- Tests (coverage for new logic)

Output:
- Inline comments for specific issues
- A summary comment with high/medium/low priority items
- Concrete fix suggestions and quick patches where safe
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"
}
}
]
}
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,11 @@ yarn-error.log*
.vscode
.vscode*
.vercel

# AI Tool Configuration Files
.cursorrules
.clinerules
.roo-config.json
.chatgpt-instructions.md
.claude-instructions.md
.ai-rules.md
20 changes: 2 additions & 18 deletions .husky/pre-push
Original file line number Diff line number Diff line change
@@ -1,22 +1,6 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

# ShiftAI Pre-push Hook - Intercept push for AI analysis and PR management
# Git pre-push hook passes: $1=remote_name, $2=remote_url

# 🗑️ EARLY EXIT: Check for delete operations at shell level
if ps aux | grep -v grep | grep -q "git.*push.*--delete"; then
exit 0
fi

fi
# Check command line arguments in current process tree
if pgrep -f "git.*push.*--delete" > /dev/null 2>&1; then
exit 0
fi

export GIT_PUSH_REMOTE_NAME="$1"
export GIT_PUSH_REMOTE_URL="$2"

npx @deriv-com/shiftai-cli hook pre-push

fi
exit $?
Loading
Loading