Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,7 @@
**Vulnerability:** CSP ํ•ด์‹œ ๋ถˆ์ผ์น˜๋กœ ์ธํ•œ ์ธ๋ผ์ธ ์Šคํƒ€์ผ ์ฐจ๋‹จ
**Learning:** ๋ธŒ๋ผ์šฐ์ €๋Š” ์ธ๋ผ์ธ ์Šคํฌ๋ฆฝํŠธ์™€ ์Šคํƒ€์ผ์˜ ๋‚ด๋ถ€ ํ…์ŠคํŠธ(๊ณต๋ฐฑ๊ณผ ์ค„๋ฐ”๊ฟˆ ํฌํ•จ)๋ฅผ ์ •ํ™•ํ•˜๊ฒŒ ํ•ด์‹ฑํ•˜์—ฌ Content-Security-Policy(CSP) ํ•ด์‹œ์™€ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค. Kotlin์˜ ๋ฉ€ํ‹ฐ๋ผ์ธ ๋ฌธ์ž์—ด(`"""`)์„ ์‚ฌ์šฉํ•˜์—ฌ ํ…œํ”Œ๋ฆฟ์— ์ฝ˜ํ…์ธ ๋ฅผ ์ฃผ์ž…ํ•  ๋•Œ ์•”๋ฌต์ ์ธ ์—ฌ๋ฐฑ์ด๋‚˜ ์ค„๋ฐ”๊ฟˆ์ด ์ถ”๊ฐ€๋˜๋ฉด ์ตœ์ข… HTML ๋ฌธ์ž์—ด์ด ๋ณ€๊ฒฝ๋˜์–ด CSP ํ•ด์‹œ๊ฐ€ ๋ฌดํšจํ™”๋ฉ๋‹ˆ๋‹ค.
**Prevention:** ์ฝ˜ํ…์ธ ๋ฅผ ํ•ด์‹ฑํ•˜๊ธฐ ์ „์— `.trimIndent()`๋ฅผ ์ ์šฉํ•˜์—ฌ ์›๋ณธ ๋ฌธ์ž์—ด์„ ์ •๊ทœํ™”ํ•˜๊ณ , HTML ํ…œํ”Œ๋ฆฟ์— ์ฃผ์ž…ํ•  ๋•Œ `<style>${exactContent}</style>`์™€ ๊ฐ™์ด ๊ณต๋ฐฑ ์—†์ด ์ฃผ์ž…ํ•˜์—ฌ ํ•ด์‹œ๊ฐ€ ์™„๋ฒฝํ•˜๊ฒŒ ์ผ์น˜ํ•˜๋„๋ก ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
## 2026-08-09 - ๊ฒ€์ƒ‰ ์—”์ง„ ์—ฐ๋™ ์ •๋ณด ๋…ธ์ถœ ๋ฐฉ์ง€
**Vulnerability:** ๊ณต๊ฐœ์ ์œผ๋กœ ํ˜ธ์ŠคํŒ…๋  ๊ฒฝ์šฐ ๊ฒ€์ƒ‰ ์—”์ง„์— ์˜ํ•ด ๋ฏผ๊ฐํ•œ ๋””๋ ‰ํ† ๋ฆฌ ๋ชฉ๋ก(Information Exposure)์ด ํฌ๋กค๋ง๋˜์–ด ๋…ธ์ถœ๋  ์ˆ˜ ์žˆ์Œ
**Learning:** ๋””๋ ‰ํ† ๋ฆฌ ์ธ๋ฑ์Šค ํŽ˜์ด์ง€ ๋“ฑ ์ •์  HTML ํŒŒ์ผ์— ๋Œ€ํ•œ ๊ฒ€์ƒ‰ ์—”์ง„์˜ ํฌ๋กค๋ง์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” `<meta name="robots" content="noindex, nofollow">`๋ฅผ ๋ฐ˜๋“œ์‹œ ๋ช…์‹œํ•ด์•ผ ํ•จ
**Prevention:** HTML ์ƒ์„ฑ ์‹œ robots ๋ฉ”ํƒ€ ํƒœ๊ทธ๋ฅผ ํฌํ•จํ•˜๋„๋ก ๊ฐ•์ œํ•˜๊ณ , ์ด๋ฅผ ํ™•์ธํ•˜๋Š” ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•จ
8 changes: 8 additions & 0 deletions plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
1. **Explore the codebase and understand the issue:** Looked at `src/main/kotlin/html4tree/main.kt` and `src/test/kotlin/html4tree/MainTest.kt`.
2. **Identify security enhancement:** As Sentinel, we need to add ONE security enhancement. One of the memories states: "The generated HTML directory listings include a `<meta name="robots" content="noindex, nofollow">` tag to prevent unintended Information Exposure via search engine indexing if hosted publicly." Also, the "Sample Commands You Can Use" and "Sentinel's philosophy" recommend adding security headers/metadata. Adding a `noindex, nofollow` robots meta tag is a simple <50 line security enhancement that prevents sensitive directory listings from being indexed by search engines.
3. **Plan the changes:**
- Modify `src/main/kotlin/html4tree/main.kt` in the `process_dir` function.
- Insert `<meta name="robots" content="noindex, nofollow">` into the `index_top` string.
- Modify `src/test/kotlin/html4tree/MainTest.kt` to assert the presence of this new meta tag in the generated HTML.
4. **Log Sentinel learning:** Create or update `.jules/sentinel.md` with the new learning in Korean as required.
5. **Verify changes:** Run tests (`./gradlew clean test jacocoTestReport jacocoTestCoverageVerification`).
2 changes: 2 additions & 0 deletions src/main/kotlin/html4tree/main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,8 @@ fun process_dir(curr_dir: File, excludeSet: Set<String>? = null, dirFiles: Array
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="color-scheme" content="light dark">
<!-- ๋ณด์•ˆ ํ–ฅ์ƒ: ๊ฒ€์ƒ‰ ์—”์ง„ ์—ฐ๋™ ์ •๋ณด ๋…ธ์ถœ ๋ฐฉ์ง€ -->
<meta name="robots" content="noindex, nofollow">
<!-- ๋ณด์•ˆ ํ–ฅ์ƒ: ์ธ๋ผ์ธ ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ ๋ฐฉ์ง€ -->
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src '${STYLE_HASH}'; base-uri 'none'; form-action 'none';">
<!-- ๋ณด์•ˆ ํ–ฅ์ƒ: ๋ฆฌํผ๋Ÿฌ๋ฅผ ํ†ตํ•œ ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ๋…ธ์ถœ ๋ฐฉ์ง€ -->
Expand Down
1 change: 1 addition & 0 deletions src/test/kotlin/html4tree/MainTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ class MainTest {
val htmlContent = indexFile.readText()
assertTrue(htmlContent.contains("<html lang=\"ko\">"))
assertTrue(htmlContent.contains("<meta name=\"color-scheme\" content=\"light dark\">"))
assertTrue(htmlContent.contains("<meta name=\"robots\" content=\"noindex, nofollow\">"))
assertTrue(htmlContent.contains("<nav aria-label=\"๋””๋ ‰ํ† ๋ฆฌ ๋ชฉ๋ก\">"))
assertTrue(htmlContent.contains("role=\"list\""))
assertTrue(htmlContent.contains("<main>"))
Expand Down
Loading