From e07b4a28d6ac6086e5b652f72b9089e4d06f7e80 Mon Sep 17 00:00:00 2001 From: Christian Cleberg Date: Wed, 18 Mar 2026 19:23:29 -0500 Subject: harden README web rendering and sanitize untrusted links --- HutchTests/ReadmeViewTests.swift | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 HutchTests/ReadmeViewTests.swift (limited to 'HutchTests/ReadmeViewTests.swift') diff --git a/HutchTests/ReadmeViewTests.swift b/HutchTests/ReadmeViewTests.swift new file mode 100644 index 0000000..9c3c019 --- /dev/null +++ b/HutchTests/ReadmeViewTests.swift @@ -0,0 +1,29 @@ +import Foundation +import Testing +@testable import Hutch + +struct ReadmeViewTests { + + @Test + func sanitizedReadmeLinkURLStringRejectsUnexpectedSchemes() { + #expect(sanitizedReadmeLinkURLString("javascript:alert(1)") == nil) + #expect(sanitizedReadmeLinkURLString("file:///tmp/readme") == nil) + #expect(sanitizedReadmeLinkURLString("data:text/html;base64,SGVsbG8=") == nil) + } + + @Test + func processInlineDropsUnsafeMarkdownLinks() { + let rendered = processInline("[click me](javascript:alert)") + + #expect(rendered == "click me") + #expect(!rendered.contains("href=")) + #expect(!rendered.contains("javascript:")) + } + + @Test + func sanitizedReadmeLinkURLStringAllowsExpectedDestinations() { + #expect(sanitizedReadmeLinkURLString("https://example.com/docs?q=1") == "https://example.com/docs?q=1") + #expect(sanitizedReadmeLinkURLString("mailto:test@example.com") == "mailto:test@example.com") + #expect(sanitizedReadmeLinkURLString("#readme") == "#readme") + } +} -- cgit v1.2.3