Files
windmill/frontend/src/lib/components/MarkupApprovalGate.svelte
T
hugocasaandClaude Opus 4.8 7b813d1f74 fix(frontend): sanitize job result markup, gate it on unsandboxed public apps (#10127)
* fix(frontend): sanitize html and svg result rendering

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore(frontend): add dompurify to lockfile root deps

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(frontend): keep sanitizing rich results on public app surfaces

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(frontend): gate risky app markup on unsandboxed public surfaces

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(frontend): derive app markup isolation from the real origin

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* style(frontend): use the design-system danger alert for the markup gate

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 15:49:20 +02:00

31 lines
1000 B
Svelte

<script lang="ts">
import { Button } from './common'
import Alert from './common/alert/Alert.svelte'
// Shown instead of runnable-authored markup on the public app surfaces, where the
// app's author and its viewer are different people and the app is not sandboxed.
// Enabling the app's sandbox isolates the markup and removes this prompt.
let { children }: { children: import('svelte').Snippet } = $props()
let approved = $state(false)
</script>
{#if approved}
{@render children()}
{:else}
<Alert type="error" title="This content is not rendered">
<div class="flex flex-col items-start gap-2">
<p>
Rendering it can expose you to <a
href="https://owasp.org/www-community/attacks/xss/"
target="_blank"
rel="noreferrer"
class="underline">XSS attacks</a
>. Only enable it if you trust the author of this app.
</p>
<Button unifiedSize="sm" variant="default" on:click={() => (approved = true)}>
Enable rendering
</Button>
</div>
</Alert>
{/if}