diff --git a/.jules/sentinel.md b/.jules/sentinel.md index cdf8801..babce18 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -88,3 +88,7 @@ **Vulnerability:** CSP 해시 불일치로 인한 인라인 스타일 차단 **Learning:** 브라우저는 인라인 스크립트와 스타일의 내부 텍스트(공백과 줄바꿈 포함)를 정확하게 해싱하여 Content-Security-Policy(CSP) 해시와 비교합니다. Kotlin의 멀티라인 문자열(`"""`)을 사용하여 템플릿에 콘텐츠를 주입할 때 암묵적인 여백이나 줄바꿈이 추가되면 최종 HTML 문자열이 변경되어 CSP 해시가 무효화됩니다. **Prevention:** 콘텐츠를 해싱하기 전에 `.trimIndent()`를 적용하여 원본 문자열을 정규화하고, HTML 템플릿에 주입할 때 ``와 같이 공백 없이 주입하여 해시가 완벽하게 일치하도록 해야 합니다. +## 2026-08-09 - 검색 엔진 연동 정보 노출 방지 +**Vulnerability:** 공개적으로 호스팅될 경우 검색 엔진에 의해 민감한 디렉토리 목록(Information Exposure)이 크롤링되어 노출될 수 있음 +**Learning:** 디렉토리 인덱스 페이지 등 정적 HTML 파일에 대한 검색 엔진의 크롤링을 방지하기 위해서는 ``를 반드시 명시해야 함 +**Prevention:** HTML 생성 시 robots 메타 태그를 포함하도록 강제하고, 이를 확인하는 단위 테스트를 작성해야 함 diff --git a/plan.md b/plan.md new file mode 100644 index 0000000..b726d27 --- /dev/null +++ b/plan.md @@ -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 `` 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 `` 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`). diff --git a/src/main/kotlin/html4tree/main.kt b/src/main/kotlin/html4tree/main.kt index 8942c04..ad4f84d 100644 --- a/src/main/kotlin/html4tree/main.kt +++ b/src/main/kotlin/html4tree/main.kt @@ -348,6 +348,8 @@ fun process_dir(curr_dir: File, excludeSet: Set? = null, dirFiles: Array + + diff --git a/src/test/kotlin/html4tree/MainTest.kt b/src/test/kotlin/html4tree/MainTest.kt index 179b6c5..4cc027e 100644 --- a/src/test/kotlin/html4tree/MainTest.kt +++ b/src/test/kotlin/html4tree/MainTest.kt @@ -322,6 +322,7 @@ class MainTest { val htmlContent = indexFile.readText() assertTrue(htmlContent.contains("")) assertTrue(htmlContent.contains("")) + assertTrue(htmlContent.contains("")) assertTrue(htmlContent.contains("