FIX: Write only a safe session id and a positive sequence into the client script - #145
Conversation
…ient script The session id is written into the script inside quotes and the sequence as a number, both as given. A session id holding a quote or a backslash broke the script, and a sequence below 1 was written as it was. A session id that is not 1 to 64 ASCII letters, digits and hyphens is now written as an empty string, and a sequence that is not a positive 32 bit integer is written as 1. A sequence given as text is now read when it is made of digits, as the .NET builder does.
Proven in CIFull build and test run on this branch: https://github.com/51Degrees/pipeline-java/actions/runs/35187920129 A draft pull request only runs the link lint, so the Pull Requests workflow was dispatched against this branch as a dry run to get real evidence. Nothing was merged, and the log shows why: with no pull request based on this branch the run builds the branch on its own as pull request 0, and the checkout and completion steps both print "Not running for a PR". All 15 jobs finished green, being 11 build and test jobs (Java 8, 11, 17 and 21 on Ubuntu and Windows, and Java 11, 17 and 21 on macOS), the pull request lookup, the configure step, the performance comparison and the completion step. Reading the job logs rather than the conclusions, each job reports 23 Maven module summaries, and on Java 11 and later they add up to 657 tests run with 0 failures, 0 errors and 0 skipped. Java 8 runs 642, the difference being the tests that need a later Java. The log contains no "BUILD FAILURE", no "FAILURES!", no "ERRORS!" and no summary line with a non-zero failure or error count. The pull request has not been marked ready and no review has been requested. |
What is wrong
The JavaScript builder writes the session id into the script inside double
quotes and the sequence as a number, both exactly as the evidence gives
them.
the page gets nothing. The session id can come from the page request as
query.session-idevidence, and the Sequence Element keeps a session idthat is already there rather than replacing it.
0or anegative number reaches the script. The Sequence Element adds one to
whatever number it finds, so a request carrying
-1reaches the builderas
0, and the largest integer wraps round to the smallest.sequence of
1and an empty session id.What changed
JavaScriptBuilderElement:^[A-Za-z0-9-]{1,64}$, andanything else, including a value of the wrong type, is written as an
empty string;
anything else is written as
1;what the .NET builder does. Before this change, text was ignored and the
sequence was always
1.The rule is in the specification, in the draft
51Degrees/specifications#31 (steps 3 and 5 of
pipeline-specification/pipeline-elements/javascript-builder.md).Tests
SessionIdAndSequenceTests, which needs no browser. Each rendered scriptis parsed with the GraalVM JavaScript engine that this module already
depends on, without running it. The tests are:
SessionId_Valid_Rendered,SessionId_LongestValid_RenderedSessionId_Invalid_RenderedEmptyfora"b,a\b,</script>, a 65character id, a non-ASCII id and an empty one
SessionId_InvalidWithSequenceElement_RenderedEmpty, the same valueswith the Sequence Element in the pipeline
SessionId_FromSequenceElement_RenderedNoSequenceElement_NoEvidence_DefaultsRenderedSequence_InvalidText_RenderedOneforabc,-1,0,99999999999,an empty value and
2147483648Sequence_InvalidNumber_RenderedOnefor-1,0, the smallest integerand a value too large for an integer
Sequence_Valid_Renderedfor5and the largest integer, as a numberand as text
Sequence_InvalidWithSequenceElement_RenderedOnefor-1and thelargest integer, which the Sequence Element turns into
0and thesmallest integer
Before the source change, 17 of the 32 cases fail, including:
With the change, the module's tests pass, leaving out
JavaScriptBuilderTestsbecause it starts a browser:Things found on the way that are not changed here
is already an
Integer, so in practice this module cannot run without theSequence Element. The tests that need a pipeline without that element use
a small stand in for the JSON builder so the values reach the builder as
given.
int, so arequest carrying
sequence=abcmakes the pipeline throw rather thanstarting again at 1. Nothing reaches the script in that case.
query.session-idorquery.sequence, so in a web application neither is collected from therequest unless another element asks for them. The usage sharing filter
does ask for them.
Overlap with other work
builds the script rather than in the session id and sequence, so the two
do not touch the same lines.
The same change in the other ports
The Node port of this change is
pipeline-node#207.
The merges between this draft, #143 and #144 were run locally in both
directions and all six are clean. The three way merge was built and tested
as well, giving
Tests run: 74, Failures: 0, Errors: 0, Skipped: 0andBUILD SUCCESSforpipeline.javascriptbuilder, leaving out the test thatstarts a browser. So the three can land in any order without a merge.
CI on this branch, 17 September 2026
The "Pull Requests" workflow was dispatched on this branch with
dryrun=true,which builds the branch and merges nothing. Run
35187920129
ran on
34ec39b, the head of this branch, and concluded success with all 15jobs green. In the
Ubuntu_Java_21job the Maven totals are 657 tests run, 0failures, 0 errors and 6 skipped, with no error lines in the log.
This branch is three commits behind
mainand merges into it cleanly.The nightly checks out the pull request, merges
maininto it and buildsthat before it merges anything, so the combination is tested there.