Skip to content

[bot] Merge 25.11 to 26.3#294

Open
github-actions[bot] wants to merge 6 commits into
release26.3-SNAPSHOTfrom
26.3_fb_bot_merge_25.11
Open

[bot] Merge 25.11 to 26.3#294
github-actions[bot] wants to merge 6 commits into
release26.3-SNAPSHOTfrom
26.3_fb_bot_merge_25.11

Conversation

@github-actions

Copy link
Copy Markdown

Generated automatically.
Merging changes from: 47ca924
Approve all matching PRs simultaneously.
Approval will trigger automatic merge.
Verify all PRs before approving: https://internal.labkey.com/Scrumtime/Backlog/harvest-gitOpenPullRequests.view?branch=26.3_fb_bot_merge_25.11

labkey-martyp and others added 6 commits June 22, 2026 13:02
## Rationale

`GetImportMethodsAction` and four sibling actions in
`LaboratoryController` looked up assay protocols by row id via
`ExperimentService.getExpProtocol(int)`, an unscoped global primary-key
lookup. Because these actions are guarded only by container-level
permissions, a user with read access to any single folder could supply
an arbitrary protocol row id and have the server operate on a protocol
defined in a folder they cannot read. `GetImportMethodsAction`
additionally echoed the protocol's name, container, and container path
back in its response, allowing cross-container enumeration of assay
design names and folder paths (an IDOR / information-disclosure issue).
The unchecked lookup in `GetImportMethodsAction` could also NPE on a
non-existent row id.

## Related Pull Requests

None.

## Changes

- Each protocol lookup now verifies the protocol is in scope for the
request container via `AssayService.getAssayProtocols(getContainer())`
before use, covering `GetImportMethodsAction`, `ProcessAssayDataAction`,
`SaveTemplateAction`, `CreateTemplateAction`, and
`GetAssayImportHeadersAction`.
- The scope check is folded into each existing null guard, returning the
same generic not-found message whether the row id is unknown or simply
out of scope, so the response is not an existence oracle.
- Legitimate same-container callers (e.g.
`Laboratory.Utils.getAssayDetails` from the assay import/template
panels) are unaffected, since they always pass an in-scope protocol.
## Rationale

Two spots in LDKController rendered untrusted content as raw HTML. The
container-scoped-table inspection view is a correction to a previous
security fix (#268): the HTMLView cleanup there wrapped the whole string
in HtmlString.of, which escaped the literal <br>/<p> markup too — safe,
but it broke the intended formatting. This escapes only the dynamic
validation messages (which can contain arbitrary content from direct DB
inserts that bypass the user schema) while preserving the markup. The
invalid-redirect error message separately echoed the user-supplied URL
via HtmlString.unsafe, so it is now escaped.

## Related Pull Requests

- #268

## Changes

- Container-scoped-table inspection view: escape each validation message
with PageFlowUtil.filter before joining with <br>, then wrap the
assembled markup in HtmlString.unsafe — fixing the over-escaping
introduced by #268 while keeping the output safe.
- Invalid-redirect error message: switch the user-supplied URL from
HtmlString.unsafe to HtmlString.of so it is escaped.
#### Rationale
Using StringBuilder to manually build up HTML is error prone and unsafe.
Updating usages to use the java DOM API so all HTML is properly escaped
and potential XSS issues are mitigated.

#### Related Pull Requests
* <!-- list of links to related pull requests (replace this comment) -->

#### Changes
* LaboratoryController: Use java DOM API instead of StringBuilder
 Conflicts:
	laboratory/src/org/labkey/laboratory/LaboratoryController.java
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.

4 participants