The three-regex gate could be bypassed (an attribute without a space, <svg/onload>, entity-encoded or tab-split javascript: URLs, MathML xlink:href, base, meta refresh, forms) and it blanked a whole post or category when ordinary text such as "Data: 12 maja 2024" matched. - sanitizeJournalHtml runs sanitize-html with the Journal plugin's bluemonday policy: UGC elements plus footer, class, schema.org microdata, four validated inline styles, footnote roles, dir=auto, two chat transcript data attributes; http, https, mailto and relative URLs only - gateJournalHtml and isSafeJournalHtml keep their signatures; html is always the sanitized value and is never blanked - post body, category content and both page payloads are sanitized; the blocked notice, its style and string, and the blocked props and content_blocked field are removed - toPostView moves to postView.ts so list pages and cards do not load the sanitizer - tests cover every bypass from the review, the Data:/metadata: text and an imported author footer; the SSR smoke expects the unsafe sample's safe paragraphs
15 lines
606 B
Vue
15 lines
606 B
Vue
<script setup lang="ts">
|
|
// The post body. v-html only ever receives HTML that went through the Journal
|
|
// sanitizer, which removes what the policy does not allow and keeps the rest.
|
|
// The page passes an already sanitized body; sanitizing again here guards a
|
|
// caller that does not, and gives the same string on server and client.
|
|
import { sanitizeJournalHtml } from '../../utils/htmlGate.ts'
|
|
|
|
const props = defineProps<{ html: string | null | undefined }>()
|
|
const html = computed(() => sanitizeJournalHtml(props.html))
|
|
</script>
|
|
|
|
<template>
|
|
<div class="journal-post-body" v-html="html" />
|
|
</template>
|