From 861f36354fa32b77b1f7f9e59532f2ead7bbf331 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Mon, 5 Oct 2026 19:02:43 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[HIGH]=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=86=A0=ED=83=80=EC=9E=85=20=EC=98=A4?= =?UTF-8?q?=EC=97=BC=20=EB=B0=8F=20DOM=20XSS=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AppGuardrail 대시보드(scanner/dashboard/index.html)에서 발생하는 프로토타입 오염(Prototype Pollution) 및 DOM 기반 크로스 사이트 스크립팅(DOM XSS) 취약점을 수정했습니다. - 사용자 입력 기반 카테고리를 담는 `byCat` 객체를 `Object.create(null)`로 초기화하여 프로토타입 오염 방지 - 객체 키 유효성 검증 시 프로토타입 체인을 무시하도록 `in` 연산자 대신 `Object.hasOwn` 사용 - 객체 속성(e.g., `SEV[sevKey].color`)이 DOM 템플릿에 안전하게 바인딩되도록 `esc()` 함수 래핑 적용 --- .jules/sentinel.md | 4 ++++ scanner/dashboard/index.html | 12 +++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/.jules/sentinel.md b/.jules/sentinel.md index 1600d4323..b46c1ffb1 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -127,3 +127,7 @@ **Vulnerability:** The `/api/v1/webhook` POST endpoint in `appguardrail_core/controlplane.py` failed to validate the `url` property when accepting it into the database, leading to Stored SSRF risks. In addition, the core SSRF validation logic (`_is_safe_url`) in both the CLI and control-plane did not verify the input type (e.g. `isinstance(url, str)`). Passing non-string types (like integers) resulted in unhandled `AttributeError` exceptions inside `urllib.parse.urlparse`, which led to API 500 crashes on malicious JSON payloads. **Learning:** Network endpoints must explicitly validate the data type of user-provided configurations prior to execution or storage. Furthermore, webhooks configured by users should always be checked for SSRF when saved, as trusting them later assumes input has already been safely validated, bypassing downstream network guardrails. **Prevention:** Apply `_is_safe_url` checks directly upon ingestion (e.g., in `/api/v1/webhook`) and enforce type checks `if not isinstance(url, str): return False` prior to using library parsing functions like `urlparse`. Always return gracefully failing responses (like `400 Bad Request`) for unsafe URLs instead of allowing unhandled 500 server errors. +## 2023-10-27 - [JavaScript Prototype Pollution and DOM XSS in Dashboard] +**Vulnerability:** The AppGuardrail dashboard was vulnerable to Prototype Pollution and DOM XSS when iterating through findings because it initialized a dictionary for categories with `{}` and accessed properties based on a user-controlled severity key using the `in` operator (which checks the prototype chain). Furthermore, the mapped color values were interpolated directly into the HTML without an escape wrapper. +**Learning:** Even statically mapped values retrieved from a dictionary (like `SEV[sevKey].color`) must be escaped before being interpolated into DOM contexts to appease strict CodeQL rules and add defense-in-depth. User-provided keys used in dictionary mappings should be verified using `Object.hasOwn()` rather than `in`, and dictionaries collecting arbitrary keys must be initialized with `Object.create(null)` to completely avoid prototype pollution. +**Prevention:** Always use `Object.create(null)` for dynamic mapping dictionaries. When performing property lookups based on external inputs, validate the key existence specifically on the object itself using `Object.hasOwn(obj, key)`. Even when retrieving statically trusted values, wrap them in output-encoding functions (like `esc()`) before inserting them into innerHTML. diff --git a/scanner/dashboard/index.html b/scanner/dashboard/index.html index 132bc31b2..96a9b3691 100644 --- a/scanner/dashboard/index.html +++ b/scanner/dashboard/index.html @@ -170,11 +170,11 @@