feat: SARIF 2.1.0 download on deep scan (Shannon 흡수)
Browse files
app.py
CHANGED
|
@@ -10,6 +10,7 @@ import requests
|
|
| 10 |
import gradio as gr
|
| 11 |
from huggingface_hub import whoami
|
| 12 |
from gradio_client import Client
|
|
|
|
| 13 |
|
| 14 |
ENGINE = os.environ.get("CHITOS_ENGINE_REPO", "")
|
| 15 |
HFTOKEN = os.environ.get("HF_TOKEN", "")
|
|
@@ -469,6 +470,17 @@ def _save_html(body, host, deep):
|
|
| 469 |
return fn
|
| 470 |
|
| 471 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 472 |
def _spin(lang):
|
| 473 |
return ("""<div style="text-align:center;padding:40px 0;font-family:sans-serif">
|
| 474 |
<div style="width:46px;height:46px;border:5px solid #ede9fe;border-top-color:#6d28d9;border-radius:50%;margin:0 auto;animation:chspin .8s linear infinite"></div>
|
|
@@ -493,28 +505,32 @@ def free_scan(url, lang):
|
|
| 493 |
|
| 494 |
|
| 495 |
def deep_scan(url, lang, profile: gr.OAuthProfile | None = None, oauth_token: gr.OAuthToken | None = None):
|
|
|
|
| 496 |
if profile is None or oauth_token is None:
|
| 497 |
return _note(_L('먼저 위의 <b>"Sign in with Hugging Face"</b> 버튼으로 로그인하세요. (회사/조직 도메인 메일로 가입한 계정)',
|
| 498 |
-
'First sign in with the <b>"Sign in with Hugging Face"</b> button above. (an account registered on your company/org domain email)', lang), "mid"),
|
| 499 |
if not (url or "").strip():
|
| 500 |
-
return _note(_L("진단할 주소를 입력하세요.", "Enter a URL to scan.", lang), "mid"),
|
| 501 |
try:
|
| 502 |
email = (whoami(token=oauth_token.token).get("email") or "").lower()
|
| 503 |
except Exception:
|
| 504 |
email = ""
|
| 505 |
if not email:
|
| 506 |
return _note(_L("로그인 계정의 인증된 이메일을 읽지 못했습니다. HF 계정 이메일 인증 후 다시 시도하세요.",
|
| 507 |
-
"Could not read a verified email from your account. Verify your HF account email and try again.", lang), "hi"),
|
| 508 |
edom = email.split("@")[-1]
|
| 509 |
tdom = _domain(url)
|
| 510 |
if edom != tdom and not tdom.endswith("." + edom) and not edom.endswith("." + tdom):
|
| 511 |
return _note(_L("도메인 소유 확인 실패. 진단 대상(<b>%s</b>)의 도메인 이메일로 가입한 HF 계정으로 로그인해야 합니다. 현재 계정 도메인: <b>%s</b>" % (html.escape(tdom), html.escape(edom)),
|
| 512 |
-
"Ownership check failed. Sign in with an HF account on the target domain (<b>%s</b>). Your account domain: <b>%s</b>" % (html.escape(tdom), html.escape(edom)), lang), "hi"),
|
| 513 |
d = _api("/deep", {"url": url})
|
| 514 |
body = build_report(d, deep=True, verified_email=email, lang=lang)
|
| 515 |
if d.get("error") or d.get("blocked"):
|
| 516 |
-
return body,
|
| 517 |
-
|
|
|
|
|
|
|
|
|
|
| 518 |
|
| 519 |
|
| 520 |
def consult(area, name, company, email, phone, msg, lang):
|
|
@@ -799,8 +815,9 @@ with gr.Blocks(title="CHITOS 인스턴트 스캔", css=CSS, theme=gr.themes.Soft
|
|
| 799 |
u2 = gr.Textbox(label="진단할 주소 / Target URL", placeholder="example.com")
|
| 800 |
b2 = gr.Button("인증 후 심화 진단 / Verify & deep scan", variant="primary")
|
| 801 |
f2 = gr.File(label="리포트 다운로드 / Download report (HTML)", visible=False)
|
|
|
|
| 802 |
o2 = gr.HTML()
|
| 803 |
-
b2.click(_loading, lang_state, [o2, f2]).then(deep_scan, inputs=[u2, lang_state], outputs=[o2, f2, last_deep])
|
| 804 |
with gr.Tab("③ 상담 · CONSULT"):
|
| 805 |
g_d3 = gr.HTML(desc3("ko"))
|
| 806 |
g_ah = gr.HTML(area_help("ko"))
|
|
|
|
| 10 |
import gradio as gr
|
| 11 |
from huggingface_hub import whoami
|
| 12 |
from gradio_client import Client
|
| 13 |
+
from chitos_sarif import to_sarif
|
| 14 |
|
| 15 |
ENGINE = os.environ.get("CHITOS_ENGINE_REPO", "")
|
| 16 |
HFTOKEN = os.environ.get("HF_TOKEN", "")
|
|
|
|
| 470 |
return fn
|
| 471 |
|
| 472 |
|
| 473 |
+
def _save_sarif(d, host):
|
| 474 |
+
try:
|
| 475 |
+
s = to_sarif(d)
|
| 476 |
+
except Exception:
|
| 477 |
+
return None
|
| 478 |
+
fn = os.path.join(tempfile.gettempdir(), "CHITOS_%s.sarif.json" % host.replace(".", "_"))
|
| 479 |
+
with open(fn, "w", encoding="utf-8") as f:
|
| 480 |
+
json.dump(s, f, ensure_ascii=False, indent=1)
|
| 481 |
+
return fn
|
| 482 |
+
|
| 483 |
+
|
| 484 |
def _spin(lang):
|
| 485 |
return ("""<div style="text-align:center;padding:40px 0;font-family:sans-serif">
|
| 486 |
<div style="width:46px;height:46px;border:5px solid #ede9fe;border-top-color:#6d28d9;border-radius:50%;margin:0 auto;animation:chspin .8s linear infinite"></div>
|
|
|
|
| 505 |
|
| 506 |
|
| 507 |
def deep_scan(url, lang, profile: gr.OAuthProfile | None = None, oauth_token: gr.OAuthToken | None = None):
|
| 508 |
+
_hide = gr.update(visible=False)
|
| 509 |
if profile is None or oauth_token is None:
|
| 510 |
return _note(_L('먼저 위의 <b>"Sign in with Hugging Face"</b> 버튼으로 로그인하세요. (회사/조직 도메인 메일로 가입한 계정)',
|
| 511 |
+
'First sign in with the <b>"Sign in with Hugging Face"</b> button above. (an account registered on your company/org domain email)', lang), "mid"), _hide, _hide, None
|
| 512 |
if not (url or "").strip():
|
| 513 |
+
return _note(_L("진단할 주소를 입력하세요.", "Enter a URL to scan.", lang), "mid"), _hide, _hide, None
|
| 514 |
try:
|
| 515 |
email = (whoami(token=oauth_token.token).get("email") or "").lower()
|
| 516 |
except Exception:
|
| 517 |
email = ""
|
| 518 |
if not email:
|
| 519 |
return _note(_L("로그인 계정의 인증된 이메일을 읽지 못했습니다. HF 계정 이메일 인증 후 다시 시도하세요.",
|
| 520 |
+
"Could not read a verified email from your account. Verify your HF account email and try again.", lang), "hi"), _hide, _hide, None
|
| 521 |
edom = email.split("@")[-1]
|
| 522 |
tdom = _domain(url)
|
| 523 |
if edom != tdom and not tdom.endswith("." + edom) and not edom.endswith("." + tdom):
|
| 524 |
return _note(_L("도메인 소유 확인 실패. 진단 대상(<b>%s</b>)의 도메인 이메일로 가입한 HF 계정으로 로그인해야 합니다. 현재 계정 도메인: <b>%s</b>" % (html.escape(tdom), html.escape(edom)),
|
| 525 |
+
"Ownership check failed. Sign in with an HF account on the target domain (<b>%s</b>). Your account domain: <b>%s</b>" % (html.escape(tdom), html.escape(edom)), lang), "hi"), _hide, _hide, None
|
| 526 |
d = _api("/deep", {"url": url})
|
| 527 |
body = build_report(d, deep=True, verified_email=email, lang=lang)
|
| 528 |
if d.get("error") or d.get("blocked"):
|
| 529 |
+
return body, _hide, _hide, None
|
| 530 |
+
host = d.get("host", "site")
|
| 531 |
+
sarif_fn = _save_sarif(d, host)
|
| 532 |
+
sarif_up = gr.update(value=sarif_fn, visible=True) if sarif_fn else _hide
|
| 533 |
+
return body, gr.update(value=_save_html(body, host, True), visible=True), sarif_up, {"d": d, "email": email}
|
| 534 |
|
| 535 |
|
| 536 |
def consult(area, name, company, email, phone, msg, lang):
|
|
|
|
| 815 |
u2 = gr.Textbox(label="진단할 주소 / Target URL", placeholder="example.com")
|
| 816 |
b2 = gr.Button("인증 후 심화 진단 / Verify & deep scan", variant="primary")
|
| 817 |
f2 = gr.File(label="리포트 다운로드 / Download report (HTML)", visible=False)
|
| 818 |
+
f_sarif = gr.File(label="SARIF 2.1.0 다운로드 / Download SARIF (CI/CD·GitHub Security)", visible=False)
|
| 819 |
o2 = gr.HTML()
|
| 820 |
+
b2.click(_loading, lang_state, [o2, f2]).then(deep_scan, inputs=[u2, lang_state], outputs=[o2, f2, f_sarif, last_deep])
|
| 821 |
with gr.Tab("③ 상담 · CONSULT"):
|
| 822 |
g_d3 = gr.HTML(desc3("ko"))
|
| 823 |
g_ah = gr.HTML(area_help("ko"))
|