From 53823b860883dad6ec29673a97c17843dd355294 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Fri, 28 Aug 2026 13:58:26 +0000 Subject: [PATCH 1/6] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[securi?= =?UTF-8?q?ty=20improvement]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .jules/sentinel.md | 4 ++++ components/krds-gallery.js | 15 +++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/.jules/sentinel.md b/.jules/sentinel.md index fa902ea..d54cc83 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -47,3 +47,7 @@ **Vulnerability:** 사용자 입력값(`lang`)을 검증 없이 `console.warn`과 같은 로그 함수에 그대로 보간하여 출력할 경우, 로그 인젝션(Log Forging) 공격에 노출될 수 있음. **Learning:** 사용자 입력이 포함된 문자열을 직접 보간하면 악의적인 페이로드가 로그 파일에 주입되어 로그 분석 시스템을 방해하거나 다른 취약점을 연계할 수 있음. **Prevention:** 로그를 남길 때는 검증되지 않은 외부 입력값을 동적으로 문자열에 주입(Interpolation)하는 대신, 사전에 정의된 정적이고 안전한 메시지로 대체해야 함. +## 2026-08-28 - DOM API 예외 처리 누락 방어 +**Vulnerability:** DOM 요소를 탐색할 때 (예: `document.getElementById`, `element.closest`) 결과가 null인지 확인하지 않고 속성을 변경하거나 메서드를 호출하여 발생하는 unhandled script exception. +**Learning:** 정적 웹사이트 프론트엔드 코드에서 DOM 요소를 조회할 때, 해당 요소가 존재하지 않으면 `TypeError`가 발생하여 스크립트 실행이 중단될 수 있습니다. 이를 DoS 취약점으로 취급하지는 않으나(보안 극장 방지), 방어적 프로그래밍 관점에서 우아한 기능 저하(graceful degradation)를 위해 null 체크가 필수적입니다. +**Prevention:** Vanilla JavaScript에서 DOM API로 요소를 조회한 후 속성 변경이나 메서드 호출을 수행하기 전에 항상 반환값이 null이 아닌지 검증하는 방어적 프로그래밍 패턴을 적용해야 합니다. diff --git a/components/krds-gallery.js b/components/krds-gallery.js index 672e72f..5aa6d6d 100644 --- a/components/krds-gallery.js +++ b/components/krds-gallery.js @@ -6,12 +6,23 @@ tabList.forEach((t) => { const sel = t === tab; t.setAttribute("aria-selected", sel); - document.getElementById(t.getAttribute("aria-controls")).hidden = !sel; + const targetId = t.getAttribute("aria-controls"); + if (targetId) { + const target = document.getElementById(targetId); + if (target) { + target.hidden = !sel; + } + } }); }); }); }); // Tag remove document.querySelectorAll(".krds-tag__remove").forEach((btn) => - btn.addEventListener("click", () => btn.closest(".krds-tag").remove()) + btn.addEventListener("click", () => { + const tag = btn.closest(".krds-tag"); + if (tag) { + tag.remove(); + } + }) ); From 84f5f3adb6476e4623172cb623aa02224db82c15 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Fri, 28 Aug 2026 14:02:23 +0000 Subject: [PATCH 2/6] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[securi?= =?UTF-8?q?ty=20improvement]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From 4898665595592323592983776f4e91d2e848f3ce Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Fri, 28 Aug 2026 14:05:11 +0000 Subject: [PATCH 3/6] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[securi?= =?UTF-8?q?ty=20improvement]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From d2e467324a77ecb485cd2295e3bd392460db94a9 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Fri, 28 Aug 2026 14:09:22 +0000 Subject: [PATCH 4/6] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[securi?= =?UTF-8?q?ty=20improvement]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From ab5b1925fcb749b302dfd2d8412e81a0fa2fab4e Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Fri, 28 Aug 2026 14:19:05 +0000 Subject: [PATCH 5/6] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[securi?= =?UTF-8?q?ty=20improvement]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From b91600d1c26ef8416da507e802dbc4889e7e3c29 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Fri, 28 Aug 2026 14:28:47 +0000 Subject: [PATCH 6/6] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[securi?= =?UTF-8?q?ty=20improvement]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit