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
Comment on lines +35 to +44

Check warning

Code scanning / CodeQL

Checkout of untrusted code in trusted context Medium

Potential unsafe checkout of untrusted pull request on privileged workflow.

Copilot Autofix

AI 12 days ago

In general, the fix is to avoid checking out and operating on the untrusted PR HEAD in a privileged context. For a review bot like this, the Claude action can work from the base repository combined with GitHub’s pull request metadata, without needing to execute code from the PR checkout. So the best fix is to stop checking out the PR head repository/ref, and instead either (a) check out the base repository on the merge commit / base ref, or (b) remove the checkout entirely if the Claude action does not require a local working tree.

The minimal change that preserves functionality while removing the unsafe pattern is:

  • Replace the “Checkout PR head” step with a standard checkout of the current repository using the default behavior of actions/checkout@v4. This gives the action read‑only access to the base repo as seen by the workflow, not to attacker‑controlled fork code.
  • Keep the rest of the workflow unchanged so that permissions, tokens, and the Claude action invocation continue to work as before.

Concretely, in .github/workflows/claude.yml, lines 35–41 (the Checkout PR head step) should be replaced by a safer checkout:

- name: Checkout repository
  uses: actions/checkout@v4
  with:
      fetch-depth: 20

No new imports or methods are needed; this is purely a workflow configuration change within that file.

Suggested changeset 1
.github/workflows/claude.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml
--- a/.github/workflows/claude.yml
+++ b/.github/workflows/claude.yml
@@ -31,14 +31,11 @@
                   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
+            # Checkout the repository in a safe context (do not use untrusted PR HEAD)
+            - name: Checkout repository
               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
EOF
@@ -31,14 +31,11 @@
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
# Checkout the repository in a safe context (do not use untrusted PR HEAD)
- name: Checkout repository
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
Copilot is powered by AI and may make mistakes. Always verify output.
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