chore: Implement CodeQL CI Alignment and Security Scanning
- Added comprehensive QA report for CodeQL CI alignment implementation, detailing tests, results, and findings. - Created CodeQL security scanning guide in documentation, outlining usage and common issues. - Developed pre-commit hooks for CodeQL scans and findings checks, ensuring security issues are identified before commits. - Implemented scripts for running CodeQL Go and JavaScript scans, aligned with CI configurations. - Verified all tests passed, including backend and frontend coverage, TypeScript checks, and SARIF file generation.
This commit is contained in:
229
.github/skills/security-scan-codeql-scripts/run.sh
vendored
Executable file
229
.github/skills/security-scan-codeql-scripts/run.sh
vendored
Executable file
@@ -0,0 +1,229 @@
|
||||
#!/usr/bin/env bash
|
||||
# Security Scan CodeQL - Execution Script
|
||||
#
|
||||
# This script runs CodeQL security analysis using the security-and-quality
|
||||
# suite to match GitHub Actions CI configuration exactly.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Source helper scripts
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
SKILLS_SCRIPTS_DIR="$(cd "${SCRIPT_DIR}/../scripts" && pwd)"
|
||||
|
||||
# shellcheck source=../scripts/_logging_helpers.sh
|
||||
source "${SKILLS_SCRIPTS_DIR}/_logging_helpers.sh"
|
||||
# shellcheck source=../scripts/_error_handling_helpers.sh
|
||||
source "${SKILLS_SCRIPTS_DIR}/_error_handling_helpers.sh"
|
||||
# shellcheck source=../scripts/_environment_helpers.sh
|
||||
source "${SKILLS_SCRIPTS_DIR}/_environment_helpers.sh"
|
||||
|
||||
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)"
|
||||
|
||||
# Set defaults
|
||||
set_default_env "CODEQL_THREADS" "0"
|
||||
set_default_env "CODEQL_FAIL_ON_ERROR" "true"
|
||||
|
||||
# Parse arguments
|
||||
LANGUAGE="${1:-all}"
|
||||
FORMAT="${2:-summary}"
|
||||
|
||||
# Validate language
|
||||
case "${LANGUAGE}" in
|
||||
go|javascript|js|all)
|
||||
;;
|
||||
*)
|
||||
log_error "Invalid language: ${LANGUAGE}. Must be one of: go, javascript, all"
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
|
||||
# Normalize javascript -> js for internal use
|
||||
if [[ "${LANGUAGE}" == "javascript" ]]; then
|
||||
LANGUAGE="js"
|
||||
fi
|
||||
|
||||
# Validate format
|
||||
case "${FORMAT}" in
|
||||
sarif|text|summary)
|
||||
;;
|
||||
*)
|
||||
log_error "Invalid format: ${FORMAT}. Must be one of: sarif, text, summary"
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
|
||||
# Validate CodeQL is installed
|
||||
log_step "ENVIRONMENT" "Validating CodeQL installation"
|
||||
if ! command -v codeql &> /dev/null; then
|
||||
log_error "CodeQL CLI is not installed"
|
||||
log_info "Install via: gh extension install github/gh-codeql"
|
||||
log_info "Then run: gh codeql set-version latest"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# Check CodeQL version
|
||||
CODEQL_VERSION=$(codeql version 2>/dev/null | head -1 | grep -oP '\d+\.\d+\.\d+' || echo "unknown")
|
||||
log_info "CodeQL version: ${CODEQL_VERSION}"
|
||||
|
||||
# Minimum version check
|
||||
MIN_VERSION="2.17.0"
|
||||
if [[ "${CODEQL_VERSION}" != "unknown" ]]; then
|
||||
if [[ "$(printf '%s\n' "${MIN_VERSION}" "${CODEQL_VERSION}" | sort -V | head -n1)" != "${MIN_VERSION}" ]]; then
|
||||
log_warning "CodeQL version ${CODEQL_VERSION} may be incompatible"
|
||||
log_info "Recommended: gh codeql set-version latest"
|
||||
fi
|
||||
fi
|
||||
|
||||
cd "${PROJECT_ROOT}"
|
||||
|
||||
# Track findings
|
||||
GO_ERRORS=0
|
||||
GO_WARNINGS=0
|
||||
JS_ERRORS=0
|
||||
JS_WARNINGS=0
|
||||
SCAN_FAILED=0
|
||||
|
||||
# Function to run CodeQL scan for a language
|
||||
run_codeql_scan() {
|
||||
local lang=$1
|
||||
local source_root=$2
|
||||
local db_name="codeql-db-${lang}"
|
||||
local sarif_file="codeql-results-${lang}.sarif"
|
||||
local query_suite=""
|
||||
|
||||
if [[ "${lang}" == "go" ]]; then
|
||||
query_suite="codeql/go-queries:codeql-suites/go-security-and-quality.qls"
|
||||
else
|
||||
query_suite="codeql/javascript-queries:codeql-suites/javascript-security-and-quality.qls"
|
||||
fi
|
||||
|
||||
log_step "CODEQL" "Scanning ${lang} code in ${source_root}/"
|
||||
|
||||
# Clean previous database
|
||||
rm -rf "${db_name}"
|
||||
|
||||
# Create database
|
||||
log_info "Creating CodeQL database..."
|
||||
if ! codeql database create "${db_name}" \
|
||||
--language="${lang}" \
|
||||
--source-root="${source_root}" \
|
||||
--threads="${CODEQL_THREADS}" \
|
||||
--overwrite 2>&1 | while read -r line; do
|
||||
# Filter verbose output, show important messages
|
||||
if [[ "${line}" == *"error"* ]] || [[ "${line}" == *"Error"* ]]; then
|
||||
log_error "${line}"
|
||||
elif [[ "${line}" == *"warning"* ]]; then
|
||||
log_warning "${line}"
|
||||
fi
|
||||
done; then
|
||||
log_error "Failed to create CodeQL database for ${lang}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Run analysis
|
||||
log_info "Analyzing with security-and-quality suite..."
|
||||
if ! codeql database analyze "${db_name}" \
|
||||
"${query_suite}" \
|
||||
--format=sarif-latest \
|
||||
--output="${sarif_file}" \
|
||||
--sarif-add-baseline-file-info \
|
||||
--threads="${CODEQL_THREADS}" 2>&1; then
|
||||
log_error "CodeQL analysis failed for ${lang}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_success "SARIF output: ${sarif_file}"
|
||||
|
||||
# Parse results
|
||||
if command -v jq &> /dev/null && [[ -f "${sarif_file}" ]]; then
|
||||
local total_findings
|
||||
local error_count
|
||||
local warning_count
|
||||
local note_count
|
||||
|
||||
total_findings=$(jq '.runs[].results | length' "${sarif_file}" 2>/dev/null || echo 0)
|
||||
error_count=$(jq '[.runs[].results[] | select(.level == "error")] | length' "${sarif_file}" 2>/dev/null || echo 0)
|
||||
warning_count=$(jq '[.runs[].results[] | select(.level == "warning")] | length' "${sarif_file}" 2>/dev/null || echo 0)
|
||||
note_count=$(jq '[.runs[].results[] | select(.level == "note")] | length' "${sarif_file}" 2>/dev/null || echo 0)
|
||||
|
||||
log_info "Found: ${error_count} errors, ${warning_count} warnings, ${note_count} notes (${total_findings} total)"
|
||||
|
||||
# Store counts for global tracking
|
||||
if [[ "${lang}" == "go" ]]; then
|
||||
GO_ERRORS=${error_count}
|
||||
GO_WARNINGS=${warning_count}
|
||||
else
|
||||
JS_ERRORS=${error_count}
|
||||
JS_WARNINGS=${warning_count}
|
||||
fi
|
||||
|
||||
# Show findings based on format
|
||||
if [[ "${FORMAT}" == "text" ]] || [[ "${FORMAT}" == "summary" ]]; then
|
||||
if [[ ${total_findings} -gt 0 ]]; then
|
||||
echo ""
|
||||
log_info "Top findings:"
|
||||
jq -r '.runs[].results[] | "\(.level): \(.message.text | split("\n")[0]) (\(.locations[0].physicalLocation.artifactLocation.uri):\(.locations[0].physicalLocation.region.startLine))"' "${sarif_file}" 2>/dev/null | head -15
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check for blocking errors
|
||||
if [[ ${error_count} -gt 0 ]]; then
|
||||
log_error "${lang}: ${error_count} HIGH/CRITICAL findings detected"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
log_warning "jq not available - install for detailed analysis"
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Run scans based on language selection
|
||||
if [[ "${LANGUAGE}" == "all" ]] || [[ "${LANGUAGE}" == "go" ]]; then
|
||||
if ! run_codeql_scan "go" "backend"; then
|
||||
SCAN_FAILED=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "${LANGUAGE}" == "all" ]] || [[ "${LANGUAGE}" == "js" ]]; then
|
||||
if ! run_codeql_scan "javascript" "frontend"; then
|
||||
SCAN_FAILED=1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Final summary
|
||||
echo ""
|
||||
log_step "SUMMARY" "CodeQL Security Scan Results"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
if [[ "${LANGUAGE}" == "all" ]] || [[ "${LANGUAGE}" == "go" ]]; then
|
||||
if [[ ${GO_ERRORS} -gt 0 ]]; then
|
||||
echo -e " Go: ${RED}${GO_ERRORS} errors${NC}, ${GO_WARNINGS} warnings"
|
||||
else
|
||||
echo -e " Go: ${GREEN}0 errors${NC}, ${GO_WARNINGS} warnings"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "${LANGUAGE}" == "all" ]] || [[ "${LANGUAGE}" == "js" ]]; then
|
||||
if [[ ${JS_ERRORS} -gt 0 ]]; then
|
||||
echo -e " JavaScript: ${RED}${JS_ERRORS} errors${NC}, ${JS_WARNINGS} warnings"
|
||||
else
|
||||
echo -e " JavaScript: ${GREEN}0 errors${NC}, ${JS_WARNINGS} warnings"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
# Exit based on findings
|
||||
if [[ "${CODEQL_FAIL_ON_ERROR}" == "true" ]] && [[ ${SCAN_FAILED} -eq 1 ]]; then
|
||||
log_error "CodeQL scan found HIGH/CRITICAL issues - fix before proceeding"
|
||||
echo ""
|
||||
log_info "View results:"
|
||||
log_info " VS Code: Install SARIF Viewer extension, open codeql-results-*.sarif"
|
||||
log_info " CLI: jq '.runs[].results[]' codeql-results-*.sarif"
|
||||
exit 1
|
||||
else
|
||||
log_success "CodeQL scan complete - no blocking issues"
|
||||
exit 0
|
||||
fi
|
||||
312
.github/skills/security-scan-codeql.SKILL.md
vendored
Normal file
312
.github/skills/security-scan-codeql.SKILL.md
vendored
Normal file
@@ -0,0 +1,312 @@
|
||||
---
|
||||
# agentskills.io specification v1.0
|
||||
name: "security-scan-codeql"
|
||||
version: "1.0.0"
|
||||
description: "Run CodeQL security analysis for Go and JavaScript/TypeScript code"
|
||||
author: "Charon Project"
|
||||
license: "MIT"
|
||||
tags:
|
||||
- "security"
|
||||
- "scanning"
|
||||
- "codeql"
|
||||
- "sast"
|
||||
- "vulnerabilities"
|
||||
compatibility:
|
||||
os:
|
||||
- "linux"
|
||||
- "darwin"
|
||||
shells:
|
||||
- "bash"
|
||||
requirements:
|
||||
- name: "codeql"
|
||||
version: ">=2.17.0"
|
||||
optional: false
|
||||
environment_variables:
|
||||
- name: "CODEQL_THREADS"
|
||||
description: "Number of threads for analysis (0 = auto)"
|
||||
default: "0"
|
||||
required: false
|
||||
- name: "CODEQL_FAIL_ON_ERROR"
|
||||
description: "Exit with error on HIGH/CRITICAL findings"
|
||||
default: "true"
|
||||
required: false
|
||||
parameters:
|
||||
- name: "language"
|
||||
type: "string"
|
||||
description: "Language to scan (go, javascript, all)"
|
||||
default: "all"
|
||||
required: false
|
||||
- name: "format"
|
||||
type: "string"
|
||||
description: "Output format (sarif, text, summary)"
|
||||
default: "summary"
|
||||
required: false
|
||||
outputs:
|
||||
- name: "sarif_files"
|
||||
type: "file"
|
||||
description: "SARIF files for each language scanned"
|
||||
- name: "summary"
|
||||
type: "stdout"
|
||||
description: "Human-readable findings summary"
|
||||
- name: "exit_code"
|
||||
type: "number"
|
||||
description: "0 if no HIGH/CRITICAL issues, non-zero otherwise"
|
||||
metadata:
|
||||
category: "security"
|
||||
subcategory: "sast"
|
||||
execution_time: "long"
|
||||
risk_level: "low"
|
||||
ci_cd_safe: true
|
||||
requires_network: false
|
||||
idempotent: true
|
||||
---
|
||||
|
||||
# Security Scan CodeQL
|
||||
|
||||
## Overview
|
||||
|
||||
Executes GitHub CodeQL static analysis security testing (SAST) for Go and JavaScript/TypeScript code. Uses the **security-and-quality** query suite to match GitHub Actions CI configuration exactly.
|
||||
|
||||
This skill ensures local development catches the same security issues that CI would detect, preventing CI failures due to security findings.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- CodeQL CLI 2.17.0 or higher installed
|
||||
- Query packs: `codeql/go-queries`, `codeql/javascript-queries`
|
||||
- Sufficient disk space for CodeQL databases (~500MB per language)
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Usage
|
||||
|
||||
Scan all languages with summary output:
|
||||
|
||||
```bash
|
||||
cd /path/to/charon
|
||||
.github/skills/scripts/skill-runner.sh security-scan-codeql
|
||||
```
|
||||
|
||||
### Scan Specific Language
|
||||
|
||||
Scan only Go code:
|
||||
|
||||
```bash
|
||||
.github/skills/scripts/skill-runner.sh security-scan-codeql go
|
||||
```
|
||||
|
||||
Scan only JavaScript/TypeScript code:
|
||||
|
||||
```bash
|
||||
.github/skills/scripts/skill-runner.sh security-scan-codeql javascript
|
||||
```
|
||||
|
||||
### Full SARIF Output
|
||||
|
||||
Get detailed SARIF output for integration with tools:
|
||||
|
||||
```bash
|
||||
.github/skills/scripts/skill-runner.sh security-scan-codeql all sarif
|
||||
```
|
||||
|
||||
### Text Output
|
||||
|
||||
Get text-formatted detailed findings:
|
||||
|
||||
```bash
|
||||
.github/skills/scripts/skill-runner.sh security-scan-codeql all text
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Required | Default | Description |
|
||||
|-----------|------|----------|---------|-------------|
|
||||
| language | string | No | all | Language to scan (go, javascript, all) |
|
||||
| format | string | No | summary | Output format (sarif, text, summary) |
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Required | Default | Description |
|
||||
|----------|----------|---------|-------------|
|
||||
| CODEQL_THREADS | No | 0 | Analysis threads (0 = auto-detect) |
|
||||
| CODEQL_FAIL_ON_ERROR | No | true | Fail on HIGH/CRITICAL findings |
|
||||
|
||||
## Query Suite
|
||||
|
||||
This skill uses the **security-and-quality** suite to match CI:
|
||||
|
||||
| Language | Suite | Queries | Coverage |
|
||||
|----------|-------|---------|----------|
|
||||
| Go | go-security-and-quality.qls | 61 | Security + quality issues |
|
||||
| JavaScript | javascript-security-and-quality.qls | 204 | Security + quality issues |
|
||||
|
||||
**Note:** This matches GitHub Actions CodeQL default configuration exactly.
|
||||
|
||||
## Outputs
|
||||
|
||||
- **SARIF Files**:
|
||||
- `codeql-results-go.sarif` - Go findings
|
||||
- `codeql-results-js.sarif` - JavaScript/TypeScript findings
|
||||
- **Databases**:
|
||||
- `codeql-db-go/` - Go CodeQL database
|
||||
- `codeql-db-js/` - JavaScript CodeQL database
|
||||
- **Exit Codes**:
|
||||
- 0: No HIGH/CRITICAL findings
|
||||
- 1: HIGH/CRITICAL findings detected
|
||||
- 2: Scanner error
|
||||
|
||||
## Security Categories
|
||||
|
||||
### CWE Coverage
|
||||
|
||||
| Category | Description | Languages |
|
||||
|----------|-------------|-----------|
|
||||
| CWE-079 | Cross-Site Scripting (XSS) | JS |
|
||||
| CWE-089 | SQL Injection | Go, JS |
|
||||
| CWE-117 | Log Injection | Go |
|
||||
| CWE-200 | Information Exposure | Go, JS |
|
||||
| CWE-312 | Cleartext Storage | Go, JS |
|
||||
| CWE-327 | Weak Cryptography | Go, JS |
|
||||
| CWE-502 | Deserialization | Go, JS |
|
||||
| CWE-611 | XXE Injection | Go |
|
||||
| CWE-640 | Email Injection | Go |
|
||||
| CWE-798 | Hardcoded Credentials | Go, JS |
|
||||
| CWE-918 | SSRF | Go, JS |
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: Full Scan (Default)
|
||||
|
||||
```bash
|
||||
# Scan all languages, show summary
|
||||
.github/skills/scripts/skill-runner.sh security-scan-codeql
|
||||
```
|
||||
|
||||
Output:
|
||||
```
|
||||
[STEP] CODEQL: Scanning Go code...
|
||||
[INFO] Creating database for backend/
|
||||
[INFO] Analyzing with security-and-quality suite (61 queries)
|
||||
[INFO] Found: 0 errors, 5 warnings, 3 notes
|
||||
[STEP] CODEQL: Scanning JavaScript code...
|
||||
[INFO] Creating database for frontend/
|
||||
[INFO] Analyzing with security-and-quality suite (204 queries)
|
||||
[INFO] Found: 0 errors, 2 warnings, 8 notes
|
||||
[SUCCESS] CodeQL scan complete - no HIGH/CRITICAL issues
|
||||
```
|
||||
|
||||
### Example 2: Go Only with Text Output
|
||||
|
||||
```bash
|
||||
# Detailed text output for Go findings
|
||||
.github/skills/scripts/skill-runner.sh security-scan-codeql go text
|
||||
```
|
||||
|
||||
### Example 3: CI/CD Pipeline Integration
|
||||
|
||||
```yaml
|
||||
# GitHub Actions example (already integrated in codeql.yml)
|
||||
- name: Run CodeQL Security Scan
|
||||
run: .github/skills/scripts/skill-runner.sh security-scan-codeql all summary
|
||||
continue-on-error: false
|
||||
```
|
||||
|
||||
### Example 4: Pre-Commit Integration
|
||||
|
||||
```bash
|
||||
# Already available via pre-commit
|
||||
pre-commit run codeql-go-scan --all-files
|
||||
pre-commit run codeql-js-scan --all-files
|
||||
pre-commit run codeql-check-findings --all-files
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Common Issues
|
||||
|
||||
**CodeQL version too old**:
|
||||
```bash
|
||||
Error: Extensible predicate API mismatch
|
||||
Solution: Upgrade CodeQL CLI: gh codeql set-version latest
|
||||
```
|
||||
|
||||
**Query pack not found**:
|
||||
```bash
|
||||
Error: Could not resolve pack codeql/go-queries
|
||||
Solution: codeql pack download codeql/go-queries codeql/javascript-queries
|
||||
```
|
||||
|
||||
**Database creation failed**:
|
||||
```bash
|
||||
Error: No source files found
|
||||
Solution: Verify source-root points to correct directory
|
||||
```
|
||||
|
||||
## Exit Codes
|
||||
|
||||
- **0**: No HIGH/CRITICAL (error-level) findings
|
||||
- **1**: HIGH/CRITICAL findings detected (blocks CI)
|
||||
- **2**: Scanner error or invalid arguments
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [security-scan-trivy](./security-scan-trivy.SKILL.md) - Container/dependency vulnerabilities
|
||||
- [security-scan-go-vuln](./security-scan-go-vuln.SKILL.md) - Go-specific CVE checking
|
||||
- [qa-precommit-all](./qa-precommit-all.SKILL.md) - Pre-commit quality checks
|
||||
|
||||
## CI Alignment
|
||||
|
||||
This skill is specifically designed to match GitHub Actions CodeQL workflow:
|
||||
|
||||
| Parameter | Local | CI | Aligned |
|
||||
|-----------|-------|-----|---------|
|
||||
| Query Suite | security-and-quality | security-and-quality | ✅ |
|
||||
| Go Queries | 61 | 61 | ✅ |
|
||||
| JS Queries | 204 | 204 | ✅ |
|
||||
| Threading | auto | auto | ✅ |
|
||||
| Baseline Info | enabled | enabled | ✅ |
|
||||
|
||||
## Viewing Results
|
||||
|
||||
### VS Code SARIF Viewer (Recommended)
|
||||
|
||||
1. Install extension: `MS-SarifVSCode.sarif-viewer`
|
||||
2. Open `codeql-results-go.sarif` or `codeql-results-js.sarif`
|
||||
3. Navigate findings with inline annotations
|
||||
|
||||
### Command Line (jq)
|
||||
|
||||
```bash
|
||||
# Count findings
|
||||
jq '.runs[].results | length' codeql-results-go.sarif
|
||||
|
||||
# List findings
|
||||
jq -r '.runs[].results[] | "\(.level): \(.message.text)"' codeql-results-go.sarif
|
||||
```
|
||||
|
||||
### GitHub Security Tab
|
||||
|
||||
SARIF files are automatically uploaded to GitHub Security tab in CI.
|
||||
|
||||
## Performance
|
||||
|
||||
| Language | Database Creation | Analysis | Total |
|
||||
|----------|------------------|----------|-------|
|
||||
| Go | ~30s | ~30s | ~60s |
|
||||
| JavaScript | ~45s | ~45s | ~90s |
|
||||
| All | ~75s | ~75s | ~150s |
|
||||
|
||||
**Note:** First run downloads query packs; subsequent runs are faster.
|
||||
|
||||
## Notes
|
||||
|
||||
- Requires CodeQL CLI 2.17.0+ (use `gh codeql set-version latest` to upgrade)
|
||||
- Databases are regenerated each run (not cached)
|
||||
- SARIF files are gitignored (see `.gitignore`)
|
||||
- Query results may vary between CodeQL versions
|
||||
- Use `.codeql/` directory for custom queries or suppressions
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2025-12-24
|
||||
**Maintained by**: Charon Project
|
||||
**Source**: CodeQL CLI + GitHub Query Packs
|
||||
Reference in New Issue
Block a user