Releases: JamieMagee/codeql-nix
Releases · JamieMagee/codeql-nix
Release list
v0.3.0
[0.3.0] — 2026-05-25 (Phase 3a)
Added
ql/lib/codeql/nix/Derivation.qll: recognises calls to nixpkgs-style
derivation wrappers (stdenv.mkDerivation,stdenvNoCC.mkDerivation,
buildPythonPackage,buildPythonApplication— faithful to
nixpkgs-hammering's scope) and exposesgetKind,getAttrs,
hasAttr,getDirectBinding,getADirectBinding, and
getNthAttrName.getAttrspeels through parens, the
(finalAttrs: { … })callback shape, andlet … in { … }bodies.
Foundation for the Phase 3anixpkgs-hammering-port queries.ql/test/library-tests/Derivation/: library-level test covering 12
derivation-call shapes including callback, callback+rec, callback+let,
parens, plain rec, both Python wrappers, andinherit/ inherit-from
cases.ql/src/Security/CWE-1078/MesonAndCmake.ql(plus qhelp and
ql/test/queries/CodeQuality/MesonAndCmake/): ports
nixpkgs-hammering'smeson-cmakerule. Flags derivations whose
nativeBuildInputsdeclare bothmesonandcmake, where nixpkgs
convention is to pick one primary configure-phase build system.ql/src/Security/CWE-1078/NameInsteadOfPnameVersion.{ql,qhelp}: ports
nixpkgs-hammering'sname-and-versionrule, flagging derivations that
setnameandversionwithoutpname; includes a CodeQuality qltest
fixture covering direct,inherit, callback, andbuildPythonPackage
forms.ql/src/Security/CWE-1078/ExplicitPhases.qlplus qhelp and query tests:
ports nixpkgs-hammering'sexplicit-phasesrule, reporting direct
overrides ofconfigurePhase,buildPhase,checkPhase, and
installPhasewhile leaving hook-based customization and unrelated
phases to their dedicated rules.ql/src/Security/CWE-1078/ProtectedPhaseOverride.ql(plus qhelp and
ql/test/queries/CodeQuality/ProtectedPhaseOverride/): ports
nixpkgs-hammering'sfixup-phaseandpatch-phaserules. Flags
derivations that overridefixupPhaseorpatchPhasedirectly
instead of extending the default phase withpre*/post*hooks.ql/src/Security/CWE-1078/MissingPhaseHooks.ql(plus qhelp and
ql/test/queries/CodeQuality/MissingPhaseHooks/): ports
nixpkgs-hammering'smissing-phase-hooksrule for
configurePhase,buildPhase,checkPhase, andinstallPhase.
Flags string-literal phase overrides that omit the corresponding
runHook preXand/orrunHook postXcalls.ql/src/Security/CWE-1078/AttributeTypo.ql(plus qhelp and
ql/test/queries/CodeQuality/AttributeTypo/): ports the narrow Phase
3a variant ofnixpkgs-hammering'sattribute-typorule. Flags
likely top-level derivation-attribute typos when they are either
case-only mistakes or members of a handwritten typo allow-list; leaves
unrelated custom attributes alone.ql/src/Security/CWE-1078/DuplicateCheckInputs.ql(plus qhelp and
ql/test/queries/CodeQuality/DuplicateCheckInputs/): ports
nixpkgs-hammering'sduplicate-check-inputsrule. Flags
derivations that repeat a package frompropagatedBuildInputsin
checkInputsornativeCheckInputs, where the check-time copy is
redundant.ql/src/Security/CWE-1078/AttributeOrdering.ql(plus qhelp and
ql/test/queries/CodeQuality/AttributeOrdering/): ports
nixpkgs-hammering'sattribute-orderingrule. Flags derivation
attributes that appear before the canonical predecessor they should
follow, while ignoring unknown attributes andinheritclauses.ql/src/Security/CWE-1078/UnclearGpl.ql(plus qhelp and
ql/test/queries/CodeQuality/UnclearGpl/): ports
nixpkgs-hammering'sunclear-gplrule. Flags deprecated ambiguous
GNU license aliases in derivationmeta.licensebindings and
recommends the explicitOnly/Plusvariant instead.ql/src/Security/CWE-1078/EnvVarsAtTopLevel.ql(plus qhelp and
ql/test/queries/CodeQuality/EnvVarsAtTopLevel/): ports
nixpkgs-hammering'senvironment-variables-go-to-envrule. Flags
selected environment variables declared as top-level derivation
attributes and recommends moving them underenv.ql/src/Security/CWE-1078/UnnecessaryParallelBuilding.ql(plus qhelp
andql/test/queries/CodeQuality/UnnecessaryParallelBuilding/): ports
nixpkgs-hammering'sunnecessary-parallel-buildingrule. Flags
redundantenableParallelBuilding = true;when Meson, CMake, or qmake
already enables parallel builds through the default configure hook.ql/src/Security/CWE-1078/BuildToolsInBuildInputs.ql(plus qhelp and
ql/test/queries/CodeQuality/BuildToolsInBuildInputs/): ports
nixpkgs-hammering'sbuild-tools-in-build-inputsrule. Flags
build-only tooling declared inbuildInputsand recommends moving it
tonativeBuildInputs.ql/src/codeql-suites/nix-code-quality.qls: new suite that bundles
the Phase 3anixpkgs-hammeringports for opt-in style/quality
scanning. Disjoint by tag fromnix-code-scanning.qls.
Changed
ql/src/codeql-suites/nix-code-scanning.qls: now excludes queries
taggedquality. Existing queries (taggedmaintainability/
correctness) are unaffected; Phase 3a quality lints are picked up
by the newnix-code-quality.qlssuite instead.
v0.2.0
[0.2.0] — 2026-05-24 (Phase 2)
Added
ql/lib/codeql/nix/Taint.qll: a lightweight taint-tracking library
targeting the shell-injection use case. DefinesSource(untrusted
function formals via a nixpkgs-aware allow-list,builtins.getEnv),
Sink(interpolations and direct bindings to shell-context
attributes, excluding path-style${pkg}/...patterns),
Sanitizer(lib.escapeShellArg/lib.escapeShellArgs), and
flowsTo/isReachableFromSanitizerpredicates. Self-contained —
does NOT depend onDataFlow::InputSig(that's a Phase 3 project).ql/src/Security/CWE-077/ShellInjectionInBuildPhase.ql(CWE-077,
CWE-078): reports flows from untrusted sources into shell-context
attribute interpolations withoutlib.escapeShellArg.ql/src/Security/CWE-077/MissingShellEscape.ql(CWE-077, CWE-078):
reports any shell-context interpolation that is not preceded by a
sanitizer call. The defensive-coding counterpart of the above.Scope.qll:isCallbackArgNamepredicate exemptingfinalAttrs,
prevAttrs, andoldAttrsfromUnusedBinding(deadnix convention).
Changed
Scope.qll:getAStrictAncestorandresolvesToare nowcached.
This materialises the recursive ancestor closure once per database
and dropsUnusedBindingfull-nixpkgs analyze time from ~2 minutes
to ~16 seconds. Required to makeTaint.qll's flow predicates
tractable on the full nixpkgs corpus.
Performance
- Full nixpkgs analyze time (43,142 .nix files, 12 queries,
--threads=0): ~39 s, down from ~3 m 2 s in Phase 1's 10-query
baseline despite adding two flow-based queries.
Notes
FetcherCallandimportwere dropped from theSourceset during
Phase 2 triage: they always evaluate to Nix store paths or attrsets,
never to user-controlled strings that can break shell quoting.
Including them as sources produced almost-exclusively false positives.- The
with-scope handling and explicitdefUseChaincaching items
from the Phase 2 plan were deferred to Phase 3 — neither produced a
precision or performance improvement large enough to justify their
cost when evaluated in isolation.
v0.1.0
[0.1.0] — 2026-05-23 (Phase 1)
Added
.github/workflows/release.yml: triggered onv*tag pushes. Builds
the extractor pack, packages it ascodeql-extractor-nix-vX.Y.Z-linux64.tar.gz,
pulls the matching CHANGELOG section as release notes, and creates a
GitHub Release with the tarball as an asset.ql/lib/codeql/nix/Scope.qll: lexical scope library porting deadnix's
fixpoint scope analysis to QL. ExposesScope,NameReference,
resolvesTo, andisUnusedBindingpredicates handling let-bindings,
let-attrset bindings, function formals + universal, and inherit
clauses (with correct outer-scope resolution forinherit name;).ql/src/Security/CWE-563/UnusedBinding.ql: reports defined names
that have no in-scope reference. Skipsrec { }and the legacy
let { body = …; }'sbodyattribute (both externally visible);
exempts identifiers starting with_(deadnix convention).BuiltinsGetEnv.ql(CWE-807): flagsbuiltins.getEnvand baregetEnv
calls underwith builtins;because they read the host environment during
evaluation.DeprecatedUriLiteral.ql(CWE-477): flags bare URI literals deprecated by Nix RFC 45 and recommends quoted strings.ql/src/Security/CWE-829/UnpinnedImportFetch.ql(CWE-829, CWE-094): detects
importof unpinned fetcher results, where network-controlled content is
fetched and immediately evaluated as Nix code.ql/src/Security/CWE-078/SpaceInFlagString.ql(plus qhelp and tests) to detect flag-list string literals with embedded whitespace that Bash word-splits into multiple argv entries.RecAttrsetMerge.ql(CWE-665): warns when//merges arec { ... }
attrset, since recursive references do not see the merged result.DuplicateAttrsetKey.ql(CWE-710): detects duplicate top-level keys in a single attrset literal before evaluation fails.- Phase 1 library expansion:
ql/lib/codeql/nix/Builtins.qll—BuiltinCallclass recognising
builtins.Xinvocations and (best-effort) bareXreferences
under awith builtins;scope.ql/lib/codeql/nix/Strings.qll—isListElementOfBinding(node, attrName)
helper plus anisFlagListAttributeNameallow-list ofmkDerivation
argv-style attributes.Nix.qll: new aliases (LetExpression,LetAttrsetExpression,
FunctionExpression,Formals,Formal,WithExpression,
LookupPath,BareUriLiteral,BinaryExpression), plus
hasInterpolation,indentedHasInterpolation,isLookupPath
predicates.
NixPathLookup.ql(CWE-829): detects<...>-style search-path lookups
that depend on the ambient$NIX_PATH.CHANGELOG.mdandCONTRIBUTING.md.ql/src/Security/CWE-477/LegacyLetAttrset.ql(CWE-477): flags the deprecated
legacylet { body = …; }attrset syntax and recommends modern
let ... in ...instead.