potiuk opened a new pull request, #66741: URL: https://github.com/apache/airflow/pull/66741
## Summary Bring DAG `owner_links` and operator extra-link rendering in line with the scheme-allowlist policy already applied to markdown links (react-markdown's default [`urlTransform`](https://github.com/remarkjs/react-markdown#urltransform)) and log / XCom linkification (which is `https?://`-only). Before this change, both surfaces rendered DAG-author-supplied URLs (`dag.owner_links` set in the DAG file; operator extra-link URLs commonly read from task-pushed XCom) directly as `<a href={url} target="_blank">` with no scheme filter. `target="_blank"` blocks `javascript:` navigation on every modern browser, so the application itself provided no defense in depth on the rare legacy / embedded webview that still navigates `javascript:` in a new tab. After this change, both surfaces consult a shared `getSafeExternalUrl(url)` helper that passes through `http:` / `https:` / `mailto:` / relative URLs and returns `undefined` for anything else. Unsafe URLs are silently skipped on the extra-links page; the owner-link surface falls back to the existing in-app `/dags?owners=X` filter link. ## Files changed - `airflow-core/src/airflow/ui/src/utils/links.ts` — new `getSafeExternalUrl` helper. - `airflow-core/src/airflow/ui/src/utils/links.test.ts` — new vitest cases for the allow / reject matrix. - `airflow-core/src/airflow/ui/src/pages/TaskInstance/ExtraLinks.tsx` — wrap extra-link `url` with the helper; skip rendering when undefined. - `airflow-core/src/airflow/ui/src/pages/DagsList/DagOwners.tsx` — wrap `owner_links[owner]` with the helper; fall back to the filter-link when unsafe. ## Test plan - [ ] `pnpm vitest run src/utils/links.test.ts` — 34 / 34 tests pass (8 allow + 9 reject cases for `getSafeExternalUrl`, plus the existing tests) - [ ] `pnpm lint` — eslint clean, `tsc --p tsconfig.app.json` clean - [ ] `prek run --from-ref upstream/main --stage pre-commit` — clean ## Migration DAG-author-supplied `owner_links` entries using non-allowlisted schemes (`javascript:`, `data:`, `file:`, etc.) are silently skipped on the UI and fall back to the in-app owner-filter link; same for operator extra-links carrying such schemes. No DAG-level API surface changes. ##### Was generative AI tooling used to co-author this PR? - [X] Yes — Claude Opus 4.7 (1M context) Generated-by: Claude Opus 4.7 (1M context) following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
