-
Notifications
You must be signed in to change notification settings - Fork 0
π¨ Palette: λ€μ΄μΌλ‘κ·Έ λ«κΈ° λ²νΌμ λ¨μΆν€ ν΄ν μΆκ° #876
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5816da1
68c4868
f5dd3a5
d76e0a9
0cb3eaf
30745fd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -114,8 +114,11 @@ | |
| const ctx = String(f.context||'app-code'); | ||
| return BLOCKING_SEV.has(sev) && !NON_BLOCKING.has(ctx); | ||
| } | ||
| function esc(s){return String(s==null?'':s).replace(/[&<>"]/g,c=>({'&':'&','<':'<','>':'>','"':'"'}[c]));} | ||
| function esc(s){return String(s==null?'':s).replace(/[&<>"'`]/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":''','`':'`'}[c]));} | ||
| function safeUrl(u){ | ||
| if (typeof u === 'string' && u.startsWith('//')) { | ||
| return '#'; | ||
| } | ||
| try { | ||
| const parsed = new URL(u, window.location.href); | ||
| if (parsed.protocol === 'http:' || parsed.protocol === 'https:') return u; | ||
|
|
@@ -248,7 +251,7 @@ <h1>Dashboard</h1> | |
| function openDetail(f){ | ||
| lastFocus = document.activeElement; | ||
| const s = String(f.severity||'INFO').toUpperCase(); | ||
| const refs = (f.references||[]).map(r=>`<a href="${esc(safeUrl(r))}" target="_blank" rel="noopener" aria-label="${esc(r)} (opens in a new tab)">${esc(r)} β</a>`).join('<br>'); | ||
| const refs = (f.references||[]).map(r=>`<a href="${esc(safeUrl(r))}" target="_blank" rel="noopener">${esc(r)}</a>`).join('<br>'); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π― Functional Correctness | π‘ Minor | β‘ Quick win μ ν μ΄λ¦Ό μλ΄λ₯Ό μ μ§νμΈμ.
π€ Prompt for AI Agents |
||
| const owasp = (f.owasp||[]).join(', '); | ||
| const cwe = (f.cwe||[]).join(', '); | ||
| const d = document.getElementById('detail'); | ||
|
|
@@ -257,7 +260,7 @@ <h1>Dashboard</h1> | |
| <div class="dlg-head"> | ||
| <span class="chip" style="background:${SEV[s]?SEV[s].color:'var(--info)'}">${esc(s)}</span> | ||
| <span class="t" id="dlg-title">${esc(f.rule_id)}</span> | ||
| <button aria-label="Close" onclick="document.getElementById('detail').close()">β</button> | ||
| <button aria-label="Close" title="Close (Esc)" onclick="document.getElementById('detail').close()">β</button> | ||
| </div> | ||
| <div class="dlg-body"> | ||
| <p class="file">${esc(f.file)}:${esc(f.line)} Β· ${esc(f.category)} Β· context: ${esc(f.context||'app-code')}${isDeployBlocking(f)?' Β· <span class="tag block">deploy-blocking</span>':''}</p> | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,10 +2,12 @@ | |
|
|
||
| import json | ||
| import json as _json | ||
| import re | ||
| import threading | ||
| import urllib.error | ||
| import urllib.request | ||
| from contextlib import closing | ||
| from html.parser import HTMLParser | ||
|
|
||
| import pytest | ||
|
|
||
|
|
@@ -14,6 +16,20 @@ | |
| make_dashboard_server, render_tokens_css) | ||
|
|
||
|
|
||
| class _ButtonAttributeParser(HTMLParser): | ||
| """Collect attributes from every dashboard button element.""" | ||
|
|
||
| def __init__(self): | ||
| """Initialize an empty button-attribute collection.""" | ||
| super().__init__() | ||
| self.buttons = [] | ||
|
|
||
| def handle_starttag(self, tag, attrs): | ||
| """Record one button's attributes while ignoring other elements.""" | ||
| if tag == "button": | ||
| self.buttons.append(dict(attrs)) | ||
|
|
||
|
|
||
| def _serve(server): | ||
| thread = threading.Thread(target=server.serve_forever, daemon=True) | ||
| thread.start() | ||
|
|
@@ -223,6 +239,7 @@ def test_server_404s_missing_findings(tmp_path): | |
| server.shutdown() | ||
| server.server_close() | ||
|
|
||
|
|
||
| def test_dashboard_empty_state_clear_filters(): | ||
| """Empty state CTA must expose Clear filters control that resets state.""" | ||
| html = dashboard_index_path().read_text(encoding="utf-8") | ||
|
|
@@ -231,3 +248,23 @@ def test_dashboard_empty_state_clear_filters(): | |
| assert "aria-label=\"Clear filters\"" in html | ||
| assert "onclick=\"query=''; filterSev=''; render(); document.getElementById('q')?.focus();\"" in html | ||
| assert "Clear filters</button>" in html | ||
|
|
||
|
|
||
| def test_dashboard_dialog_close_button_has_tooltip(): | ||
| """The dynamically rendered close button exposes its label and Esc tooltip.""" | ||
| html = dashboard_index_path().read_text(encoding="utf-8") | ||
| detail_markup = re.search( | ||
| r"d\.innerHTML\s*=\s*`(?P<markup>.*?)`;", | ||
| html, | ||
| flags=re.DOTALL, | ||
| ) | ||
| assert detail_markup is not None | ||
|
|
||
| parser = _ButtonAttributeParser() | ||
| parser.feed(detail_markup.group("markup")) | ||
|
|
||
| assert any( | ||
| attributes.get("title") == "Close (Esc)" | ||
| and attributes.get("aria-label") == "Close" | ||
| for attributes in parser.buttons | ||
| ) | ||
|
Comment on lines
+258
to
+262
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π― Functional Correctness | π‘ Minor | β‘ Quick win κ²μ¬ λμμ μμΈ λ€μ΄μΌλ‘κ·Έ λ«κΈ° λ²νΌμΌλ‘ μ ννμΈμ.
π§° Toolsπͺ GitHub Actions: Tests / 0_Unit tests (Python 3.11).txt[error] 258-264: pytest test_dashboard_dialog_close_button_has_tooltip failed: the dashboard dialog close button does not have title="Close (Esc)" and aria-label="Close" attributes. Command 'python -m pytest -q' failed with exit code 1. πͺ GitHub Actions: Tests / 1_Unit tests (Python 3.13).txt[error] 258-264: pytest test_dashboard_dialog_close_button_has_tooltip failed: the dashboard dialog close button does not expose title="Close (Esc)" and aria-label="Close". Command 'python -m pytest -q' failed with exit code 1. πͺ GitHub Actions: Tests / Unit tests (Python 3.11)[error] 258-264: pytest test_dashboard_dialog_close_button_has_tooltip failed: the dashboard dialog close button does not have title="Close (Esc)" and aria-label="Close". Command 'python -m pytest -q' exited with code 1. πͺ GitHub Actions: Tests / Unit tests (Python 3.13)[error] 258-264: pytest test_dashboard_dialog_close_button_has_tooltip failed: the dashboard dialog close button does not have title="Close (Esc)" and aria-label="Close". Command 'python -m pytest -q' failed with exit code 1. π€ Prompt for AI Agents |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
π Security & Privacy | π‘ Minor | β‘ Quick win
π§© Analysis chain
π Script executed:
Repository: ContextualWisdomLab/appguardrail
Length of output: 11027
π Script executed:
Repository: ContextualWisdomLab/appguardrail
Length of output: 10943
π Script executed:
Repository: ContextualWisdomLab/appguardrail
Length of output: 8936
Open Redirect (CWE-601): URL Redirection to Untrusted Site ('Open Redirect')
Reachability: External Β· Exploitability: Moderate
URLμ μ κ·νν κ°μΌλ‘ κ²μ¦νκ³ λ°ννμΈμ.
safeUrlμnew URL()λ‘ μΈλΆ URLμ μΉμΈν λ€ μλ³Έ λ¬Έμμ΄μhrefμ λ°νν©λλ€. λ°λΌμ μ ν 곡백·μ μ΄λ¬ΈμΒ·μμ¬λμκ° ν¬ν¨λ μ λ ₯μ΄ μΈλΆ origin λ§ν¬λ‘ ν΄μλ μ μμ΅λλ€. μ κ·ν νhttp:μhttps:νμ© λͺ©λ‘μ μ μ©νκ³ λ³ν μ λ ₯ ν μ€νΈλ₯Ό μΆκ°νμΈμ.π€ Prompt for AI Agents
Source: Coding guidelines