hotfix: readability's bug of failed to load document. (#2031)

* hotfix: fix the bug of sanitizing that causes readability failed to fetch document content.

* chores: add the commit `db83710` into changelog.

* chores: add additional description for DOMPurify.

* typo: rename the sanitizing function's parameter name.

---------

Co-authored-by: Innei <i@innei.in>
This commit is contained in:
但为君故 2024-12-07 16:40:16 +08:00 committed by GitHub
parent 6f7095e9ab
commit 05f5477139
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 17 additions and 6 deletions

View File

@ -1610,7 +1610,7 @@
* window memo object and markdown link render style ([70d0808](https://github.com/RSSNext/follow/commit/70d0808d75ad5ae754da3e84299566bbb55eec14))
* windows rounded left ([bf07c5e](https://github.com/RSSNext/follow/commit/bf07c5e2bfa740c02c6ca834e9935565098ca2a5))
* z-index ([d69df8b](https://github.com/RSSNext/follow/commit/d69df8bbacb159fb5bd5251a66c08fb58bec9d52))
* hotfix fix the bug of sanitizing that causes readability failed to fetch document content. ([db83710](https://github.com/RSSNext/follow/commit/db83710ee86eafa75052e80bc2c0e9927ea46560))
### Features

View File

@ -8,6 +8,19 @@ import { isDev } from "~/env"
const userAgents = `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36 ${name}/${version}`
// For avoiding xss attack from readability, the raw document string should be sanitized.
// The xss attack in electron may lead to more serious outcomes than browser environment.
// It may allows remotely execute malicious scripts in main process.
// Before the sanitizing, the DOMPurify requires a `window` environment provided by linkedom.
function sanitizeHTMLString(dirtyDocumentString: string) {
const parser = parseHTML(dirtyDocumentString)
const purify = DOMPurify(parser.window)
// How do DOMPurify changes the origin html structure,
// You can refer its document https://github.com/cure53/DOMPurify?tab=readme-ov-file#can-i-configure-dompurify
const sanitizedDocumentString = purify.sanitize(dirtyDocumentString)
return sanitizedDocumentString
}
export async function readability(url: string) {
const dirtyDocumentString = await fetch(url, {
headers: {
@ -27,15 +40,13 @@ export async function readability(url: string) {
return res.text()
})
// For avoid xss attack from readability, the raw document string should be purified.
const cleanedDocumentString = DOMPurify.sanitize(dirtyDocumentString)
const sanitizedDocumentString = sanitizeHTMLString(dirtyDocumentString)
const baseUrl = new URL(url).origin
// FIXME: linkedom does not handle relative addresses in strings. Refer to
// @see https://github.com/WebReflection/linkedom/issues/153
// JSDOM handles it correctly, but JSDOM introduces canvas binding.
const { document } = parseHTML(cleanedDocumentString)
const baseUrl = new URL(url).origin
const { document } = parseHTML(sanitizedDocumentString)
document.querySelectorAll("a").forEach((a) => {
a.href = replaceRelativeAddress(baseUrl, a.href)