Skip to content

🛡️ Sentinel: [MEDIUM] Fix CSP Hash Mismatch due to Kotlin Multiline Strings - #283

Closed
seonghobae wants to merge 1 commit into
masterfrom
sentinel-csp-hash-fix-10525982417683885382
Closed

🛡️ Sentinel: [MEDIUM] Fix CSP Hash Mismatch due to Kotlin Multiline Strings#283
seonghobae wants to merge 1 commit into
masterfrom
sentinel-csp-hash-fix-10525982417683885382

Conversation

@seonghobae

@seonghobaeseonghobae commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

🚨 Severity: MEDIUM
💡 Vulnerability: Kotlin 다중 줄 문자열의 공백 및 들여쓰기 때문에 계산된 CSP 해시와 실제 주입된 <style> 내용의 해시가 일치하지 않아 보안 정책이 올바르게 적용되지 않는 문제가 있었습니다.
🎯 Impact: 브라우저에서 인라인 스타일이 CSP에 의해 차단되거나, 부정확한 해시로 인해 보안 정책 검증이 실패할 수 있습니다.
🔧 Fix: cssContent, styleHash, css 선언을 최상위 private val 상수로 이동하고 .trimIndent()를 사용하여 공백을 제거, <style> 태그에 여백 없이 내용을 삽입하도록 수정했습니다.
✅ Verification: export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 && ./gradlew clean test jacocoTestReport jacocoTestCoverageVerification --continue 명령을 통해 100% 테스트 커버리지를 검증했습니다.


PR created automatically by Jules for task 10525982417683885382 started by @seonghobae

Summary by CodeRabbit

  • 버그 수정

    • 인라인 스타일의 보안 정책 해시가 실제 브라우저 콘텐츠와 정확히 일치하도록 개선했습니다.
    • 페이지 생성 시 불필요한 공백이나 줄바꿈으로 인해 스타일이 적용되지 않던 문제를 방지했습니다.
  • 보안

    • 콘텐츠 보안 정책(CSP) 적용 일관성을 강화해 스타일 차단 및 관련 보안 위험을 줄였습니다.
    • 생성되는 페이지 전반에서 동일한 스타일 보안 검증이 적용됩니다.

CopilotAI review requested due to automatic review settings July 27, 2026 03:30
@google-labs-jules

Copy link
Copy Markdown

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@coderabbitai

coderabbitaiBot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

CSS 콘텐츠와 CSP 스타일 해시 생성을 전역 값으로 중앙화하고, 디렉터리별 HTML 생성에서 이를 재사용하도록 변경했습니다. Kotlin 다중 줄 문자열의 CSP 해시 불일치 예방 지침도 보안 문서에 추가했습니다.

Changes

CSP 스타일 해시 중앙화

Layer / File(s)Summary
스타일 콘텐츠와 CSP 해시 중앙화
src/main/kotlin/html4tree/main.kt, .jules/sentinel.md
CSS 원문, SHA-256 기반 styleHash, <style> 래퍼를 파일 상단에서 생성하고 process_dir의 CSP 및 HTML 스타일 삽입에서 재사용합니다. 보안 문서에는 trimIndent()와 정확한 스타일 콘텐츠 주입 지침이 추가되었습니다.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers:copilot

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ Passed제목이 Kotlin multiline 문자열로 인한 CSP 해시 불일치 수정이라는 핵심 변경을 정확히 요약합니다.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sentinel-csp-hash-fix-10525982417683885382

Comment @coderabbitai help to get the list of available commands.

CopilotAI 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 addresses a CSP (Content-Security-Policy) style hash mismatch caused by whitespace/indentation artifacts from Kotlin multiline strings, ensuring the computed sha256-... hash matches the exact <style> contents injected into generated index.html files.

Changes:

  • Moves the inline CSS, its SHA-256 hash computation, and the rendered <style> block to top-level private vals so the content is stable and reused.
  • Applies .trimIndent() to normalize multiline CSS formatting and removes extra whitespace inside the <style> element that previously broke hash validation.
  • Adds a new Sentinel learning entry documenting the issue and prevention guidance.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

FileDescription
src/main/kotlin/html4tree/main.ktNormalizes CSS multiline string formatting and centralizes CSS + CSP hash generation to prevent CSP hash mismatches.
.jules/sentinel.mdDocuments the CSP hash mismatch root cause and prevention guidance for future hardening.

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

@coderabbitaicoderabbitaiBot 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/main/kotlin/html4tree/main.kt (1)

97-101: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

실제 <style> 본문과 해시의 일치를 회귀 테스트로 검증하세요.

현재 MainTest.kt:305-346은 CSP 해시의 형식과 CSS 조각만 확인합니다. cssContent와 실제 삽입된 <style> 본문이 달라도 테스트가 통과할 수 있으므로, 생성된 스타일 본문을 추출해 SHA-256/Base64를 계산한 뒤 CSP의 해시와 비교하는 검증을 추가하세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/main/kotlin/html4tree/main.kt` around lines 97 - 101, Update the
regression tests around the CSP hash checks in MainTest.kt to extract the
generated `<style>` element’s actual body, compute its SHA-256 digest and Base64
value, and assert it matches the CSP hash. Keep the existing hash-format and
CSS-fragment assertions, and anchor the new validation to the generated style
output rather than only cssContent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.jules/sentinel.md:
- Around line 87-90: Update the CSP guidance in the html4tree entry to state
that hash mismatches typically cause browsers to block styles, not enable a
policy bypass. Revise the existing nonce-based guidance around the referenced
security instructions to match the current hash-based implementation, or
explicitly mark it as historical.
---
Nitpick comments:
In `@src/main/kotlin/html4tree/main.kt`:
- Around line 97-101: Update the regression tests around the CSP hash checks in
MainTest.kt to extract the generated `<style>` element’s actual body, compute
its SHA-256 digest and Base64 value, and assert it matches the CSP hash. Keep
the existing hash-format and CSS-fragment assertions, and anchor the new
validation to the generated style output rather than only cssContent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4f41bc2e-f37c-4395-9389-c92d002d222c

📥 Commits

Reviewing files that changed from the base of the PR and between a859a11 and 00d89f9.

📒 Files selected for processing (2)
  • .jules/sentinel.md
  • src/main/kotlin/html4tree/main.kt

Comment thread.jules/sentinel.md
Comment on lines +87 to +90
## 2026-07-27 - [html4tree] CSP Hash Mismatch due to Kotlin Multiline Strings
**Vulnerability:** 브라우저가 CSP(Content-Security-Policy) 해시를 계산할 때, 인라인 스크립트와 스타일의 정확한 텍스트에 기반합니다. Kotlin의 다중 줄 문자열 내의 불필요한 공백과 줄바꿈으로 인해 생성된 해시와 브라우저가 계산한 해시가 불일치하여, 결과적으로 스타일 적용이 실패하거나 보안 정책 우회 가능성이 생깁니다.
**Learning:** 정적 생성 도구에서 CSP를 위해 콘텐츠 해시를 계산할 때는, 인젝트된 콘텐츠 주변의 암묵적 여백이나 들여쓰기가 결과 해시를 무효화할 수 있음을 인지해야 합니다.
**Prevention:** 콘텐츠 문자열에 `.trimIndent()`를 적용하여 해싱 전에 포맷을 정리하고, 암묵적 여백 없이(예: `<style>${exactStyleContent}</style>`) HTML에 인젝트하여 완전한 해시 일치를 보장하십시오.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

CSP 불일치의 영향과 기존 nonce 지침을 정정하세요.

해시 불일치는 일반적으로 브라우저가 스타일을 차단하는 문제이지, 보안 정책 우회를 가능하게 하는 문제는 아닙니다. 또한 24행의 nonce 기반 지침이 현재의 hash 기반 구현과 충돌하므로, 기존 항목을 hash 방식으로 갱신하거나 역사적 지침임을 명확히 표시하세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.jules/sentinel.md around lines 87 - 90, Update the CSP guidance in the
html4tree entry to state that hash mismatches typically cause browsers to block
styles, not enable a policy bypass. Revise the existing nonce-based guidance
around the referenced security instructions to match the current hash-based
implementation, or explicitly mark it as historical.

@seonghobaeChatGPT Codex Connector

Copy link
Copy Markdown
CollaboratorAuthor

Closing as superseded by canonical #363. Both normalize the multiline stylesheet and inject it without template padding, but #363 additionally proves byte identity through an independent real generated-file digest oracle, adds one-time hashing, APA 7 doctoring, changelog, and fresh current-head CI/JaCoCo/security evidence. No result from this duplicate head is reused.

@google-labs-jules

Copy link
Copy Markdown

Closing as superseded by canonical #363. Both normalize the multiline stylesheet and inject it without template padding, but #363 additionally proves byte identity through an independent real generated-file digest oracle, adds one-time hashing, APA 7 doctoring, changelog, and fresh current-head CI/JaCoCo/security evidence. No result from this duplicate head is reused.

Understood. Acknowledging that this work is now obsolete and stopping work on this task.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@seonghobae