Skip to content

Model static UI5 bindElement contexts - #448

Closed
mbaluda wants to merge 8 commits into
mbaluda/fp-manifest-modelsfrom
mbaluda/ui5-binding-contexts
Closed

mbaluda wants to merge 8 commits into
mbaluda/fp-manifest-modelsfrom
mbaluda/ui5-binding-contexts

Conversation

@mbaluda

@mbaluda mbaluda commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

What This PR Contributes

  • Adds a runnable UI5 application that demonstrates client-side XSS through an inherited bindElement context:
    • An Input writes to the absolute default-model path /customer/name.
    • HTML controls read relative {name} beneath string and object-form bindElement contexts.
    • A Playwright regression verifies every supported positive sink and every negative sink independently.
  • Models statically known default-model contexts assigned with:
    • control.bindElement("/absolute/path").
    • The legacy control.bindElement("/absolute/path", parameters) overload.
    • control.bindElement({ path: "/absolute/path", ... }) object binding information.
  • Scopes context propagation precisely:
    • Applies the context only to the target control and its descendants in the owning controller/view.
    • Supports both XML and JSON view control hierarchies.
    • Selects the nearest nested bindElement context.
    • Preserves a closer items aggregation context instead of incorrectly using an outer element context.
    • Excludes named-model binding information and model>path strings.
  • Adds positive and negative CodeQL coverage for exact path resolution and XSS:
    • Vulnerable absolute-source-to-relative-sink flows for all supported overloads.
    • XML and JSON view contexts.
    • Sibling controls that do not inherit the context.
    • Named-model bindings.
    • Nested bindElement overrides.
    • Nested items aggregation precedence.
  • Depends on Model manifest-created UI5 client data models #447, which provides path-specific manifest-created JSON model nodes and linear canonical binding flow.
  • Validation:
    • npm ci && npm run test:runtime in javascript/frameworks/ui5/test/queries/UI5Xss/xss-bind-element-context — passed (1/1 Playwright test).
    • codeql test run javascript/frameworks/ui5/test — passed (81/81 CodeQL tests).
    • git diff --check — passed.

Future Works

  • Support bindObject.
  • Support dynamically computed binding contexts.
  • Model setBindingContext, createBindingContext, and context-producing APIs.
  • Generalize context propagation to additional aggregation APIs and factory callbacks.

@mbaluda
mbaluda added this pull request to stack #449 October 2, 2026 12:19
@mbaluda mbaluda changed the title mbaluda/ui5 binding contexts Model static UI5 bindElement contexts Oct 2, 2026

This comment was marked as resolved.

@mbaluda
mbaluda force-pushed the mbaluda/ui5-binding-contexts branch from 6eb5273 to b591929 Compare October 2, 2026 13:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

JSON-specific logic lacks coverage, and aggregate runtime assertions can conceal incorrect sink behavior.

Review effort: Balanced
Findings: 2 Medium severity

Open (2)
Resolved since last review (1)

mbaluda and others added 5 commits October 2, 2026 18:12
Provide a runnable UI5 app and Playwright test proving unsanitized flow through an inherited bindElement context before static modeling.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Resolve relative default-model bindings through the nearest statically known bindElement context while preserving closer aggregation contexts and view isolation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Accept the Code Scanning output produced by workflow run 37006051980 for the bindElement context regression.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Extract static default-model paths from legacy two-argument calls and object binding infos while excluding named-model contexts.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Exercise JSON control containment and context precedence, and assert every positive and negative runtime sink independently.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 2, 2026 16:16
@mbaluda
mbaluda force-pushed the mbaluda/ui5-binding-contexts branch from 0ff1a36 to 074f099 Compare October 2, 2026 16:16

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

JavaScript-view bindings remain unsupported, and the lockfile contains organization-specific package URLs.

Review effort: Balanced
Findings: 1 High severity · 2 Medium severity

Open (3)
Resolved since last review (1)

},
"node_modules/@adobe/css-tools": {
"version": "4.5.0",
"resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@adobe/css-tools/-/css-tools-4.5.0.tgz",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated all 498 lockfile tarball URLs to registry.npmjs.org while preserving the locked dependency versions. Commit: 8743ee1.

Accept the Code Scanning output produced by workflow run 37032867682 after the latest UI5 context regressions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 2, 2026 16:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Control-reference ambiguity can produce false contexts, and relative aggregation composition lacks regression coverage.

Review effort: Balanced
Findings: 1 High severity · 3 Medium severity

Open (4)
Resolved since last review (2)

Comment on lines +200 to +203
not exists(UI5BindingPath itemsBinding |
itemsBinding = bindingPath.getNearestEnclosingItemsBinding() and
controlIsDescendantOrSelf(itemsBinding.getControlDeclaration(), context.getControl())
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a relative aggregation regression asserting /customer + {orders} + {name} resolves to /customer/orders/name. Commit: 8743ee1.

@mbaluda

mbaluda commented Oct 3, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Fix the code for all comments in this review thread.

When a review comment includes a suggested change, apply the suggestion exactly.

Do not make changes beyond what is described in the linked review thread.

Co-authored-by: mbaluda <5237080+mbaluda@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 3, 2026 14:09

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Path-resolution errors and ineffective regression fixtures still need correction.

Review effort: Balanced
Findings: 1 High severity · 3 Medium severity

Open (4)
Previously missed (4)

In code that hasn't changed since last review

Medium severity Avoid duplicate separators in resolved binding paths

javascript/​frameworks/​ui5/​lib/​advanced_security/​javascript/​frameworks/​ui5/​UI5View.qll:212

With bindElement("/customer/"), UI5 resolves {name} to /customer/name, but this helper produces /customer//name. Manifest-backed flow compares absolute paths exactly, so an input bound to /customer/name no longer reaches this sink. Reuse an existing trailing separator, and add a path-resolution regression for this case.

Medium severity Use VBox items aggregation for child controls

javascript/​frameworks/​ui5/​test/​queries/​UI5Xss/​xss-bind-element-context/​json_component/​view/​app.view.json:22

Both jsonCustomerDetails and jsonOtherDetails are sap.m.VBox controls, which use the inherited items aggregation, not content. UI5 therefore cannot attach these children as written, even though the expected results treat them as an inherited-context XSS flow and a nested context override. Change both child aggregations to items so the fixture represents a valid UI5 hierarchy.

Medium severity Use a valid items aggregation for context binding

javascript/​frameworks/​ui5/​test/​queries/​UI5Xss/​xss-bind-element-context/​json_component/​view/​app.view.json:32

sap.ui.commons.Carousel has a content aggregation, not items, so items: "{/otherList}" does not create a list-entry context in UI5. The expected /otherList/name result thus validates a context that this fixture cannot produce. Use a control with an items aggregation and a valid JSONView binding/template, then update both expected-result files to verify aggregation precedence on that hierarchy.

Medium severity Match cloned aggregation sink IDs

javascript/​frameworks/​ui5/​test/​queries/​UI5Xss/​xss-bind-element-context/​runtime/​xss.spec.js:5

The List renders clones of its template, with IDs such as ...--aggregationSink-__clone0. The current suffix selector misses those clones, so the aggregationSink negative assertion passes even if a rendered clone contains the injected marker. Match cloned sink IDs as well as the original IDs.

Co-authored-by: mbaluda <5237080+mbaluda@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 3, 2026 14:32

Copilot AI commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

@copilot Fix the code for all comments in this review thread.

When a review comment includes a suggested ch...

Addressed the linked review findings in 8743ee1. The targeted CodeQL tests and Playwright regression pass.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +153 to +155
not exists(bindingPath.getModelName()) and
controller = bindingPath.getView().getController() and
controlContainsBinding(this.getControl(), bindingPath)
Comment on lines +201 to +203
not exists(StaticBindElementContext closer |
closer.appliesTo(bindingPath) and
controlIsStrictDescendant(closer.getControl(), result.getControl())
Comment on lines +221 to +222
if contextPath = "/"
then result = "/" + relativePath
new sap.m.Input({
value: "{/customer/name}"
}),
new sap.ui.core.HTML("jsBoundSink", {
@mbaluda mbaluda closed this Oct 3, 2026
Copilot stopped work on behalf of mbaluda due to an error October 3, 2026 21:37
Copilot stopped work on behalf of mbaluda due to an error October 3, 2026 21:37
Copilot stopped work on behalf of mbaluda due to an error October 3, 2026 21:39
@mbaluda
mbaluda deleted the mbaluda/ui5-binding-contexts branch October 4, 2026 10:10
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