Skip to content

Commit 86af861

Browse files
steipeteSebTardif
andcommitted
fix(security): remove raw blog description HTML
Co-authored-by: Sebastien Tardif <sebtardif@ncf.ca>
1 parent 10f1d9d commit 86af861

5 files changed

Lines changed: 13 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## Unreleased
44

5+
- Security: remove raw HTML from blog descriptions so frontmatter cannot inject active markup (#207, thanks @SebTardif).
56
- Testimonials: prune 20 low-signal shoutouts into the backup file, and add Windows chief @pavandavuluri's "Clawfather" Build shoutout and @rodrigofarinha on agent speed.
67

78
- Testimonials: add 5 more shoutouts — GitHub's @ashleywolf on the fastest-growing project celebration, plus @bartslodyczka, @nelsonlopes_, @morganlinton, and @mronge — with cached avatars.

src/content.config.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ const blog = defineCollection({
1919
schema: z.object({
2020
title: z.string(),
2121
description: z.string(),
22-
descriptionHtml: z.string().optional(),
2322
date: z.date(),
2423
// Single author (legacy)
2524
author: z.string().optional(),

src/content/blog/openclaw-nvidia-skill-security.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
---
22
title: "OpenClaw Collaborates with NVIDIA for Stronger Agent Skill Security"
33
description: "Every ClawHub skill now ships with a Skill Card documenting what the skill does and where it came from, and is scanned by SkillSpector for hidden instructions and other agentic risks"
4-
descriptionHtml: 'Every ClawHub skill now ships with a <a href="https://github.com/NVIDIA/Trustworthy-AI/blob/main/Skill%20Card.md">Skill Card</a> documenting what the skill does and where it came from, and is scanned by <a href="https://github.com/nvidia/skillspector">SkillSpector</a> for hidden instructions and other agentic risks'
54
date: 2026-06-01T05:30:00.000Z
65
authors:
76
- name: "Vincent Koc"

src/pages/blog/[...slug].astro

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ const canonicalPostUrl = absoluteUrl(blogPostPath(post));
7676
const ogImage = resolveBlogSocialImage(post.id, post.data.ogImage);
7777
const articleImageUrl = absoluteUrl(ogImage.src);
7878
79-
const descriptionHtml = post.data.descriptionHtml ?? post.data.description;
8079
const structuredAuthors = authors.map((author) => {
8180
const sameAs = getSortedAuthorLinkMeta(author)
8281
.map((link) => link.url)
@@ -127,7 +126,7 @@ const articleStructuredData = {
127126
<header class="article-header">
128127
<a class="back-link" href="/blog"><span aria-hidden="true">←</span> All posts</a>
129128
<h1>{post.data.title}</h1>
130-
<p class="dek" set:html={descriptionHtml} />
129+
<p class="dek">{post.data.description}</p>
131130

132131
<div class="byline">
133132
<div class="byline-avatars">

tests/static-assets.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,17 @@ function listSourceFiles(relativeDir: string): string[] {
3434
}
3535

3636
describe('static public assets', () => {
37+
test('renders blog descriptions as escaped text instead of raw HTML', () => {
38+
const articlePage = readText('src/pages/blog/[...slug].astro');
39+
const contentSchema = readText('src/content.config.ts');
40+
const blogSources = listSourceFiles('src/content/blog').map(readText);
41+
42+
expect(articlePage).toContain('<p class="dek">{post.data.description}</p>');
43+
expect(articlePage).not.toContain('set:html');
44+
expect(contentSchema).not.toContain('descriptionHtml');
45+
expect(blogSources.every((source) => !source.includes('descriptionHtml:'))).toBe(true);
46+
});
47+
3748
test('uses the canonical OpenClaw design-system contract', () => {
3849
const layout = readText('src/layouts/Layout.astro');
3950
const orderedImports = [

0 commit comments

Comments
 (0)