Skip to content

Address reported security issues in the testresults module#654

Open
vagisha wants to merge 5 commits into
release26.3-SNAPSHOTfrom
26.3_fb_testresults-security
Open

Address reported security issues in the testresults module#654
vagisha wants to merge 5 commits into
release26.3-SNAPSHOTfrom
26.3_fb_testresults-security

Conversation

@vagisha

@vagisha vagisha commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

Rationale

A security review of the testresults module identified several issues, addressed here. (The cross-container access findings were already fixed on the 26.3 release branch and are not part of this PR.)

Changes

*Stored XSS (High) - result views and email preview

  • failureDetail.jsp: HTML-encode the failure language and stack trace
  • runDetail.jsp: render the run log/xml popup via a <pre> textContent node instead of document.write of concatenated HTML.
  • trainingdata.jsp: render the daily-email preview in a sandboxed iframe (scripts disabled, opaque origin) instead of document.write of the raw email HTML.

Transaction and SQL handling (Medium)

  • ChangeBoundaries.execute: wrapped the GlobalSettings update transaction in try-with-resources so it cannot leak on an exception before commit, and parameterized the INSERT with bind parameters.

Daily email output encoding (Low)

  • SendTestResultsEmail.getHTMLEmail: HTML-encode the git hash, missing-user name, problem-table computer name, and test name.

Logging hygiene (Low)

  • Replaced all five e.printStackTrace() calls with Log4J2 logging that includes the exception.

Tests

  • Added testViewLogPopup, which opens the run-log popup and asserts the stored log is displayed (the existing tests only exercised the ViewLog API).

Not in scope (by decision)

  • The unauthenticated PostAction upload (SkylineNightly posts) abuse control is deferred as a separate follow-up work.
  • The stack trace returned by PostAction / PostErrorFilesAction is kept intentionally, so SkylineTester can diagnose posting failures from the client.

Co-Authored-By: Claude noreply@anthropic.com

vagisha and others added 5 commits June 28, 2026 19:58
* failureDetail.jsp: HTML-encode the failure language and stack trace with
  LABKEY.Utils.encodeHtml before building the row markup, rather than
  concatenating them straight into innerHTML.
* runDetail.jsp: render the run log/xml popup via a <pre> textContent node
  instead of document.write of concatenated HTML.
* trainingdata.jsp: render the email preview in a sandboxed iframe (scripts
  disabled, opaque origin) instead of document.write of the raw email HTML.

All three display stored run/failure data that originates from the
unauthenticated SkylineNightly results upload (PostAction), so a crafted post
could otherwise store script that runs in an admin's browser.

Co-Authored-By: Claude <noreply@anthropic.com>
…urces

* ChangeBoundaries.execute: the GlobalSettings update transaction was opened
  with a bare assignment and committed with no try/finally, so it could leak if
  an exception was thrown before commit. Wrapped it in try-with-resources, like
  every other transaction in this controller.
* PostAction / PostErrorFilesAction: documented that the stack trace returned in
  the response is intentional, so SkylineTester can diagnose posting failures
  from the client without server log access. Noted by the security review;
  kept by design.

Co-Authored-By: Claude <noreply@anthropic.com>
…t includes

  the exception, per the logging convention. TestResultsController used its
  existing _log; RunDetail, TestResultsModule, and TestResultsWebPart got a
  static LOG via LogHelper.getLogger.
* ChangeBoundaries.execute: parameterized the GlobalSettings INSERT with bind
  parameters (VALUES (?, ?)) instead of concatenating the warning/error integer
  values into the SQL string.

Co-Authored-By: Claude <noreply@anthropic.com>
…g-user name,

  problem-table computer name, and test name.
* trainingdata.jsp: the email-preview iframe used height:100%, which collapses to
  zero against the popup body (no defined height) and showed a blank popup;
  switched to 100vh so the preview renders.
* TestResultsTest: added testViewLogPopup, which opens the run-log popup and
  asserts the stored log is displayed.

Co-Authored-By: Claude <noreply@anthropic.com>
* TestResultsController SaveXML: parameterized the two filename log statements
* ChangeBoundaries.execute: removed the unused GlobalSettings local
* TestResultsModule: moved the LogHelper import to its correct position.

Co-Authored-By: Claude <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