Repository navigation
v3.6.3
v3.6.3 — corrected Flask auth advice and four Semgrep rules that never matched
Correction — 2026-10-17: The initial release notes incorrectly stated that
the repaired JWT pattern blocks under --fail-on HIGH. It is reported at
CRITICAL severity, but under Fendix's confidence-gated release policy a
Semgrep-only finding remains WARN without qualifying corroboration. This
gate outcome is unchanged from v3.6.2.
The notes also said scans can now block where v3.6.2 passed. Under the
default policy that is not true either, for any of the four repaired
rules. Both passages are corrected below and in CHANGELOG.md. The v3.6.3
tag message keeps the original wording.
A security-correctness patch.
Fixed:
- flask-route-no-auth-decorator told users to place the auth decorator
"directly above the @app.route(...) line". Flask's route() must be the
outermost decorator, so following that advice left the route
unauthenticated. The finding's fix text, SARIF help and catalog
remediation now say the decorator goes directly below @app.route(...),
and that one placed above it does not protect the route.- Only the text after "directly" changed.
- Every finding keeps its title, fingerprints, grouping and baseline
match.
- Four bundled Semgrep rules could never fire. They listed alternative
patterns that Semgrep requires to match all at once, so no code could
ever trigger them. Each now matches its intended shapes:- python-eval-injection: eval() / exec() with a non-literal argument;
- python-jwt-decode-no-verification: jwt.decode() with
verify_signature: False, or "none" among the algorithms; - python-sql-injection-string-format: an execute() query built with %,
+, an f-string or .format(); - python-command-injection-shell-true: os.system() / os.popen() with a
non-literal command. subprocess(..., shell=True) stays with
python-subprocess-shell-true-with-variable, so it is reported once.
- The public security catalog printed raw Semgrep metavariables, such as
"found in '$VAR'" or "Flask route '$FUNC'", for eleven checks. Those
rules now publish static titles and remediation. - A rule clause that Semgrep silently ignored was removed from
python-hardcoded-secret-assignment. Detection is unchanged.
Known overlap:
When both analyzers run, jwt.decode(..., options={"verify_signature":
False}) can produce two findings for the same call:
- a Python-analyzer finding (PY_JWT_WEAK, auth_bypass, HIGH);
- a Semgrep finding (python-jwt-decode-no-verification, auth, CRITICAL).
Both describe the same real insecure call. Each keeps its own evidence and
provenance, and the second finding does not mean the code ran twice. Under
the default confidence-gated --fail-on, both are WARN: the Semgrep finding
is CRITICAL severity, but without qualifying corroboration a Semgrep-only
finding does not block. This release does not change cross-analyzer
correlation or verdict precedence; merging the two without lowering the
verdict is tracked in #127.
Unchanged: report schema, SARIF structure, fingerprints, finding identity,
exit codes, and the Action's inputs and outputs.
Upgrading:
- Scans can now report findings that v3.6.2 did not: eval and exec
injection, SQL built by string formatting, os.system and os.popen
command injection, and JWT decoding without signature verification.
These are findings v3.6.2 should have reported. - They carry their rule severity: CRITICAL, or HIGH for eval and exec.
Under the default confidence-gated --fail-on, an uncorroborated Semgrep
finding remains WARN, so the release-gate outcome is unchanged from
v3.6.2. With --enforce-confidence=false, the legacy severity-only gate,
they block at or above the threshold and are marked policy_override. - Where the Python analyzer runs (the default --code scan, the official
image and the Action), most of these were already reported. There, the
new findings are algorithms=["none"] and the Semgrep verify_signature
finding described above. - The GitHub Action is unchanged, and @v1 still points to the v3.6.2
release commit. Set version: v3.6.3 to install this release, or leave
version unset to install the latest release.
Full notes: CHANGELOG.md, section 3.6.3.