Skip to content

Commit 9e885fc

Browse files
WomB0ComB0claude
andauthored
fix(security): resolve CodeQL & zizmor code-scanning alerts (#18)
* fix(security): resolve CodeQL/zizmor code-scanning alerts - env_utils: replace fragile `find(...) != 0` scheme check with the anchored `rfind(prefix, 0) == 0` idiom in validate_url_env (hardens the prefix match; CodeQL #1 is a false positive — env-var config validation, not an authentication barrier — dismissed separately). - ci.yml: drop workflow-level `security-events: write`; grant it only to the `gates` job that runs CodeQL (zizmor excessive-permissions #7). - security.yml: pin the org reusable security-scan.yml to a commit SHA (zizmor unpinned-uses #5), matching ci.yml's existing convention. - add .github/zizmor.yml documenting intentional ignores: secrets-inherit on first-party org reusable callers (#6, #8) and template-injection in gh-aw generated workflow files (#11-20, DO NOT EDIT / maintainer vars). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(env_utils): use strncmp for allocation-free scheme check Address review feedback: check the http(s):// prefix directly on the const char* with std::strncmp instead of constructing a std::string, avoiding an unnecessary heap allocation. strncmp stops at the NUL terminator, so short values remain safe. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 33f730b commit 9e885fc

4 files changed

Lines changed: 42 additions & 5 deletions

File tree

.github/workflows/ci.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,22 @@ on:
1515
pull_request:
1616
branches: [main]
1717

18+
# Least-privilege at the workflow level; the only job that needs to write
19+
# code-scanning results (the reusable `gates` aggregator, which runs CodeQL)
20+
# is granted `security-events: write` at the job level below.
1821
permissions:
1922
contents: read
20-
security-events: write
21-
pull-requests: read
2223

2324
concurrency:
2425
group: ${{ github.workflow }}-${{ github.ref }}
2526
cancel-in-progress: true
2627

2728
jobs:
2829
gates:
30+
permissions:
31+
contents: read
32+
security-events: write
33+
pull-requests: read
2934
uses: resq-software/.github/.github/workflows/required.yml@f4b51a620aa1bf89c0bce4f434b36f92ff7d517d
3035
with:
3136
lang: cpp

.github/workflows/security.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ permissions:
2121

2222
jobs:
2323
scan:
24-
uses: resq-software/.github/.github/workflows/security-scan.yml@main
24+
uses: resq-software/.github/.github/workflows/security-scan.yml@73b9edb8f4f28a99f70ee22eb5e2dd2bf7807c84 # main
2525
with:
2626
languages: '["c-cpp","actions"]'
2727
enable-semgrep: true

.github/zizmor.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# zizmor configuration — https://docs.zizmor.sh/configuration/
2+
#
3+
# The ignores below are documented, intentional exceptions. Each is either a
4+
# first-party trusted caller or a file generated by gh-aw (githubnext Agentic
5+
# Workflows). They are not hand-editable findings.
6+
rules:
7+
# `secrets: inherit` on the thin callers to our own org-wide reusable
8+
# workflows in resq-software/.github. The reusables (security-scan / required)
9+
# legitimately need the scan tokens (e.g. Semgrep), and the boundary is
10+
# first-party, so blanket inheritance is acceptable here.
11+
secrets-inherit:
12+
ignore:
13+
- security.yml
14+
- ci.yml
15+
16+
# template-injection findings live entirely inside gh-aw GENERATED files
17+
# ("DO NOT EDIT" — regenerated by `gh aw compile`). The expansions are
18+
# maintainer-controlled repository variables / workflow inputs
19+
# (e.g. vars.GH_AW_DEFAULT_MAX_AI_CREDITS), not external attacker input.
20+
# They cannot be fixed by hand; fixes belong upstream in gh-aw.
21+
template-injection:
22+
ignore:
23+
- agentics-maintenance.yml
24+
- ai-auditor.lock.yml
25+
- auto-triage-issues.lock.yml
26+
- daily-secrets-analysis.lock.yml
27+
- duplicate-code-detector.lock.yml

packages/resq-common/include/resq/env_utils.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,13 @@ inline bool validate_url_env(const char* env_name, bool required = false) {
140140
return true;
141141
}
142142

143-
std::string url(value);
144-
if (url.find("http://") != 0 && url.find("https://") != 0) {
143+
// Anchored prefix check with strncmp: matches only when the scheme is a
144+
// true prefix, and avoids both the fragile `find(...) != 0` idiom and an
145+
// allocating std::string copy. value is non-null/non-empty here, and
146+
// strncmp stops at the NUL terminator, so short values are safe.
147+
const bool has_http_scheme = std::strncmp(value, "http://", 7) == 0 ||
148+
std::strncmp(value, "https://", 8) == 0;
149+
if (!has_http_scheme) {
145150
std::cerr << "Error: " << env_name << " must start with http:// or https://" << std::endl;
146151
return false;
147152
}

0 commit comments

Comments
 (0)