a2ui-project / a2ui-project/a2ui

[BUG]: `createSurface.theme` values stored without validation and consumed as CSS values

Abierto
#2,293 2 comentarios 0 reacciones 1 asignado Reclamado por @Varun-S10 Ver en GitHub
P2 status: first-line-handled status: needs review type: bug
Lenguaje dominante
TypeScript
Estrellas
16.4k
Forks
1.3k
Merge medio
2 d 13 h
PR fusionados (30 d)
134

Descripción

# `createSurface.theme` values stored without validation and consumed as CSS values

Repository: https://github.com/a2ui-project/a2ui
Affected package: `@a2ui/web_core` (verified on 0.10.6); observable in the Angular renderer
CWE: CWE-20 (Improper Input Validation) with CSS value injection consequence

## Summary

The specification states that theme fields such as `primaryColor` must be hexadecimal color codes, but no layer enforces this. The message envelope declares `theme: z.any()`, the surface model stores it verbatim, and the Angular renderer pipes it into a CSS custom property that a Button consumes via the `background` shorthand — where `url(...)` is valid.

## Affected code

- `renderers/web_core/src/v0_9/schema/server-to-client.ts:33` — `theme: z.any()`
- `renderers/web_core/src/v0_9/state/surface-model.ts:57-65` — stored verbatim (themeSchema is only broadcast in capabilities)
- `renderers/angular/.../basic-catalog-component.ts:69-72` — `@HostBinding('style.--a2ui-color-primary')`
- `renderers/angular/.../button.component.ts:77` — `background: var(--a2ui-color-primary)` (shorthand)

## Observed behavior

- `createSurface` with `theme: {primaryColor: "url(https://attacker.example/beacon)"}` is accepted and stored verbatim through the published package pipeline (no error).
- In the Angular renderer, the button's computed `background-image` contains the injected URL, and one cross-origin request was captured via the Performance API.
- The Lit renderer consumes `background-color`, where `url()` is inert; only the Angular shorthand path is affected.

## Impact

An agent can cause cross-origin requests from the host origin (disclosing IP/User-Agent/timing) and overlay attacker-chosen imagery on buttons (UI spoofing). No script execution was achieved — the value remains contained within a CSS declaration.

## Suggested remediation

Validate theme on receipt: `themeSchema.parse(theme)` with a strict hex/named-color allowlist.

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.