Skip to content

Sanitize data-driven homepage output to prevent stored XSS - #95

Closed
VatsalSy wants to merge 793 commits into
mainfrom
comphy-lab/fix-unescaped-yaml-content-vulnerability
Closed

Sanitize data-driven homepage output to prevent stored XSS#95
VatsalSy wants to merge 793 commits into
mainfrom
comphy-lab/fix-unescaped-yaml-content-vulnerability

Conversation

@VatsalSy

Copy link
Copy Markdown
Member

Motivation

  • The homepage rendered YAML fields verbatim via Liquid, which allowed author-curated HTML to pass through and introduced a stored XSS/attribute-injection risk if data files were tampered with.
  • The intent is to preserve a very small set of allowed inline formatting (e.g. , , , nbsp) while ensuring all other content and links are escaped or validated.

Description

  • Add _includes/safe-inline.html which first escapes input and then selectively restores a limited set of approved inline tags/entities.
  • Add _includes/safe-href.html which validates/escapes href values and only permits site-relative anchors/paths, http(s), or mailto:, falling back to # for unsafe values.
  • Update index.html to route hero tagline/lede, theme descriptions, news meta, image attributes, action labels, team bios and other data-driven fields through safe-inline.html, safe-href.html, and | escape/| slugify as appropriate to prevent text- and attribute-context injection.
  • Ensure image alt, poster, src, and other attributes are escaped and that link targets are constrained to safe schemes.

Testing

  • Ran npm test -- --runInBand, all test suites passed (12 suites, 77 tests).
  • Ran ./scripts/lint-check.sh, lint checks completed successfully with no blocking issues.
  • Attempted bundle exec jekyll build but it could not be executed in this environment due to local Ruby/Gemfile/Bundler mismatches and remote gem fetch failures, so a full Jekyll build was not run here.

Codex Task

VatsalSy and others added 30 commits November 9, 2025 15:25
- Capitalize 'Markdown' in add-person.md documentation
- Fix quote escaping in teaching.js selector strings
- Break long selector string into multiple lines for readability
October 2025 website updates - Team, research, teaching additions
- Add js-yaml override to force version >=4.1.1
- Resolves Dependabot alerts #10 and #11
- Fixes prototype pollution in YAML merge operations
Add volume 22 and page range 657-667 for the stood-up drop paper now that it's officially published.
Adds comprehensive command-line options to both scripts:

Build script (build.sh):
- --help: Display usage information
- --clean: Force rebuild by removing _site and .jekyll-cache
- --skip-deps: Skip dependency installation for faster rebuilds
- --skip-seo: Skip SEO metadata generation
- --skip-research: Skip research page generation

Deploy script (deploy.sh):
- --help: Display usage information
- --port PORT: Use specific port instead of auto-detection
- --host HOST: Bind to specific host (default: localhost)
- --drafts: Include draft posts in build
- --incremental: Enable faster incremental rebuilds
- --no-livereload: Disable live reload feature
- --open: Auto-open browser after server starts

Both scripts maintain backward compatibility and include improved
error handling and user feedback.
Adds year-based organization to News.md and history.md:
- Creates separate sections for 2026 and 2025
- Moves Durham University announcement under 2025 heading
- Adds paper [21] (Soft Matter) to January 2026 section
- Maintains 5-item limit for regular news items
- Updates add-news command to handle year sections
- Special announcements now excluded from 5-item count

This structure makes the news system more scalable as we enter 2026.
Changes to aboutCoMPhy.md:
- Update location badge from Physics of Fluids to Durham University
- Change map link to Durham campus location
- Remove mailto badge to avoid duplicate email display
- Keep two email containers with envelope and copy functionality
Keep shared command definitions in the OpenCode directory. Ignore the local .claude symlink so it stays machine-specific.
Reject missing or non-numeric port values and missing host args up front. Clarify news month ordering guidance to match reverse-chronological usage.
Generate the GitHub App token before checkout and push via origin so
updates are attributed to the app for ruleset bypass.
Force author and committer identity to the GitHub App bot and
log the latest commit metadata for verification.
Preserve jsdom globals in Jest setup and align tests.
Scope markdownlint to repo ignores and quiet noisy content.
Relax ESLint max-len/no-console for legacy scripts and fix CSS spacing.
VatsalSy and others added 22 commits April 25, 2026 08:39
The legacy --research-list-text chain in styles.css resolves to
--color-secondary, which bridge.css remaps to --c-paper-tint --
invisible on dark paper. --c-brand-blue also lacks a dark override,
leaving the Highlights heading dim. Override both in research-v2.css
with theme-aware values.
Website v2: design-system migration, redesigned homepage + team + research + news
Pad table separator rows for markdownlint MD060
Replace the broken /VatsalSy and /comphy-bot footer routes with live external destinations so the v2 footer no longer emits 404s.
Adds the Tiny Defects, Big Consequences news item that was
only in News.md but not in the structured feed. Fixes typo
in URL (tiniy -> tiny).

Closes #5182
- Added news item for the award (kind: award, date: 2026-05-28)
- Added featured hero work entry showcasing the award video on landing page
- Added the image as poster frame for the video hero slide
- Updated index.html to support poster attribute on video elements
Update npm and Ruby dependency constraints to resolve the current Dependabot alerts for fast-uri, PostCSS, and Nokogiri. Also refresh markdownlint-cli2/ws-resolved dev dependencies so npm audit is clean.
Copilot AI review requested due to automatic review settings June 29, 2026 06:02

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens the Jekyll homepage (index.html) against stored XSS / attribute injection by escaping data-driven YAML content and introducing small, reusable sanitization includes for inline markup and link URLs.

Changes:

  • Added _includes/safe-inline.html to escape text and then allow a very small inline allowlist (em, strong, b,  , &).
  • Added _includes/safe-href.html to allowlist safe href schemes/forms and escape them before insertion into attributes.
  • Updated index.html to route many YAML-provided fields through safe-inline.html, safe-href.html, and | escape / | slugify to reduce text- and attribute-context injection risk.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
index.html Escapes and sanitizes data-driven homepage content/attributes; routes link targets through safe-href.html.
_includes/safe-inline.html New helper include that escapes input and restores a narrow inline allowlist.
_includes/safe-href.html New helper include that allowlists URL forms/schemes and escapes them for href attributes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread index.html
</video>
{% elsif img.youtube %}
<iframe
src="https://www.youtube-nocookie.com/embed/{{ img.youtube }}?autoplay=1&amp;mute=1&amp;loop=1&amp;playlist={{ img.youtube }}&amp;controls=0&amp;modestbranding=1&amp;rel=0&amp;playsinline=1&amp;iv_load_policy=3"

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 459f17a322

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread index.html
<span class="hero__caption-eyebrow">Featured work</span>
<b class="hero__caption-title">{{ img.caption_title }}</b>
<span class="hero__caption-sub">{{ img.caption_sub }}</span>{%- comment -%} caption_sub may contain <em> for journal names; it's author-curated content, safe to render as HTML. {%- endcomment -%}
<b class="hero__caption-title">{{ img.caption_title | escape }}</b>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid double-escaping hero caption entities

When a hero caption title already contains an entity, this new escape call double-encodes it; the existing _data/hero.yml entry Viscosity &amp; drop-impact forces will render on the fourth hero slide as the literal text Viscosity &amp; drop-impact forces instead of Viscosity & drop-impact forces. Use the same safe-inline handling for caption titles or normalize the data to raw ampersands before escaping.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants