mirror of
https://github.com/AgentSeal/codeburn.git
synced 2026-04-26 14:10:43 +00:00
chore(ci): add semgrep guard against prototype pollution regressions in provider hot paths (#78)
* chore(ci): add semgrep rule no-bracket-assign-on-literal-object-map * chore(ci): add workflow running semgrep bracket-assign guard on push/PR * fix(parser): use Object.create(null) for categoryBreakdown map * chore(ci): expand semgrep rule to cover ||, ??=, and if-guard variants * chore(ci): limit push trigger to main and add semgrep --strict * chore(ci): use jq to enforce finding count (--error unreliable in semgrep 1.x)
This commit is contained in:
parent
a031c8d32d
commit
5932a273a1
3 changed files with 50 additions and 1 deletions
27
.github/workflows/ci.yml
vendored
Normal file
27
.github/workflows/ci.yml
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
semgrep:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install Semgrep
|
||||
run: pip install semgrep
|
||||
|
||||
- name: Run Semgrep bracket-assign guard
|
||||
run: |
|
||||
set -e
|
||||
semgrep --config .semgrep/rules/no-bracket-assign-hot-paths.yml \
|
||||
--strict --json \
|
||||
src/providers/ src/parser.ts > semgrep-out.json
|
||||
FINDINGS=$(jq '.results | length' semgrep-out.json)
|
||||
if [ "$FINDINGS" -gt 0 ]; then
|
||||
jq -r '.results[] | "::error file=\(.path),line=\(.start.line)::\(.extra.message)"' semgrep-out.json
|
||||
exit 1
|
||||
fi
|
||||
22
.semgrep/rules/no-bracket-assign-hot-paths.yml
Normal file
22
.semgrep/rules/no-bracket-assign-hot-paths.yml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
rules:
|
||||
- id: no-bracket-assign-on-literal-object-map
|
||||
languages: [typescript]
|
||||
severity: ERROR
|
||||
message: >
|
||||
Bracket-assign on a map created with `{}` allows prototype pollution when
|
||||
the key comes from external data. Initialize the map with
|
||||
`Object.create(null)` instead.
|
||||
patterns:
|
||||
- pattern-either:
|
||||
- pattern: $MAP[$KEY] = $MAP[$KEY] ?? $INIT
|
||||
- pattern: $MAP[$KEY] = $MAP[$KEY] || $INIT
|
||||
- pattern: $MAP[$KEY] ??= $INIT
|
||||
- pattern: |
|
||||
if (!$MAP[$KEY]) $MAP[$KEY] = $INIT
|
||||
- pattern-not-inside: |
|
||||
const $MAP = Object.create(null)
|
||||
...
|
||||
paths:
|
||||
include:
|
||||
- '/src/providers/*.ts'
|
||||
- '/src/parser.ts'
|
||||
|
|
@ -173,7 +173,7 @@ function buildSessionSummary(
|
|||
const toolBreakdown: SessionSummary['toolBreakdown'] = Object.create(null)
|
||||
const mcpBreakdown: SessionSummary['mcpBreakdown'] = Object.create(null)
|
||||
const bashBreakdown: SessionSummary['bashBreakdown'] = Object.create(null)
|
||||
const categoryBreakdown: SessionSummary['categoryBreakdown'] = {} as SessionSummary['categoryBreakdown']
|
||||
const categoryBreakdown: SessionSummary['categoryBreakdown'] = Object.create(null)
|
||||
|
||||
let totalCost = 0
|
||||
let totalInput = 0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue