From 201a7bf79842c03b56d9dcd7fe25576f591e6812 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Fri, 3 Jul 2026 21:01:21 +0000 Subject: [PATCH] =?UTF-8?q?=EB=B3=B4=EC=95=88:=20=EC=8B=AC=EB=B3=BC?= =?UTF-8?q?=EB=A6=AD=20=EB=A7=81=ED=81=AC=20=EA=B2=BD=EB=A1=9C=20=EC=9A=B0?= =?UTF-8?q?=ED=9A=8C=20=EC=B7=A8=EC=95=BD=EC=A0=90=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?(canonicalFile)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `go` 함수 내에서 `File(topDir).canonicalFile`을 `File(topDir).absoluteFile`로 변경 - 기존 `canonicalFile` 사용 시, 심볼릭 링크 경로가 먼저 해석된 후 `LinkOption.NOFOLLOW_LINKS` 검사가 실행되어 심볼릭 링크 제한 우회 가능성이 존재했음. - 로컬 변수명 규칙 준수를 위해 `top_dir`을 `topDirFile`로 리팩토링. - 보안 일지 (`.jules/sentinel.md`)에 `canonicalFile` 사용 관련 핵심 보안 학습 사항 기록 추가. --- .jules/sentinel.md | 5 +++++ src/main/kotlin/html4tree/main.kt | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.jules/sentinel.md b/.jules/sentinel.md index 6c61284..215421a 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -22,3 +22,8 @@ **Vulnerability:** Defense in Depth (CSP Missing) **Learning:** Even when inputs are properly escaped, statically generated HTML that displays file/directory structures should implement a Content Security Policy (CSP) to provide an extra layer of defense against potential XSS bypasses. **Prevention:** Include a strict CSP meta tag (e.g., `default-src 'none'; style-src 'unsafe-inline';`) in auto-generated HTML headers when external scripts or resources are not required. + +## 2024-11-20 - [html4tree] Symlink Path Traversal Bypass via canonicalFile +**Vulnerability:** Symlink paths bypassed directory symlink checks causing path traversal vulnerabilities at the root directory level. +**Learning:** `File.canonicalFile` resolves symbolic links immediately. When used *before* security checks like `Files.isDirectory(..., LinkOption.NOFOLLOW_LINKS)`, the check evaluates the resolved target rather than the symlink itself, defeating the entire purpose of `NOFOLLOW_LINKS`. +**Prevention:** Use `File.absoluteFile` instead of `File.canonicalFile` when handling paths that require subsequent non-following symlink checks (e.g., using `LinkOption.NOFOLLOW_LINKS`), ensuring the symlink itself is checked before any resolution occurs. diff --git a/src/main/kotlin/html4tree/main.kt b/src/main/kotlin/html4tree/main.kt index 2e2809f..d827644 100644 --- a/src/main/kotlin/html4tree/main.kt +++ b/src/main/kotlin/html4tree/main.kt @@ -23,12 +23,12 @@ fun main(args: Array) = Html4tree().main(args) fun go(topDir: String, maxLevel: Int) { require(topDir.isNotBlank()) - val top_dir = File(topDir).canonicalFile - require(Files.isDirectory(top_dir.toPath(), LinkOption.NOFOLLOW_LINKS)) { "Top directory must be an existing non-symlink directory" } + val topDirFile = File(topDir).absoluteFile + require(Files.isDirectory(topDirFile.toPath(), LinkOption.NOFOLLOW_LINKS)) { "Top directory must be an existing non-symlink directory" } val ll = LinkedList() - ll.push(LinkedListEntry(top_dir,0)) + ll.push(LinkedListEntry(topDirFile,0)) var lle: LinkedListEntry? = ll.pull()