Skip to content

ci: Do not use github-token option if the secret is empty - #2

Merged
seqradev merged 1 commit into
mainfrom
seqradev/fix-github-token
Jan 14, 2026
Merged

ci: Do not use github-token option if the secret is empty#2
seqradev merged 1 commit into
mainfrom
seqradev/fix-github-token

Conversation

@seqradev

Copy link
Copy Markdown
Member

No description provided.

@seqradev
seqradev merged commit 84bbb5f into main Jan 14, 2026
5 checks passed
@seqradev
seqradev deleted the seqradev/fix-github-token branch January 14, 2026 21:32
seqradev pushed a commit that referenced this pull request Jan 29, 2026
misonijnik pushed a commit that referenced this pull request Mar 19, 2026
* Deserializers

* Fix parsing issues

* Extract inline serializer
misonijnik pushed a commit that referenced this pull request Mar 19, 2026
* Rewrite trace resolver

* primary actions

* Fix trace resolver

* Fix message builder
misonijnik added a commit that referenced this pull request Mar 19, 2026
Saloed pushed a commit that referenced this pull request Mar 23, 2026
Saloed added a commit that referenced this pull request Jun 1, 2026
Taint was lost through `for ... range` over a collection holding element
(`[*]`) taint. Go SSA lowers `for k, v := range m` to `next(range m)`,
producing a 3-tuple `(ok, key, value)` consumed by `extract #0/#1/#2`. A
tainted map/slice carries taint under an ElementAccessor (`[*]`). The
`range`/`next` flow functions copied the operand access path verbatim, so
the next register's fact stayed `var(R)[*]![taint]`, while `extract`
refines the tuple register with a tupleFieldAccessor (`tuple$i`). The `[*]`
ElementAccessor never unifies with the `tuple$i` FieldAccessor, so the
key/value extracts read nothing and the loop variable — then the sink —
came back clean.

Root cause was the same tuple/extract accessor-unification family as the
multi-return fix (b3bbf02), but for ELEMENT taint projecting onto tuple
slots rather than whole-value taint. The multi-return `isWholeValueTaint`
read-through already covered whole-value-tainted collections (so
source-driven map ranges like Ctx.Input.Params() already flowed); the gap
was specifically element-level taint built locally via map-update.

Fix:
- GoFlowFunctionUtils.rangeElementTupleSlots: resolve the ranged
  collection's underlying type (through named/pointer wrappers) and return
  the tuple slots the element taint projects onto — map → key slot ($1) and
  value slot ($2) (over-approximate: the whole key+value element is
  tainted); slice/array → value slot ($2) only (the int index stays clean).
- GoMethodSequentFlowFunction.handleNext: keep the original verbatim
  operand copy (preserving the whole-value path) and additionally project
  the iterated collection's `[*]` taint onto those tuple slots so the
  downstream extract's tupleFieldAccessor unifies.
- handleMapUpdate (forward + precondition): a tainted map KEY now also
  taints the map element, matching the key-slot projection above
  (`for k := range m` over a key-tainted map).
- GoMethodSequentPrecondition.handleNextPrecondition: backward counterpart
  for trace reconstruction (verbatim rebase + element-from-slot
  precondition), in lockstep with the forward gen.

Tests (red -> green): un-disabled engine fixtures MapOpsTest.mapIter001T
(range value) and mapKeyTaint001T (range key); new querylang rule sample
SourceBeegoInputParamsRange (map ranged after element/key taint, sinks the
loop var) registered in GoSampleBasedTest. Diagnostic dumps added for the
two fixtures in EngineRoadmapDiagnosticTest.

Regression: 0 new failures across
`org.opentaint.go.sast.dataflow.*` (fully green; MultiReturn intact) and
`:opentaint-go-querylang:test` (23 pre-existing GoMassiveSampleTest
baseline failures, identical set before/after — none new, none recovered).

Bench precision (owasp + sec) is flat: owasp CWE-22 38/44, CWE-78 21/25,
CWE-79 58/66, CWE-89 99/86, TOTAL 216 TP / 221 FP (unchanged); sec 178 TP /
249 FP (unchanged). The benchmark range FNs flow via whole-value taint
(already handled), so this closes a distinct element-taint gap with zero
bench cost — the key over-approximation added zero FP in practice.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Saloed added a commit that referenced this pull request Jun 29, 2026
New sample packages under samples-go/ wired into GoSampleBasedTest, each
isolating a limitation found while improving the Go ruleset (see issues.md):

- TypedFieldReadSource (#1): typed receiver on a field-read source crashes
  analysis (IllegalStateException "Unsupported field-source position: This").
- InterfaceImplSink (#2): a typed receiver matches only the exact static
  type, not a concrete implementor of the interface.
- TypedArgSink (#3): a type ascription in argument position is ignored.
- FieldReadSink (#4): a field-read sink never fires in taint mode.
- MapValueToReceiver (#5): confirms the core DOES propagate a map value into
  a receiver-position sink, so the full-scan ServeJSON false-negative is an
  unroll-strategy/config issue, not a core bug.

#1-#4 are @disabled with a todo referencing the issue; removing @disabled
reproduces the bug now and the test should pass once it is fixed. #5 is
enabled and passing. Full GoSampleBasedTest: 89 tests, 0 failures, 5 skipped.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Saloed added a commit that referenced this pull request Jun 29, 2026
Engine (opentaint-go-dataflow):
- #1 typed field-read source no longer crashes: thread GoFieldSignature.receiverType,
  allow This as a field-source condition base (taint target stays Result-only).
- #2 TypeUtils.matchesType matches interface implementations (method-set check,
  pointer/value rules, graceful fallback).
- #7 GoFunctionSignature.pkgName (declared package clause name) + candidates() branch
  so bare rand.* matches math/rand/v2.
- #11 GoConditionResolver.resolveWithType descends a single-element GoIRTupleType
  (single-return result) before a Field/Element modifier, so a result-field source
  taint action (cookie .Value) resolves and seeds field-sensitively. No whole-value taint.
- #12 GoCallExpr peels the receiver for DIRECT concrete pointer-receiver methods from the
  static target signature (fixes *sql.DB.Query arg indexing); no go-ssa-server change.
- #6 GoTaintConfiguration.matchPackage is exact for slash-qualified matchers.

Querylang (opentaint-go-querylang):
- #3 typed metavar in argument position parses to ParamCondition.TypeIs(Argument).
- #6 new GoImportRewriter pre-pass resolves package qualifiers from in-pattern imports.

Ruleset (rules/ruleset/go):
- #6 import-qualified package names across lib/security rules (bare where a local
  test-stub / ambiguous package / typed-receiver method pattern requires it).
- #7 weak-random drops the v2.* block.
- #11 http-sources cookies source taints [$I].Value.

Tooling: #10 restore scan --entry-point flag; re-point fn_investigate.py to
test rule reachability.

Gates: engine units 1300/1300; GoSampleBasedTest 95 (3 intentional skips);
rules/test/go detection harness 197/197.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
misonijnik added a commit that referenced this pull request Jul 3, 2026
- #7 PreparedStatementCreatorFactory:
newPreparedStatementCreator(String, Object[])
  DOES exist in Spring JDBC 5.3.x (arg0 is the SQL) — the "no String
overload" note
  was about the single-arg form. Added unsafeNewPSC using the 2-arg
overload;
  re-enabled. Suite: OK 979 | Skip 0 | FP 0 | FN 0.

- Removed the three disabled samples whose behavior is now captured by
minimal
  engine repros on misonijnik/core-engine-repros, leaving a NOTE that
points to
  each repro:
    - #2 staticResource(new URL("..."+resource))  ->
taint/WrapperPropagatorRepro
    - #3 ResponseEntity.header(..., "*") (varargs) ->
custom/BuilderChainMatchRepro
    - #9 (File $F).getCanonicalFile() sanitizer    ->
taint/InstanceSanitizerRepro
misonijnik added a commit that referenced this pull request Jul 3, 2026
- #7 PreparedStatementCreatorFactory:
newPreparedStatementCreator(String, Object[])
  DOES exist in Spring JDBC 5.3.x (arg0 is the SQL) — the "no String
overload" note
  was about the single-arg form. Added unsafeNewPSC using the 2-arg
overload;
  re-enabled. Suite: OK 979 | Skip 0 | FP 0 | FN 0.

- Removed the three disabled samples whose behavior is now captured by
minimal
  engine repros on misonijnik/core-engine-repros, leaving a NOTE that
points to
  each repro:
    - #2 staticResource(new URL("..."+resource))  ->
taint/WrapperPropagatorRepro
    - #3 ResponseEntity.header(..., "*") (varargs) ->
custom/BuilderChainMatchRepro
    - #9 (File $F).getCanonicalFile() sanitizer    ->
taint/InstanceSanitizerRepro
misonijnik added a commit that referenced this pull request Jul 3, 2026
- #7 PreparedStatementCreatorFactory:
newPreparedStatementCreator(String, Object[])
  DOES exist in Spring JDBC 5.3.x (arg0 is the SQL) — the "no String
overload" note
  was about the single-arg form. Added unsafeNewPSC using the 2-arg
overload;
  re-enabled. Suite: OK 979 | Skip 0 | FP 0 | FN 0.

- Removed the three disabled samples whose behavior is now captured by
minimal
  engine repros on misonijnik/core-engine-repros, leaving a NOTE that
points to
  each repro:
    - #2 staticResource(new URL("..."+resource))  ->
taint/WrapperPropagatorRepro
    - #3 ResponseEntity.header(..., "*") (varargs) ->
custom/BuilderChainMatchRepro
    - #9 (File $F).getCanonicalFile() sanitizer    ->
taint/InstanceSanitizerRepro
misonijnik added a commit that referenced this pull request Jul 4, 2026
- #7 PreparedStatementCreatorFactory:
newPreparedStatementCreator(String, Object[])
  DOES exist in Spring JDBC 5.3.x (arg0 is the SQL) — the "no String
overload" note
  was about the single-arg form. Added unsafeNewPSC using the 2-arg
overload;
  re-enabled. Suite: OK 979 | Skip 0 | FP 0 | FN 0.

- Removed the three disabled samples whose behavior is now captured by
minimal
  engine repros on misonijnik/core-engine-repros, leaving a NOTE that
points to
  each repro:
    - #2 staticResource(new URL("..."+resource))  ->
taint/WrapperPropagatorRepro
    - #3 ResponseEntity.header(..., "*") (varargs) ->
custom/BuilderChainMatchRepro
    - #9 (File $F).getCanonicalFile() sanitizer    ->
taint/InstanceSanitizerRepro
Saloed pushed a commit that referenced this pull request Jul 6, 2026
…ctor arg

Repro for the residual #2 gap behind the path-traversal FN
`new java.net.URL("file:///..." + resource)` ->
HttpResponses.staticResource(url).

taint/WrapperPropagatorRepro: a pattern-propagator `$W = new
Wrapper($SPEC)`
(from $SPEC to $W). PositiveDirect (`new Wrapper(data)`) is reported;
PositiveConcat
(`new Wrapper("prefix/" + data)`) is MISSED — the propagator does not
observe taint
when the constructor argument is a string concatenation. Same shape as
the ssrf
URL[] case that DOES work (direct var), isolating the concat as the
trigger.

TaintTest."wrapper propagator concat-arg repro" fails today
(PositiveConcat missed)
and should pass once propagators see taint through concatenated
arguments.
Saloed added a commit that referenced this pull request Jul 6, 2026
…lize ops to 3 slots

Two changes to the base-only (field-insensitive) access-path engine.

1. readAccessor abstraction fix. Reading a structural (field/element) accessor
   off a pure value-itself fact `.$` now yields the covering `.*` instead of
   leaving `.$` untouched. A `.$` fact carries no implicit `[any]`, so
   descending into an untracked field must widen to "anything reachable". This
   turns the getter summary edge in issues.issue85 into `this.* -> ret.*` (was
   `this.* -> ret.$`), which the maxFieldDepth=0 base version needs to carry
   object identity through a field getter. `.taint` (implicit [any]) and `.*`
   reads are unchanged.

   e2e (java-querylang, maxFieldDepth=0): 5 -> 2 failing methods. Fixes
   `issue 85` plus the two `rule with ellipsis method invocation*` false
   positives; the remaining `cleaner after sink 0` (needs depth >= 2) and
   `nd rule` (non-distributive) are pre-existing and unrelated. maxFieldDepth=1
   keeps the field distinct, so issue85's alias (oc.insideValue == acf) still
   needs a real alias analysis and stays a known miss there.

2. Eliminate the derived accessor array. BaseOnlyAccess kept a lazily-rebuilt
   `accessors: IntArray`; every op round-tripped through it (decompose/assemble/
   coreLength). All ops -- read/prepend/append/matchPrefix/clear/startsWith/
   equalToInitial/tail/withAbstract -- are now specialized against the three
   interned ints (staticIdx, fieldIdx, suffixIdx). The array is gone from the
   representation; enumeration for serialization and type filters goes through
   an allocation-free forEachAccessorIdx; intern(IntArray) survives only as the
   deserialization / abstraction-prefix construction boundary.

Behavior-preserving for #2: base-only unit suite 71/71 in both modes; e2e
identical to the read-fix-only state in both modes. Adds 13 abstraction unit
tests pinning the read/prepend/append/withAbstract/matchPrefix invariants.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Saloed added a commit that referenced this pull request Jul 7, 2026
…lize ops to 3 slots

Two changes to the base-only (field-insensitive) access-path engine.

1. readAccessor abstraction fix. Reading a structural (field/element) accessor
   off a pure value-itself fact `.$` now yields the covering `.*` instead of
   leaving `.$` untouched. A `.$` fact carries no implicit `[any]`, so
   descending into an untracked field must widen to "anything reachable". This
   turns the getter summary edge in issues.issue85 into `this.* -> ret.*` (was
   `this.* -> ret.$`), which the maxFieldDepth=0 base version needs to carry
   object identity through a field getter. `.taint` (implicit [any]) and `.*`
   reads are unchanged.

   e2e (java-querylang, maxFieldDepth=0): 5 -> 2 failing methods. Fixes
   `issue 85` plus the two `rule with ellipsis method invocation*` false
   positives; the remaining `cleaner after sink 0` (needs depth >= 2) and
   `nd rule` (non-distributive) are pre-existing and unrelated. maxFieldDepth=1
   keeps the field distinct, so issue85's alias (oc.insideValue == acf) still
   needs a real alias analysis and stays a known miss there.

2. Eliminate the derived accessor array. BaseOnlyAccess kept a lazily-rebuilt
   `accessors: IntArray`; every op round-tripped through it (decompose/assemble/
   coreLength). All ops -- read/prepend/append/matchPrefix/clear/startsWith/
   equalToInitial/tail/withAbstract -- are now specialized against the three
   interned ints (staticIdx, fieldIdx, suffixIdx). The array is gone from the
   representation; enumeration for serialization and type filters goes through
   an allocation-free forEachAccessorIdx; intern(IntArray) survives only as the
   deserialization / abstraction-prefix construction boundary.

Behavior-preserving for #2: base-only unit suite 71/71 in both modes; e2e
identical to the read-fix-only state in both modes. Adds 13 abstraction unit
tests pinning the read/prepend/append/withAbstract/matchPrefix invariants.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Saloed added a commit that referenced this pull request Jul 15, 2026
…lize ops to 3 slots

Two changes to the base-only (field-insensitive) access-path engine.

1. readAccessor abstraction fix. Reading a structural (field/element) accessor
   off a pure value-itself fact `.$` now yields the covering `.*` instead of
   leaving `.$` untouched. A `.$` fact carries no implicit `[any]`, so
   descending into an untracked field must widen to "anything reachable". This
   turns the getter summary edge in issues.issue85 into `this.* -> ret.*` (was
   `this.* -> ret.$`), which the maxFieldDepth=0 base version needs to carry
   object identity through a field getter. `.taint` (implicit [any]) and `.*`
   reads are unchanged.

   e2e (java-querylang, maxFieldDepth=0): 5 -> 2 failing methods. Fixes
   `issue 85` plus the two `rule with ellipsis method invocation*` false
   positives; the remaining `cleaner after sink 0` (needs depth >= 2) and
   `nd rule` (non-distributive) are pre-existing and unrelated. maxFieldDepth=1
   keeps the field distinct, so issue85's alias (oc.insideValue == acf) still
   needs a real alias analysis and stays a known miss there.

2. Eliminate the derived accessor array. BaseOnlyAccess kept a lazily-rebuilt
   `accessors: IntArray`; every op round-tripped through it (decompose/assemble/
   coreLength). All ops -- read/prepend/append/matchPrefix/clear/startsWith/
   equalToInitial/tail/withAbstract -- are now specialized against the three
   interned ints (staticIdx, fieldIdx, suffixIdx). The array is gone from the
   representation; enumeration for serialization and type filters goes through
   an allocation-free forEachAccessorIdx; intern(IntArray) survives only as the
   deserialization / abstraction-prefix construction boundary.

Behavior-preserving for #2: base-only unit suite 71/71 in both modes; e2e
identical to the read-fix-only state in both modes. Adds 13 abstraction unit
tests pinning the read/prepend/append/withAbstract/matchPrefix invariants.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant