Prasad P. Pawar created ATLAS-5417:
--------------------------------------
Summary: Atlas UI: Fix unescaped business metadata string
rendering in Classic UI basic search results table.
Key: ATLAS-5417
URL: https://issues.apache.org/jira/browse/ATLAS-5417
Project: Atlas
Issue Type: Bug
Components: atlas-webui
Affects Versions: 3.0.0
Reporter: Prasad P. Pawar
Assignee: Prasad P. Pawar
h3. Summary
Business metadata string attribute values could be stored via the REST API with
HTML markup and were shown in the Classic UI ({{{}dashboardv2{}}}) basic search
results without proper content filtering. When a user with appropriate access
opened search results containing those values, the browser could interpret the
markup as active content instead of plain or safely formatted text.
This ticket addresses incorrect rendering behavior in the search results table
for business metadata string columns.
h3. Problem / Root Cause
Metadata text is stored and returned as provided on the write path. In Classic
UI basic search:
# Business metadata string columns were flagged as {{isEditorValue}}
(rich-text/editor fields).
# The search table renderer skipped HTML entity escaping for those values.
# Raw values were inserted into the DOM via Backgrid {{{}HtmlCell{}}}.
# Values written through the REST API bypassed the UI-only sanitizer used on
the entity edit path.
Affected area: Classic UI ({{{}dashboardv2{}}}) — basic search results table,
business metadata string attribute columns only.
Not affected: React UI ({{{}dashboard/{}}}) — search and detail views already
use React text escaping or HTML allowlist sanitization.
h3. Solution Implemented
||File||Change||
|{{dashboardv2/public/js/utils/CommonViewFunction.js}}|When {{isEditorValue}}
is set, route values through {{Utils.sanitizeHtmlContent()}} (DOMPurify
allowlist) instead of inserting raw HTML|
|{{dashboardv2/public/js/views/search/SearchResultLayoutView.js}}|Document why
{{checkIsEditorValue}} marks business metadata string columns for sanitized
rich-text display|
Allowed markup after fix: {{{}b{}}}, {{{}em{}}}, {{{}strong{}}}, {{{}u{}}},
{{{}a[href]{}}}, lists, {{{}p{}}}, headings, {{strike}}
Removed/blocked: {{{}script{}}}, {{{}img{}}}, {{{}iframe{}}}, event handlers,
{{javascript:}} URLs
h4. Overall code coverage (after changes)
{code:java}
Project overall: 88.82% statements | 82.15% branches | 80.19% functions Tests:
4947 passed / 197 suites Changed-area subset: Utils.ts 92.79% statements
HtmlRenderer.tsx 100.00% statements ShowMoreText.tsx 100.00% statements
commonComponents.tsx 100.00% statements{code}
Classic UI ({{{}dashboardv2{}}}) has no Jest suite — regression covered by
manual QA below.
h3. Manual test steps (Classic UI)
Preconditions: Business metadata with a string attribute (e.g.
{{{}bm1.notes{}}}); entity with that attribute set via REST API.
||Step||Action||Expected result||
|1|Set attribute via REST API to {{<img src=x onerror="alert(1)">}}|Value
stored in metadata|
|2|Log in to Classic UI, run basic search, enable BM column|No alert/dialog;
cell empty or shows safe text only|
|3|Set value to {{<p>Hello <strong>world</strong></p>}}|Cell shows formatted
text: Hello world|
|4|Set value to {{Plain text notes}}|Cell shows: {{Plain text notes}}|
----
h3. Example: test input vs UI output
h4. Example 1 — Active markup in metadata (Classic UI search)
Input (REST API):
<img src=x onerror="alert('test')">
|| ||Before fix||After fix||
|UI behavior|Browser dialog / script runs|Nothing runs|
|Cell display|Image tag processed|Empty or safe text only|
|DOM|{{<img>}} element present|No {{<img>}} element|
----
h4. Example 2 — Script tag in metadata (Classic UI search)
Input (REST API):
<script>alert('test')</script><p>Safe notes</p>
|| ||Before fix||After fix||
|UI behavior|Script may run|Script does not run|
|Cell display|Mixed|Safe notes (with optional {{<p>}} formatting)|
|DOM|{{<script>}} may be present|No {{<script>}} tag|
----
h4. Example 3 — Safe rich text (Classic UI search)
Input (REST API):
<p>Review <strong>approved</strong> by team</p>
|| ||After fix||
|Cell display|Review approved by team|
|Behavior|Formatting preserved; no active markup|
----
h4. Example 4 — Same payload in React UI search (reference)
Input: {{<img src=x onerror="alert(1)">}}
|| ||React UI output||
|Cell display|Literal text: {{<img src=x onerror="alert(1)">}}|
|DOM|No {{<img>}} element (React auto-escapes JSX text)|
----
h3. Build & quality gates
||Check||Result||
|ESLint|0 errors|
|TypeScript|Pass|
|Vite build|Pass (~6.85s)|
|Jest (serial)|4947/4947 pass|
h3. Acceptance criteria
* Business metadata string values in Classic UI basic search render through
DOMPurify allowlist
* Active markup in metadata does not run in the browser when viewing search
results
* Safe rich text (bold, paragraphs, links) still displays correctly
* All 4947 automated tests pass
* Manual Classic UI QA completed per steps above
--
This message was sent by Atlassian Jira
(v8.20.10#820010)