From 34dd8511a926d75de5163cf4e2e5dce6051a86b6 Mon Sep 17 00:00:00 2001 From: JK Date: Sat, 4 Apr 2026 01:43:52 +0900 Subject: [PATCH 1/2] =?UTF-8?q?chore(frontend):=20=EB=B3=B4=EC=95=88=20?= =?UTF-8?q?=EC=B7=A8=EC=95=BD=EC=A0=90=20=EC=88=98=EC=A0=95=20=E2=80=94=20?= =?UTF-8?q?Dependabot=205=EA=B1=B4=20+=20XSS=201=EA=B1=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - lodash@4, lodash-es@4 → 4.18.x override 추가 (Code Injection, Prototype Pollution) - nanoid@4 → 5.x override 추가 (Predictable results) - standalone/index.ts: innerHTML → DOM API로 변경하여 XSS 방지 - innerHTML allowlist에서 standalone/index.ts 제거 Co-Authored-By: Atlas --- .../app/scripts/lint/allowlist/innerhtml.txt | 1 - frontend/app/src/shared/standalone/index.ts | 6 +++- frontend/package.json | 3 ++ frontend/pnpm-lock.yaml | 31 ++++++++++--------- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/frontend/app/scripts/lint/allowlist/innerhtml.txt b/frontend/app/scripts/lint/allowlist/innerhtml.txt index 08efd7fce..bfcc489a8 100644 --- a/frontend/app/scripts/lint/allowlist/innerhtml.txt +++ b/frontend/app/scripts/lint/allowlist/innerhtml.txt @@ -1,3 +1,2 @@ # path|expires(YYYY-MM-DD)|reason -src/shared/standalone/index.ts|2026-06-30|Standalone button loading markup helper src/shared/scroll-hint/index.ts|2026-06-30|Programmatic chevron SVG button injection diff --git a/frontend/app/src/shared/standalone/index.ts b/frontend/app/src/shared/standalone/index.ts index 7a7768cc5..46f247238 100644 --- a/frontend/app/src/shared/standalone/index.ts +++ b/frontend/app/src/shared/standalone/index.ts @@ -73,7 +73,11 @@ export function setButtonLoading( if (loading) { btn.dataset.originalText = btn.textContent || ''; btn.disabled = true; - btn.innerHTML = ` ${loadingText || btn.dataset.originalText}...`; + btn.textContent = ''; + const spinner = document.createElement('span'); + spinner.className = + 'inline-block animate-spin rounded-full h-4 w-4 border-2 border-current border-t-transparent'; + btn.append(spinner, ` ${loadingText || btn.dataset.originalText}...`); } else { btn.disabled = false; btn.textContent = btn.dataset.originalText || ''; diff --git a/frontend/package.json b/frontend/package.json index 6062631d5..35e416df8 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -38,7 +38,10 @@ "picomatch@2": "2.3.2", "picomatch@4": "4.0.4", "path-to-regexp@8": "8.4.1", + "lodash@4": "^4.18.0", + "lodash-es@4": "^4.18.0", "nanoid@3": "3.3.11", + "nanoid@4": "^5.1.0", "mermaid@10": "10.9.5", "dompurify@3": "3.3.3" } diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 6d0cbcb69..52dada0ea 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -11,7 +11,10 @@ overrides: picomatch@2: 2.3.2 picomatch@4: 4.0.4 path-to-regexp@8: 8.4.1 + lodash@4: ^4.18.0 + lodash-es@4: ^4.18.0 nanoid@3: 3.3.11 + nanoid@4: ^5.1.0 mermaid@10: 10.9.5 dompurify@3: 3.3.3 @@ -3439,8 +3442,8 @@ packages: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} - lodash-es@4.17.23: - resolution: {integrity: sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==} + lodash-es@4.18.1: + resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==} lodash.debounce@4.0.8: resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} @@ -3448,8 +3451,8 @@ packages: lodash.throttle@4.1.1: resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==} - lodash@4.17.23: - resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} longest-streak@3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} @@ -3747,9 +3750,9 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - nanoid@4.0.2: - resolution: {integrity: sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==} - engines: {node: ^14 || ^16 || >=18} + nanoid@5.1.7: + resolution: {integrity: sha512-ua3NDgISf6jdwezAheMOk4mbE1LXjm1DfMUDMuJf4AqxLFK3ccGpgWizwa5YV7Yz9EpXwEaWoRXSb/BnV0t5dQ==} + engines: {node: ^18 || >=20} hasBin: true negotiator@1.0.0: @@ -5149,7 +5152,7 @@ snapshots: dependencies: '@excalidraw/markdown-to-text': 0.1.2 mermaid: 10.9.5 - nanoid: 4.0.2 + nanoid: 5.1.7 transitivePeerDependencies: - supports-color @@ -7221,7 +7224,7 @@ snapshots: dagre-d3-es@7.0.13: dependencies: d3: 7.9.0 - lodash-es: 4.17.23 + lodash-es: 4.18.1 data-urls@6.0.1: dependencies: @@ -7822,13 +7825,13 @@ snapshots: dependencies: p-locate: 4.1.0 - lodash-es@4.17.23: {} + lodash-es@4.18.1: {} lodash.debounce@4.0.8: {} lodash.throttle@4.1.1: {} - lodash@4.17.23: {} + lodash@4.18.1: {} longest-streak@3.1.0: {} @@ -8063,7 +8066,7 @@ snapshots: elkjs: 0.9.3 katex: 0.16.38 khroma: 2.1.0 - lodash-es: 4.17.23 + lodash-es: 4.18.1 mdast-util-from-markdown: 1.3.1 non-layered-tidy-tree-layout: 2.0.2 stylis: 4.3.6 @@ -8448,7 +8451,7 @@ snapshots: nanoid@3.3.11: {} - nanoid@4.0.2: {} + nanoid@5.1.7: {} negotiator@1.0.0: {} @@ -8822,7 +8825,7 @@ snapshots: dependencies: clsx: 2.1.1 eventemitter3: 4.0.7 - lodash: 4.17.23 + lodash: 4.18.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) react-is: 18.3.1 From 2081678984a2823b24eb6fbd6cc78242e53aa9e6 Mon Sep 17 00:00:00 2001 From: JK Date: Sat, 4 Apr 2026 22:26:16 +0900 Subject: [PATCH 2/2] =?UTF-8?q?ci:=20CI=20=EC=9E=AC=EC=8B=A4=ED=96=89?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EB=B9=88=20=EC=BB=A4=EB=B0=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6