Frontmatter
| title | >- |
| Security | Protocol-relative third-party stylesheet URLs allow insecure |
| author | tomaioo |
| state | Closed |
| createdAt | Apr 12, 2026, 2:12 PM |
| updatedAt | Jun 2, 2026, 8:42 AM |
| closedAt | Jun 2, 2026, 8:42 AM |
| mergedAt | |
| branches | dev ← fix/security/protocol-relative-third-party-stylesheet |
| url | https://github.com/neomjs/neo/pull/9917 |

Input from Gemini 3.1 Pro:
β¦ # PR Review Summary
Status: Approved
Peer-Review Opening: Thanks for putting this together and catching this! Using explicit HTTPS URLs is a much better security posture and ensures dependencies resolve correctly regardless of the hosting environment.
πΈοΈ Context & Graph Linking
- Target Epic / Issue ID: PR #9917
- Related Graph Nodes: N/A
π¬ Depth Floor
Challenge OR documented search (per guide Β§7.1):
I actively looked for any other instances of protocol-relative URLs (
//...) inapps/realworld/index.htmland other core templates and found no concerns. The changes cleanly target the requested dependencies.Rhetorical-Drift Audit (per guide Β§7.4): N/A
π§ Graph Ingestion Notes
[RETROSPECTIVE]: Replacing protocol-relative URLs with explicithttps://is a small but critical security hygiene step to prevent insecure dependency loading.
π Provenance Audit
N/A
π― Close-Target Audit
N/A
π‘ MCP-Tool-Description Budget Audit
N/A
π Wire-Format Compatibility Audit
N/A
π Cross-Skill Integration Audit
N/A
π§ͺ Test-Execution Audit
- Branch checked out locally
- If a test file changed: Ran the specific test file.
- If code changed: Verified if there are tests, or if new tests are needed.
Findings: No tests needed (template/HTML change only).
π Required Actions
No required actions β eligible for human merge.
π Evaluation Metrics
[ARCH_ALIGNMENT]: 100 - I actively considered Neo's layout, routing, and component architecture and confirmed none apply. This is a pure HTML change.[CONTENT_COMPLETENESS]: 100 - I actively considered JSDoc and Anchor & Echo requirements and confirmed none apply for HTML files.[EXECUTION_QUALITY]: 100 - I actively considered syntax errors, incorrect URLs, and loading issues and confirmed none apply.[PRODUCTIVITY]: 100 - I actively considered the goal of the PR (fixing insecure loading) and confirmed it achieves it perfectly.[IMPACT]: 30 - 70 points deducted because this is a routine security fix on a single app'sindex.html, not a framework-level architectural change.[COMPLEXITY]: 10 - Low: Simple string replacement in an HTML file.[EFFORT_PROFILE]: Quick Win - High ROI (security fix) with very low complexity.Great catch!

PR Review Summary
Status: Approved
πͺ Strategic-Fit Decision
Per Β§9 Strategic-Fit Step-Back:
- Decision: Approve
- Rationale: This is a narrow external security hygiene fix. The diff changes only
apps/realworld/index.htmland replaces protocol-relative third-party stylesheet URLs with explicithttps://URLs. Fresh validation found no residual protocol-relativehref/src/url(...)entries in the touched file.
Peer-Review Opening: Thanks for the focused security cleanup. The patch is small, directly addresses the insecure dependency-loading vector described in the PR, and does not disturb the RealWorld app boot path.
πΈοΈ Context & Graph Linking
- Target Epic / Issue ID: PR #9917
- Related Graph Nodes: RealWorld app HTML shell; external CDN stylesheet loading; browser mixed-content / insecure transport hygiene
π¬ Depth Floor
Challenge OR documented search (per guide Β§7.1):
Documented search: I checked the exact diff and the touched file rather than relying on the PR description. Validation:
git diff --check origin/dev...HEAD-> clean.rg -n "href=\"//|src=\"//|url\(\s*//" apps/realworld/index.html-> no matches.- Confirmed explicit HTTPS URLs for
code.ionicframework.com,fonts.googleapis.com, anddemo.productionready.io/main.cssinapps/realworld/index.html.
Rhetorical-Drift Audit (per guide Β§7.4):
- PR description matches the diff: protocol-relative stylesheet URLs are replaced with explicit HTTPS URLs.
- No stale test or CI claims in the PR body.
- Anchor & Echo / JSDoc requirements are not applicable to a static HTML shell edit.
- Linked anchors: N/A.
Findings: Pass.
π§ Graph Ingestion Notes
[KB_GAP]: None.[TOOLING_GAP]: No automated checks are configured on this external PR; validation was local/static.[RETROSPECTIVE]: Protocol-relative third-party assets are avoidable security debt in app entry shells; explicit HTTPS is the correct low-cost default.
π Provenance Audit
N/A. No external code or architecture pattern was imported; the PR only changes URL schemes in an existing HTML file.
π― Close-Target Audit
N/A. This PR does not name a closing issue or epic.
π Contract Completeness Audit
- Problem statement: protocol-relative third-party stylesheet URLs can resolve insecurely when served over HTTP or behind a misconfigured proxy.
- Implementation: all three third-party stylesheet links in
apps/realworld/index.htmlnow use explicithttps://. - Scope: no unrelated app, framework, or build behavior changed.
Findings: Pass.
πͺ Evidence Audit
- Evidence class: L1 static validation is sufficient for a one-file HTML URL-scheme replacement.
- No runtime behavior claim requiring browser/E2E verification was made.
- Residual sweep against protocol-relative
href/src/url(...)patterns in the touched file is clean.
Findings: Pass.
π Source-of-Authority Audit
N/A. The approval is based on the live diff and local validation, not on prior comment approval.
π‘ MCP-Tool-Description Budget Audit
N/A. No MCP/OpenAPI tool descriptions are touched.
π Wire-Format Compatibility Audit
N/A. No API, JSON, A2A, or MCP wire formats are touched.
π Cross-Skill Integration Audit
N/A. No agent skills or turn-loaded substrate are touched.
π§ͺ Test-Execution & Location Audit
- Branch checked out locally:
fix/security/protocol-relative-third-party-stylesheetat788e8ee22c32a7fb1b2766605d6c680f6d52229f. - Changed file:
apps/realworld/index.html. - Ran format audit:
git diff --check origin/dev...HEAD-> clean. - Ran residual URL sweep: no protocol-relative
href/src/url(...)entries remain in the touched file. - No unit test target is applicable for this static HTML URL-scheme change.
Findings: Pass.
π‘οΈ CI / Security Checks Audit
-
gh pr view 9917 --json statusCheckRollupshows no automated checks configured for this PR. - Security posture improves by forcing HTTPS for third-party stylesheet loads.
Findings: Pass with local/static validation.
π Required Actions
No required actions. This PR is merge-eligible pending the human-only merge gate.
π Evaluation Metrics
[ARCH_ALIGNMENT]: 100 - Pure HTML shell hygiene; no Neo architectural surface is affected.[CONTENT_COMPLETENESS]: 95 - The PR clearly describes the problem and the exact file changed; no JSDoc or ticket closure metadata applies.[EXECUTION_QUALITY]: 100 - The replacement is exact and residual protocol-relative checks are clean.[PRODUCTIVITY]: 100 - Fully resolves the stated insecure dependency-loading concern.[IMPACT]: 30 - Low blast radius but positive security hygiene for the RealWorld app.[COMPLEXITY]: 5 - One-file, three-URL static change.[EFFORT_PROFILE]: Quick Win - High ROI, very low complexity.
Per AGENTS.md Β§0, this approval is merge eligibility only; merge execution remains human-only.

Input from Claude Opus 4.7 (Claude Code):
β Hi @tomaioo β late response on this, sorry for the wait. Quick context that explains why this isn't a straightforward merge:
Substrate History
Neo released GA in November 2019.
apps/realworldwas Neo's 2nd ever app, built specifically for the RealWorld framework comparison project (formerly known as gothinkster/realworld) β a comparison set of 100+ JS framework/library implementations of the same "Conduit" social-blog spec.Conformance Constraint
RealWorld's acceptance criteria for entries were strict: even slight template mismatches would exclude an implementation from the comparison set. This is why Neo's
apps/realworldcouldn't use Neo's own component library β the canonicalindex.htmltemplate is the entry contract.The Protocol-Relative URLs Are the Spec
The exact pattern in
apps/realworld/index.html:L6appears verbatim in the RealWorld frontend template specification:<link href="//code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css" ... /> <link href="//fonts.googleapis.com/css?family=..." ... /> <link rel="stylesheet" href="//demo.productionready.io/main.css" />Changing Neo's implementation diverges from the canonical template and could lose Neo's entry in the comparison set.
Path Forward
The substrate-correct way to land this is upstream first:
- PR the change to realworld-apps/realworld (the canonical template spec)
- If accepted, the 100+ downstream implementations (Neo's included) can all update to match
- We'll gladly merge this PR once the upstream change lands
The upstream path is non-trivial because of the 100+ apps cascade β the upstream maintainers may decide the protocol-relative pattern is intentional (it predates universal HSTS, but it's a documented design choice in the spec rather than an oversight). That dilemma is real.
The technical concern you raised is valid in production HTTP contexts. The constraint here is purely the comparison-conformance contract that defines what
apps/realworldis β diverging from the canonical template breaks the demo's whole purpose.Holding this PR open as
awaiting-upstreamrather than closing β if you do file the upstream PR and it lands, ping us and we'll merge promptly.β @neo-opus-ada (Claude Opus 4.7, Claude Code) on behalf of Neo maintainers

closing the PR for now as a cleanup. feel free to add a comment, in case the upstream situation changes.
Summary
Security: Protocol-relative third-party stylesheet URLs allow insecure dependency loading
Problem
Severity:
Medium| File:apps/realworld/index.html:L6The page loads external CSS via protocol-relative URLs (
//...). If the page is ever served over HTTP (or behind a misconfigured proxy), these dependencies can be fetched insecurely and altered by a man-in-the-middle, enabling content/script injection through CSS or compromised assets.Solution
Use explicit
https://URLs for all third-party resources, enforce HSTS on the hosting domain, and avoid protocol-relative URLs.Changes
apps/realworld/index.html(modified)