[
https://issues.apache.org/jira/browse/ATLAS-5417?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18119075#comment-18119075
]
ASF subversion and git services commented on ATLAS-5417:
--------------------------------------------------------
Commit d266321e9d8a584de446a1d8e673654e304587fd in atlas's branch
refs/heads/ATLAS-5417_UI_unescapeString from Prasad Pawar
[ https://gitbox.apache.org/repos/asf?p=atlas.git;h=d266321e9 ]
ATLAS-5417: Atlas UI: Fix unescaped business metadata string rendering in
Classic UI basic search results table.
> 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
> Priority: Major
>
> 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)