ci: harden PR security pipeline (#10)
Add comprehensive security scanning to CI/CD pipeline including CodeQL, Gitleaks, Semgrep custom rules, dependency review, and lifecycle script checks
This commit is contained in:
@@ -0,0 +1,21 @@
|
|||||||
|
# Code ownership for security-sensitive paths
|
||||||
|
# These files require maintainer review on every PR
|
||||||
|
|
||||||
|
# Security-critical: auth, secrets, OAuth flow
|
||||||
|
/src/auth-server.ts @patlux
|
||||||
|
/src/oauth.ts @patlux
|
||||||
|
/src/converters.ts @patlux
|
||||||
|
|
||||||
|
# CI/CD pipeline
|
||||||
|
.github/workflows/ @patlux
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
|
package.json @patlux
|
||||||
|
package-lock.json @patlux
|
||||||
|
|
||||||
|
# Security tooling
|
||||||
|
.semgrep/ @patlux
|
||||||
|
.gitleaks.toml @patlux
|
||||||
|
|
||||||
|
# This file itself
|
||||||
|
.github/CODEOWNERS @patlux
|
||||||
@@ -8,6 +8,9 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
# ──────────────────────────────────────────────────────────
|
||||||
|
# Code correctness
|
||||||
|
# ──────────────────────────────────────────────────────────
|
||||||
typecheck:
|
typecheck:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@@ -29,3 +32,140 @@ jobs:
|
|||||||
cache: npm
|
cache: npm
|
||||||
- run: npm ci
|
- run: npm ci
|
||||||
- run: npm run format:check
|
- run: npm run format:check
|
||||||
|
|
||||||
|
# ──────────────────────────────────────────────────────────
|
||||||
|
# Code-level vulnerability scanning (SAST)
|
||||||
|
# ──────────────────────────────────────────────────────────
|
||||||
|
codeql:
|
||||||
|
name: CodeQL SAST
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
actions: read
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: github/codeql-action/init@v3
|
||||||
|
with:
|
||||||
|
languages: javascript-typescript
|
||||||
|
queries: +security-extended,security-and-quality
|
||||||
|
- uses: github/codeql-action/autobuild@v3
|
||||||
|
- uses: github/codeql-action/analyze@v3
|
||||||
|
|
||||||
|
# ──────────────────────────────────────────────────────────
|
||||||
|
# Custom static analysis — pi extension attack patterns
|
||||||
|
# ──────────────────────────────────────────────────────────
|
||||||
|
semgrep:
|
||||||
|
name: Semgrep — pi extension audit
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
container:
|
||||||
|
image: semgrep/semgrep:latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Run Semgrep with custom rules
|
||||||
|
run: |
|
||||||
|
semgrep --config .semgrep/ --error --output semgrep-report.sarif --sarif .
|
||||||
|
- name: Upload SARIF
|
||||||
|
uses: github/codeql-action/upload-sarif@v3
|
||||||
|
with:
|
||||||
|
sarif_file: semgrep-report.sarif
|
||||||
|
category: semgrep-pi-audit
|
||||||
|
if: always()
|
||||||
|
|
||||||
|
# ──────────────────────────────────────────────────────────
|
||||||
|
# Hardcoded secrets detection
|
||||||
|
# ──────────────────────────────────────────────────────────
|
||||||
|
gitleaks:
|
||||||
|
name: Gitleaks — secrets scan
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- uses: gitleaks/gitleaks-action@v2
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
GITLEAKS_ENABLE_COMMENTS: "true"
|
||||||
|
|
||||||
|
# ──────────────────────────────────────────────────────────
|
||||||
|
# Dependency supply-chain security
|
||||||
|
# ──────────────────────────────────────────────────────────
|
||||||
|
deps-review:
|
||||||
|
name: Dependency review
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.event_name == 'pull_request'
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: write
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Check if dependency graph is enabled
|
||||||
|
run: |
|
||||||
|
echo "Dependency review requires enabling Dependency graph in repo settings."
|
||||||
|
echo "Go to: https://github.com/patlux/pi-commandcode-provider/settings/security_analysis"
|
||||||
|
echo "Enable: Dependency graph"
|
||||||
|
- uses: actions/dependency-review-action@v4
|
||||||
|
with:
|
||||||
|
fail-on-severity: high
|
||||||
|
allow-licenses: MIT, Apache-2.0, BSD-2-Clause, BSD-3-Clause, ISC, 0BSD
|
||||||
|
comment-summary-in-pr: always
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
deps-audit:
|
||||||
|
name: npm audit
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
cache: npm
|
||||||
|
- run: npm ci
|
||||||
|
- run: npm audit --audit-level=moderate
|
||||||
|
- name: Exit gracefully on audit findings
|
||||||
|
if: failure()
|
||||||
|
run: |
|
||||||
|
echo "::warning::npm audit found vulnerabilities. Review and patch before merging."
|
||||||
|
|
||||||
|
# ──────────────────────────────────────────────────────────
|
||||||
|
# Postinstall script check — prevents install-time malware
|
||||||
|
# ──────────────────────────────────────────────────────────
|
||||||
|
check-scripts:
|
||||||
|
name: Check lifecycle scripts
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Check for malicious lifecycle scripts
|
||||||
|
run: |
|
||||||
|
echo "::group::package.json scripts"
|
||||||
|
node -e "
|
||||||
|
const pkg = require('./package.json');
|
||||||
|
const dangerous = ['preinstall','install','postinstall','prepublish','prepare'];
|
||||||
|
const found = dangerous.filter(s => pkg.scripts && pkg.scripts[s]);
|
||||||
|
if (found.length) {
|
||||||
|
found.forEach(s => console.log('WARNING: package.json has "' + s + '":', pkg.scripts[s]));
|
||||||
|
process.exit(1);
|
||||||
|
} else {
|
||||||
|
console.log('No dangerous lifecycle scripts in package.json');
|
||||||
|
}
|
||||||
|
"
|
||||||
|
echo "::endgroup::"
|
||||||
|
echo "::group::dependency scripts (top-level)"
|
||||||
|
npm query '.scripts' --all 2>/dev/null | node -e "
|
||||||
|
const d = require('fs').readFileSync('/dev/stdin','utf8');
|
||||||
|
if (!d.trim()) { console.log('No dependency scripts found'); process.exit(0); }
|
||||||
|
let pkgs;
|
||||||
|
try { pkgs = JSON.parse(d); } catch(e) { console.log('Could not parse npm query output'); process.exit(0); }
|
||||||
|
if (!Array.isArray(pkgs)) pkgs = Object.values(pkgs);
|
||||||
|
const withScripts = pkgs.filter(p => p && p.pkgid && p.scripts);
|
||||||
|
withScripts.forEach(p => {
|
||||||
|
const dangerous = ['preinstall','install','postinstall','prepublish','prepare'];
|
||||||
|
const has = Object.keys(p.scripts || {}).filter(s => dangerous.includes(s));
|
||||||
|
if (has.length) console.log('⚠', p.pkgid, 'has scripts:', Object.keys(p.scripts));
|
||||||
|
});
|
||||||
|
if (withScripts.length === 0) console.log('No dependency lifecycle scripts');
|
||||||
|
" 2>&1 || true
|
||||||
|
echo "::endgroup::"
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
# Custom Gitleaks config for pi-commandcode-provider.
|
||||||
|
# Extends the default rule set with patterns specific to pi extensions.
|
||||||
|
|
||||||
|
title = "pi-commandcode-provider secret scan"
|
||||||
|
|
||||||
|
[allowlist]
|
||||||
|
description = "Known safe paths and test fixtures"
|
||||||
|
paths = [
|
||||||
|
# Test helpers with mock credentials
|
||||||
|
"tests/test-oauth.ts",
|
||||||
|
"tests/test-stream.ts",
|
||||||
|
"tests/test-pure-functions.ts",
|
||||||
|
"tests/test-pi-local.mjs",
|
||||||
|
"tests/test-omp-compat.mjs",
|
||||||
|
# CI workflows reference NPM_TOKEN secret name
|
||||||
|
".github/workflows/publish.yml",
|
||||||
|
]
|
||||||
|
|
||||||
|
# ──────────────────────────────────────────────────────────
|
||||||
|
# Project-specific rules
|
||||||
|
# ──────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[[rules]]
|
||||||
|
id = "pi-commandcode-api-key"
|
||||||
|
description = "Command Code API key hardcoded in source"
|
||||||
|
regex = '''(?i)COMMANDCODE_API_KEY\s*[=:]\s*['"](user_[A-Za-z0-9_-]{10,}|cc_[A-Za-z0-9_-]{10,})['"]'''
|
||||||
|
tags = ["pi-extension", "commandcode", "api-key"]
|
||||||
|
|
||||||
|
[[rules]]
|
||||||
|
id = "pi-auth-file-pattern"
|
||||||
|
description = "In-line pi auth.json content in source code"
|
||||||
|
regex = '''['"](apiKey|commandcode|command-code)['"]\s*:\s*['"]user_[A-Za-z0-9_-]{10,}['"]'''
|
||||||
|
tags = ["pi-extension", "auth"]
|
||||||
|
|
||||||
|
[[rules]]
|
||||||
|
id = "pi-hardcoded-bearer-token"
|
||||||
|
description = "Hardcoded Bearer token (20+ chars) in Authorization header"
|
||||||
|
regex = '''Bearer [A-Za-z0-9_.\-]{20,}'''
|
||||||
|
tags = ["pi-extension", "auth-token"]
|
||||||
|
|
||||||
|
[[rules]]
|
||||||
|
id = "pi-oauth-callback-url"
|
||||||
|
description = "OAuth callback URL with hardcoded key"
|
||||||
|
regex = '''callbackUrl\s*=\s*['"]http://localhost:\d+/callback['"]'''
|
||||||
|
tags = ["pi-extension", "oauth"]
|
||||||
|
|
||||||
|
[[rules]]
|
||||||
|
id = "pi-test-api-key"
|
||||||
|
description = "Test API key value that looks real"
|
||||||
|
regex = '''(user_testKey|mock-key|fake-key|test-api-key)'''
|
||||||
|
tags = ["pi-extension", "test"]
|
||||||
@@ -0,0 +1,273 @@
|
|||||||
|
rules:
|
||||||
|
# ────────────────────────────────────────────────────────────────────────
|
||||||
|
# Exfiltration: sending secrets to remote servers
|
||||||
|
# ────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
- id: pi-extension-data-exfiltration-fetch
|
||||||
|
patterns:
|
||||||
|
- pattern: fetch($URL, ...)
|
||||||
|
message: >
|
||||||
|
Data exfiltration risk: sending data to $URL via fetch.
|
||||||
|
Verify the destination is not an attacker-controlled server.
|
||||||
|
severity: ERROR
|
||||||
|
languages: [javascript, typescript]
|
||||||
|
paths:
|
||||||
|
include:
|
||||||
|
- "**/*.ts"
|
||||||
|
- "**/index.ts"
|
||||||
|
focus-metavariable: $URL
|
||||||
|
|
||||||
|
- id: pi-extension-data-exfiltration-xmlhttprequest
|
||||||
|
pattern: new XMLHttpRequest()
|
||||||
|
message: >
|
||||||
|
Suspicious XMLHttpRequest usage in provider code.
|
||||||
|
Could exfiltrate data to external servers.
|
||||||
|
severity: WARNING
|
||||||
|
languages: [javascript, typescript]
|
||||||
|
paths:
|
||||||
|
include:
|
||||||
|
- "**/*.ts"
|
||||||
|
|
||||||
|
# ────────────────────────────────────────────────────────────────────────
|
||||||
|
# Secret leakage: logging / sending API keys
|
||||||
|
# ────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
- id: pi-extension-logging-secrets
|
||||||
|
patterns:
|
||||||
|
- pattern-either:
|
||||||
|
- pattern: console.log(...)
|
||||||
|
- pattern: console.error(...)
|
||||||
|
- pattern: console.warn(...)
|
||||||
|
- pattern-regex: "api[kK]ey|API_KEY|COMMANDCODE|Bearer|authPath"
|
||||||
|
message: >
|
||||||
|
Potential secret logging: log statement includes an API key, auth token,
|
||||||
|
or auth file path pattern. Do not log secrets.
|
||||||
|
severity: ERROR
|
||||||
|
languages: [javascript, typescript]
|
||||||
|
paths:
|
||||||
|
include:
|
||||||
|
- "**/*.ts"
|
||||||
|
- "**/index.ts"
|
||||||
|
|
||||||
|
- id: pi-extension-secret-in-error-message
|
||||||
|
patterns:
|
||||||
|
- pattern: Error($MSG)
|
||||||
|
- pattern-regex: "api[kK]ey|API_KEY|COMMANDCODE|Bearer"
|
||||||
|
message: >
|
||||||
|
Possible secret leak in error message: $MSG.
|
||||||
|
Error messages surfaced to pi may leak credentials.
|
||||||
|
Use generic messages instead.
|
||||||
|
severity: WARNING
|
||||||
|
languages: [javascript, typescript]
|
||||||
|
paths:
|
||||||
|
include:
|
||||||
|
- "**/*.ts"
|
||||||
|
- "**/index.ts"
|
||||||
|
|
||||||
|
# ────────────────────────────────────────────────────────────────────────
|
||||||
|
# URL hijacking: changing API base endpoints
|
||||||
|
# ────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
- id: pi-extension-api-base-override
|
||||||
|
patterns:
|
||||||
|
- pattern-either:
|
||||||
|
- pattern: $VAR = "..."
|
||||||
|
- pattern: $VAR = process.env.$ENV_VAR ?? "..."
|
||||||
|
- metavariable-regex:
|
||||||
|
metavariable: $VAR
|
||||||
|
regex: "(?i).*(api_?base|api_base_url|base_url|host|endpoint|models_url).*"
|
||||||
|
- metavariable-regex:
|
||||||
|
metavariable: $ENV_VAR
|
||||||
|
regex: "(?i).*API.*BASE.*"
|
||||||
|
message: >
|
||||||
|
API base URL override: $ENV_VAR can redirect all requests including auth
|
||||||
|
headers to any server. Review any change to how this variable is set.
|
||||||
|
severity: ERROR
|
||||||
|
languages: [javascript, typescript]
|
||||||
|
paths:
|
||||||
|
include:
|
||||||
|
- "**/*.ts"
|
||||||
|
- "**/index.ts"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ────────────────────────────────────────────────────────────────────────
|
||||||
|
# Supply chain: dependency injection
|
||||||
|
# ────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
- id: pi-extension-untrusted-dynamic-require
|
||||||
|
patterns:
|
||||||
|
- pattern: require($MODULE)
|
||||||
|
- metavariable-regex:
|
||||||
|
metavariable: $MODULE
|
||||||
|
regex: "^(?)['\"]"
|
||||||
|
message: >
|
||||||
|
Dynamic require() of non-local, non-standard-library module: $MODULE.
|
||||||
|
External contributors could introduce malicious packages this way.
|
||||||
|
severity: ERROR
|
||||||
|
languages: [javascript, typescript]
|
||||||
|
paths:
|
||||||
|
include:
|
||||||
|
- "**/*.ts"
|
||||||
|
- "**/index.ts"
|
||||||
|
|
||||||
|
- id: pi-extension-postinstall-script
|
||||||
|
patterns:
|
||||||
|
- pattern: '"postinstall": "$SCRIPT"'
|
||||||
|
message: >
|
||||||
|
postinstall script detected: $SCRIPT. Install-time scripts can execute
|
||||||
|
arbitrary code on user machines. Must be reviewed with extreme care.
|
||||||
|
severity: ERROR
|
||||||
|
languages: [json]
|
||||||
|
paths:
|
||||||
|
include:
|
||||||
|
- "package.json"
|
||||||
|
|
||||||
|
# ────────────────────────────────────────────────────────────────────────
|
||||||
|
# File system: reading auth files / ~/.pi
|
||||||
|
# ────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
- id: pi-extension-auth-path-traversal
|
||||||
|
patterns:
|
||||||
|
- pattern: join($HOME, $PATH)
|
||||||
|
- metavariable-regex:
|
||||||
|
metavariable: $HOME
|
||||||
|
regex: "homedir|homeDir|HOME|process\\.env\\.HOME"
|
||||||
|
- metavariable-regex:
|
||||||
|
metavariable: $PATH
|
||||||
|
regex: "['\"].*\\.\\./.*['\"]"
|
||||||
|
message: >
|
||||||
|
Auth path traversal: $HOME / $PATH could read outside the intended auth
|
||||||
|
directory. Path must stay within ~/.commandcode, ~/.pi/agent, ~/.omp/agent.
|
||||||
|
severity: ERROR
|
||||||
|
languages: [javascript, typescript]
|
||||||
|
paths:
|
||||||
|
include:
|
||||||
|
- "**/*.ts"
|
||||||
|
|
||||||
|
- id: pi-extension-readfile-sensitive-paths
|
||||||
|
patterns:
|
||||||
|
- pattern: readFileSync($PATH, ...)
|
||||||
|
- pattern-not: readFileSync($PATH, "utf-8")
|
||||||
|
- metavariable-regex:
|
||||||
|
metavariable: $PATH
|
||||||
|
regex: "(auth\\.json|credentials|\\.env|id_rsa|ssh|\\.netrc|netrc|\\.npmrc)"
|
||||||
|
message: >
|
||||||
|
Suspicious file read: $PATH. Auth files or credentials being read with
|
||||||
|
potentially unsafe encoding. Review carefully.
|
||||||
|
severity: WARNING
|
||||||
|
languages: [javascript, typescript]
|
||||||
|
paths:
|
||||||
|
include:
|
||||||
|
- "**/*.ts"
|
||||||
|
|
||||||
|
# ────────────────────────────────────────────────────────────────────────
|
||||||
|
# Network: unexpected fetch calls
|
||||||
|
# ────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
- id: pi-extension-unexpected-fetch
|
||||||
|
pattern: fetch(...)
|
||||||
|
message: >
|
||||||
|
Direct fetch() call detected. Provider code should use injected
|
||||||
|
fetchImpl for testability and security. If this is intentional,
|
||||||
|
add a // nosemgrep comment on the line above.
|
||||||
|
severity: WARNING
|
||||||
|
languages: [javascript, typescript]
|
||||||
|
paths:
|
||||||
|
include:
|
||||||
|
- "**/*.ts"
|
||||||
|
- "**/index.ts"
|
||||||
|
|
||||||
|
# ────────────────────────────────────────────────────────────────────────
|
||||||
|
# Shell execution
|
||||||
|
# ────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
- id: pi-extension-shell-execution
|
||||||
|
patterns:
|
||||||
|
- pattern-either:
|
||||||
|
- pattern: child_process.exec(...)
|
||||||
|
- pattern: child_process.execSync(...)
|
||||||
|
- pattern: child_process.spawn(...)
|
||||||
|
- pattern: child_process.spawnSync(...)
|
||||||
|
- pattern: child_process.fork(...)
|
||||||
|
- pattern: exec($SCRIPT)
|
||||||
|
- pattern: execSync($SCRIPT)
|
||||||
|
message: >
|
||||||
|
Shell execution: $SCRIPT. External contributors should not add
|
||||||
|
child_process calls to provider source code.
|
||||||
|
severity: ERROR
|
||||||
|
languages: [javascript, typescript]
|
||||||
|
paths:
|
||||||
|
include:
|
||||||
|
- "**/*.ts"
|
||||||
|
- "**/index.ts"
|
||||||
|
|
||||||
|
# ────────────────────────────────────────────────────────────────────────
|
||||||
|
# Malicious import patterns
|
||||||
|
# ────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
- id: pi-extension-unusual-import
|
||||||
|
patterns:
|
||||||
|
- pattern-either:
|
||||||
|
- pattern: "import $X from \"...\""
|
||||||
|
- pattern: "const $X = require(\"...\")"
|
||||||
|
- metavariable-regex:
|
||||||
|
metavariable: $X
|
||||||
|
regex: "(compression|pako|zlib|tar|stream|archiver|request|axios|needle|got|superagent|node-fetch|undici)"
|
||||||
|
message: >
|
||||||
|
Suspicious import of $X in provider source. Network or compression
|
||||||
|
libraries could be used for data exfiltration.
|
||||||
|
severity: WARNING
|
||||||
|
languages: [javascript, typescript]
|
||||||
|
paths:
|
||||||
|
include:
|
||||||
|
- "**/*.ts"
|
||||||
|
- "**/index.ts"
|
||||||
|
|
||||||
|
- id: pi-extension-eval-like
|
||||||
|
patterns:
|
||||||
|
- pattern-either:
|
||||||
|
- pattern: eval(...)
|
||||||
|
- pattern: new Function(...)
|
||||||
|
- pattern: setTimeout($X, ...)
|
||||||
|
- pattern: setInterval($X, ...)
|
||||||
|
- pattern-not: setTimeout(() => ..., ...)
|
||||||
|
- pattern-not: setTimeout(function(...) {...}, ...)
|
||||||
|
- pattern-not: setTimeout(function $F(...) {...}, ...)
|
||||||
|
- pattern-not: setInterval(() => ..., ...)
|
||||||
|
- pattern-not: setInterval(function(...) {...}, ...)
|
||||||
|
- pattern-not: setInterval(function $F(...) {...}, ...)
|
||||||
|
message: >
|
||||||
|
Code injection risk: eval, Function constructor, or eval-like setTimeout
|
||||||
|
detected. These can execute arbitrary code.
|
||||||
|
severity: ERROR
|
||||||
|
languages: [javascript, typescript]
|
||||||
|
paths:
|
||||||
|
include:
|
||||||
|
- "**/*.ts"
|
||||||
|
- "**/index.ts"
|
||||||
|
|
||||||
|
# ────────────────────────────────────────────────────────────────────────
|
||||||
|
# Process environment: reading secrets
|
||||||
|
# ────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
- id: pi-extension-env-leak
|
||||||
|
patterns:
|
||||||
|
- pattern: process.env.$VAR
|
||||||
|
- metavariable-regex:
|
||||||
|
metavariable: $VAR
|
||||||
|
regex: "(?!COMMANDCODE_|NODE_|PATH|HOME|SHELL|USER|LANG|LC_|TERM|TMPDIR|NIX_).*"
|
||||||
|
message: >
|
||||||
|
Reading unexpected environment variable $VAR. Provider should only
|
||||||
|
read COMMANDCODE_* variables.
|
||||||
|
severity: WARNING
|
||||||
|
languages: [javascript, typescript]
|
||||||
|
paths:
|
||||||
|
include:
|
||||||
|
- "**/*.ts"
|
||||||
|
- "**/index.ts"
|
||||||
|
|
||||||
|
# ────────────────────────────────────────────────────────────────────────
|
||||||
|
# OAuth flow manipulation
|
||||||
|
# ────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# Semgrep ignore patterns
|
||||||
|
# Exclude test files and build artifacts
|
||||||
|
|
||||||
|
tests/
|
||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
coverage/
|
||||||
Reference in New Issue
Block a user