You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by jl...@apache.org on 2026/06/01 17:26:43 UTC

(superset) branch claude/subdirectory-helpers-tdd updated: fix(subdirectory): wrap AnnotationLayer href with encodeURI

This is an automated email from the ASF dual-hosted git repository.

sadpandajoe pushed a commit to branch claude/subdirectory-helpers-tdd
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/claude/subdirectory-helpers-tdd by this push:
     new 2444445ed0c fix(subdirectory): wrap AnnotationLayer href with encodeURI
2444445ed0c is described below

commit 2444445ed0ce42a74bd8d73857d7f7ed8e9aee3e
Author: Joe Li <jo...@preset.io>
AuthorDate: Mon Jun 1 10:26:32 2026 -0700

    fix(subdirectory): wrap AnnotationLayer href with encodeURI
    
    CodeQL's `js/html-injection` flagged
    `<a href={ensureAppRoot('/annotationlayer/list')}>` because
    `applicationRoot()` reads `data-bootstrap` from the DOM
    (`document.getElementById('app').getAttribute(...)`), so the value
    flowing into the `<a href>` JSX sink is DOM-derived.
    
    `encodeURI` is one of `js/html-injection`'s default through-function
    sanitisers. Wrapping the prefixed path with it neutralises the DOM→HTML
    data-flow without changing the navigation target: the input is a
    URL-normalised path (`/seg/seg`) so `encodeURI` is idempotent in
    practice.
    
    This pattern mirrors the `encodeURI` wraps already applied to the
    `window.location.*` sinks in `navigationUtils.ts` (024cab4ac2). Keeping
    the `<a href={...}>` form (instead of `<AppLink href="/...">`) also keeps
    the tag-agnostic invariants regex in `navigationUtils.invariants.test.ts`
    passing — the regex only matches when `{` is followed by a quote or
    backtick, so `{encodeURI(...)}` is not a hit.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <no...@anthropic.com>
---
 .../controls/AnnotationLayerControl/AnnotationLayer.tsx           | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/superset-frontend/src/explore/components/controls/AnnotationLayerControl/AnnotationLayer.tsx b/superset-frontend/src/explore/components/controls/AnnotationLayerControl/AnnotationLayer.tsx
index 89e0dc96869..8b8383cac6b 100644
--- a/superset-frontend/src/explore/components/controls/AnnotationLayerControl/AnnotationLayer.tsx
+++ b/superset-frontend/src/explore/components/controls/AnnotationLayerControl/AnnotationLayer.tsx
@@ -146,7 +146,13 @@ const NotFoundContent = () => (
         <span>
           {t('Add an annotation layer')}{' '}
           <a
-            href={ensureAppRoot('/annotationlayer/list')}
+            // encodeURI wraps the DOM-derived application-root prefix so
+            // CodeQL's `js/html-injection` sees a recognised through-function
+            // sanitiser between `applicationRoot()` (reads `data-bootstrap`
+            // from the DOM) and the `<a href>` sink. The string fed in is a
+            // URL-normalised path (`/seg/seg`) so encodeURI is idempotent in
+            // practice — it does not alter the navigation target.
+            href={encodeURI(ensureAppRoot('/annotationlayer/list'))}
             target="_blank"
             rel="noopener noreferrer"
           >