Skip to content
Closed
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
5 changes: 5 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,8 @@
**Vulnerability:** 정적 HTML 생성 도구에서 매번 다른 Nonce를 동적으로 생성하여 CSP에 적용하는 것은, 캐싱 효율을 저하시킬 뿐만 아니라 정적 배포 환경(예: GitHub Pages 등)에서 올바른 보안 정책 수립을 방해할 수 있는 안티 패턴입니다.
**Learning:** 정적으로 고정된 인라인 스타일이나 스크립트에는 난수화된 Nonce보다 콘텐츠 자체의 해시(SHA-256 등)를 사용하는 것이 안전하고 일관된 방식임을 배웠습니다.
**Prevention:** 자동 생성되는 정적 HTML의 콘텐츠 보안 정책(CSP)에는 `style-src 'sha256-<HASH>'` 방식을 적용하고, `<style>` 태그에서 불필요한 `nonce` 속성을 제거하여 브라우저의 무결성 검증 기능을 적극 활용하십시오.

## 2024-07-27 - [MEDIUM] 잘못된 Glob 패턴으로 인한 크래시(DoS) 방지
**Vulnerability:** `.html4ignore` 파일 파싱 시 잘못된 glob 패턴이 입력되면 `java.util.regex.PatternSyntaxException`뿐만 아니라 `IllegalArgumentException`이 발생할 수 있어 애플리케이션 크래시(DoS)가 발생할 수 있습니다.
**Learning:** `FileSystems.getDefault().getPathMatcher()`는 플랫폼 및 패턴에 따라 다양한 하위 예외를 던질 수 있으므로, 구체적인 예외 하나만 잡으면 처리되지 않은 예외로 인해 런타임 크래시가 발생할 위험이 있습니다.
**Prevention:** 사용자 입력을 처리하는 파일 매처 등에서 발생할 수 있는 여러 예외 상황을 방어하기 위해 상위 예외인 `IllegalArgumentException`을 포괄적으로 잡아(Catch) 애플리케이션이 안전하게 동작(Fail Securely)하도록 해야 합니다.
Comment on lines +88 to +90
2 changes: 1 addition & 1 deletion src/main/kotlin/html4tree/main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ fun process_ignore_file(curr_dir: File, dirFilesNames: Array<String>? = null): S
if (pattern.isNotEmpty() && pattern.length <= 100) {
try {
ignored_matchers.add(java.nio.file.FileSystems.getDefault().getPathMatcher("glob:$pattern"))
} catch (_: java.util.regex.PatternSyntaxException) {
} catch (_: IllegalArgumentException) {
}
Comment on lines 193 to 196
}
}
Expand Down
22 changes: 22 additions & 0 deletions src/test/kotlin/html4tree/GlobExceptionTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package html4tree

import org.junit.Test
import java.io.File
import java.nio.file.Files
import kotlin.test.assertTrue

class GlobExceptionTest {
@Test
fun testProcessIgnoreFileWithMalformedGlobPattern() {
val tempDir = Files.createTempDirectory("globexc").toFile()
try {
val ignoreFile = File(tempDir, ".html4ignore")
// A pattern like "[" will throw PatternSyntaxException (a subclass of IllegalArgumentException)
ignoreFile.writeText("[\n")
val excluded = process_ignore_file(tempDir, null)
assertTrue(excluded.contains("index.html"))
Comment on lines +8 to +17
} finally {
tempDir.deleteRecursively()
}
}
}
26 changes: 26 additions & 0 deletions src/test/kotlin/html4tree/GlobIllegalArgumentExceptionTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package html4tree

import org.junit.Test
import java.io.File
import java.nio.file.Files
import kotlin.test.assertTrue

class GlobIllegalArgumentExceptionTest {
@Test
fun testProcessIgnoreFileWithIllegalArgumentExceptionGlobPattern() {
val tempDir = Files.createTempDirectory("globexc2").toFile()
try {
val ignoreFile = File(tempDir, ".html4ignore")
// A pattern like "a[b" will throw PatternSyntaxException
// and we rely on IllegalArgumentException to catch it.
// But how do we test catching exactly IllegalArgumentException that is NOT PatternSyntaxException?
// Actually, PatternSyntaxException IS an IllegalArgumentException, so the catch block is fully covered
// when ANY IllegalArgumentException (or subclass) is thrown.
Comment on lines +14 to +18
ignoreFile.writeText("a[b\n")
val excluded = process_ignore_file(tempDir, null)
assertTrue(excluded.contains("index.html"))
} finally {
tempDir.deleteRecursively()
}
}
}
Loading