Sanitize data-driven homepage output to prevent stored XSS - #95
Sanitize data-driven homepage output to prevent stored XSS#95VatsalSy wants to merge 793 commits into
Conversation
- 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 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.
2025 wrap-up updates
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.
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
Bump addressable to 2.9.0 (CVE-2026-35611)
Replace the broken /VatsalSy and /comphy-bot footer routes with live external destinations so the v2 footer no longer emits 404s.
Fix footer maintainer links
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.
Align rebuild workflow Ruby toolchain
There was a problem hiding this comment.
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.htmlto escape text and then allow a very small inline allowlist (em,strong,b, ,&). - Added
_includes/safe-href.htmlto allowlist safehrefschemes/forms and escape them before insertion into attributes. - Updated
index.htmlto route many YAML-provided fields throughsafe-inline.html,safe-href.html, and| escape/| slugifyto 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.
| </video> | ||
| {% elsif img.youtube %} | ||
| <iframe | ||
| src="https://www.youtube-nocookie.com/embed/{{ img.youtube }}?autoplay=1&mute=1&loop=1&playlist={{ img.youtube }}&controls=0&modestbranding=1&rel=0&playsinline=1&iv_load_policy=3" |
There was a problem hiding this comment.
💡 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".
| <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> |
There was a problem hiding this comment.
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 & drop-impact forces will render on the fourth hero slide as the literal text Viscosity & 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 👍 / 👎.
Motivation
Description
_includes/safe-inline.htmlwhich first escapes input and then selectively restores a limited set of approved inline tags/entities._includes/safe-href.htmlwhich validates/escapes href values and only permits site-relative anchors/paths,http(s), ormailto:, falling back to#for unsafe values.index.htmlto route hero tagline/lede, theme descriptions, news meta, image attributes, action labels, team bios and other data-driven fields throughsafe-inline.html,safe-href.html, and| escape/| slugifyas appropriate to prevent text- and attribute-context injection.alt,poster,src, and other attributes are escaped and that link targets are constrained to safe schemes.Testing
npm test -- --runInBand, all test suites passed (12 suites, 77 tests)../scripts/lint-check.sh, lint checks completed successfully with no blocking issues.bundle exec jekyll buildbut 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