Team Ai
Apppublic

ayshajavd/code-security-analyzer

sourceHugging Faceapache-2.0updated 5mo agoView on Hugging Face
0likes
app.py437 linesDownload Raw Back to root
1"""2Code Security Risk Analyzer v2 - Gradio UI + REST API3=====================================================4IMPROVEMENTS OVER v1:5- Per-class threshold optimization (not global 0.3)6- Temperature scaling calibration (meaningful probabilities)7- Uses label_config.json for thresholds + calibration8- Better vulnerability detection across rare CWEs9 10Run AFTER notebooks 1-4 to use the improved models.11Upload this to: https://huggingface.co/spaces/ayshajavd/code-security-analyzer12"""13import json14import re15import time16import torch17import gradio as gr18from transformers import (19    AutoTokenizer,20    AutoModelForSequenceClassification,21    T5ForConditionalGeneration,22)23from huggingface_hub import hf_hub_download24import numpy as np25 26# ============================================================27# Label Mappings28# ============================================================29TARGET_CWES = [30    "safe", "CWE-20", "CWE-22", "CWE-78", "CWE-79", "CWE-89", "CWE-94",31    "CWE-119", "CWE-125", "CWE-190", "CWE-200", "CWE-264", "CWE-269",32    "CWE-276", "CWE-284", "CWE-287", "CWE-310", "CWE-327", "CWE-330",33    "CWE-352", "CWE-362", "CWE-399", "CWE-401", "CWE-416", "CWE-434",34    "CWE-476", "CWE-502", "CWE-601", "CWE-787", "CWE-798", "CWE-918",35]36 37CWE_NAMES = {38    "safe": "Safe Code",39    "CWE-20": "Improper Input Validation",40    "CWE-22": "Path Traversal",41    "CWE-78": "OS Command Injection",42    "CWE-79": "Cross-Site Scripting (XSS)",43    "CWE-89": "SQL Injection",44    "CWE-94": "Code Injection",45    "CWE-119": "Buffer Overflow",46    "CWE-125": "Out-of-bounds Read",47    "CWE-190": "Integer Overflow",48    "CWE-200": "Information Exposure",49    "CWE-264": "Permissions/Privileges/Access Controls",50    "CWE-269": "Improper Privilege Management",51    "CWE-276": "Incorrect Default Permissions",52    "CWE-284": "Improper Access Control",53    "CWE-287": "Improper Authentication",54    "CWE-310": "Cryptographic Issues",55    "CWE-327": "Broken Crypto Algorithm",56    "CWE-330": "Insufficient Randomness",57    "CWE-352": "Cross-Site Request Forgery (CSRF)",58    "CWE-362": "Race Condition",59    "CWE-399": "Resource Management Errors",60    "CWE-401": "Memory Leak",61    "CWE-416": "Use After Free",62    "CWE-434": "Unrestricted File Upload",63    "CWE-476": "NULL Pointer Dereference",64    "CWE-502": "Insecure Deserialization",65    "CWE-601": "Open Redirect",66    "CWE-787": "Out-of-bounds Write",67    "CWE-798": "Hardcoded Credentials",68    "CWE-918": "Server-Side Request Forgery (SSRF)",69}70 71CWE_TO_OWASP = {72    "CWE-22": "A01:2021 - Broken Access Control",73    "CWE-200": "A01:2021 - Broken Access Control",74    "CWE-264": "A01:2021 - Broken Access Control",75    "CWE-276": "A01:2021 - Broken Access Control",76    "CWE-284": "A01:2021 - Broken Access Control",77    "CWE-352": "A01:2021 - Broken Access Control",78    "CWE-601": "A01:2021 - Broken Access Control",79    "CWE-269": "A01:2021 - Broken Access Control",80    "CWE-310": "A02:2021 - Cryptographic Failures",81    "CWE-327": "A02:2021 - Cryptographic Failures",82    "CWE-330": "A02:2021 - Cryptographic Failures",83    "CWE-20": "A03:2021 - Injection",84    "CWE-78": "A03:2021 - Injection",85    "CWE-79": "A03:2021 - Injection",86    "CWE-89": "A03:2021 - Injection",87    "CWE-94": "A03:2021 - Injection",88    "CWE-119": "A03:2021 - Injection",89    "CWE-125": "A03:2021 - Injection",90    "CWE-190": "A03:2021 - Injection",91    "CWE-416": "A03:2021 - Injection",92    "CWE-476": "A03:2021 - Injection",93    "CWE-401": "A03:2021 - Injection",94    "CWE-787": "A03:2021 - Injection",95    "CWE-434": "A04:2021 - Insecure Design",96    "CWE-362": "A04:2021 - Insecure Design",97    "CWE-399": "A04:2021 - Insecure Design",98    "CWE-287": "A07:2021 - Identification & Auth Failures",99    "CWE-798": "A07:2021 - Identification & Auth Failures",100    "CWE-502": "A08:2021 - Software & Data Integrity Failures",101    "CWE-918": "A10:2021 - Server-Side Request Forgery",102}103 104SEVERITY_MAP = {105    "CWE-89": ("Critical", 95), "CWE-78": ("Critical", 93),106    "CWE-94": ("Critical", 92), "CWE-502": ("Critical", 90),107    "CWE-918": ("Critical", 88), "CWE-798": ("Critical", 87),108    "CWE-119": ("High", 85), "CWE-787": ("High", 84),109    "CWE-416": ("High", 83), "CWE-79": ("High", 80),110    "CWE-22": ("High", 78), "CWE-287": ("High", 77),111    "CWE-284": ("High", 76), "CWE-434": ("High", 75),112    "CWE-125": ("Medium", 70), "CWE-190": ("Medium", 68),113    "CWE-352": ("Medium", 67), "CWE-476": ("Medium", 65),114    "CWE-362": ("Medium", 63), "CWE-20": ("Medium", 60),115    "CWE-264": ("Medium", 58), "CWE-269": ("Medium", 57),116    "CWE-310": ("Medium", 65), "CWE-327": ("Medium", 62),117    "CWE-330": ("Medium", 55), "CWE-399": ("Low", 45),118    "CWE-401": ("Low", 42), "CWE-200": ("Low", 40),119    "CWE-276": ("Low", 38), "CWE-601": ("Medium", 55),120}121 122EXPLANATIONS = {123    "CWE-89": "**SQL Injection** means an attacker can manipulate your database queries by injecting malicious SQL code through user inputs. This could let them steal, modify, or delete ALL your data.",124    "CWE-79": "**Cross-Site Scripting (XSS)** lets attackers inject malicious JavaScript into your web pages. When other users visit the page, the script runs in their browser - stealing cookies, session tokens, or redirecting them to fake sites.",125    "CWE-78": "**OS Command Injection** means user input is being passed directly to system commands. An attacker could run ANY command on your server.",126    "CWE-94": "**Code Injection** allows attackers to inject and execute arbitrary code. Functions like `eval()`, `exec()`, or dynamic code compilation with untrusted input are the usual culprits.",127    "CWE-119": "**Buffer Overflow** happens when your code writes data beyond the allocated memory buffer. Attackers can exploit this to crash your program or execute malicious code.",128    "CWE-125": "**Out-of-bounds Read** means your code reads memory outside the intended buffer. This can leak sensitive data like passwords or encryption keys.",129    "CWE-190": "**Integer Overflow** occurs when an arithmetic operation produces a value too large for the data type, which can be chained with buffer overflows for code execution.",130    "CWE-200": "**Information Exposure** means sensitive data (API keys, passwords, stack traces) is being leaked to unauthorized parties.",131    "CWE-264": "**Improper Access Control** means users can access resources or perform actions they shouldn't be authorized for.",132    "CWE-287": "**Authentication Bypass** means the login/identity verification can be circumvented.",133    "CWE-310": "**Cryptographic Issues** - you're using weak, broken, or improperly configured encryption.",134    "CWE-352": "**CSRF** tricks authenticated users into performing unwanted actions on your site.",135    "CWE-362": "**Race Condition** means two operations compete for the same resource without proper synchronization.",136    "CWE-416": "**Use After Free** - memory is being used after it's been freed. Attackers can exploit this for arbitrary code execution.",137    "CWE-434": "**Unrestricted File Upload** lets attackers upload malicious files (like web shells) to your server.",138    "CWE-476": "**NULL Pointer Dereference** - your code tries to use a pointer that's NULL, causing crashes.",139    "CWE-502": "**Insecure Deserialization** means untrusted data is deserialized without validation, enabling code execution.",140    "CWE-601": "**Open Redirect** lets attackers redirect users from your trusted site to a malicious one for phishing.",141    "CWE-787": "**Out-of-bounds Write** - data is written outside the intended memory buffer, often leading to remote code execution.",142    "CWE-798": "**Hardcoded Credentials** - passwords, API keys, or tokens are embedded directly in the source code.",143    "CWE-918": "**SSRF** lets attackers make your server send requests to internal systems, accessing internal APIs or cloud metadata.",144    "CWE-22": "**Path Traversal** means user input is used in file paths without sanitization. Attackers can use `../` to access any file on the server.",145    "CWE-269": "**Privilege Escalation** - a user can gain higher privileges than intended.",146    "CWE-276": "**Incorrect Permissions** - files or resources have permissions that are too permissive.",147    "CWE-327": "**Broken Cryptography** - you're using algorithms like MD5 or SHA1 that are cryptographically broken.",148    "CWE-330": "**Insufficient Randomness** - security-critical random values (tokens, keys) are predictable.",149    "CWE-399": "**Resource Management Issues** - improper handling of system resources can lead to denial of service.",150    "CWE-401": "**Memory Leak** - memory is allocated but never freed, eventually causing crashes.",151    "CWE-20": "**Improper Input Validation** - user input isn't properly checked before use, enabling many other vulnerabilities.",152    "CWE-284": "**Broken Access Control** - authorization checks are missing or incorrectly implemented.",153}154 155# ============================================================156# Model Loading157# ============================================================158CLASSIFIER_ID = "ayshajavd/graphcodebert-vuln-classifier"159FIXER_ID = "ayshajavd/codet5p-vuln-fixer"160 161THRESHOLDS = {cwe: 0.3 for cwe in TARGET_CWES}162TEMPERATURE = 1.0163 164print("Loading classifier...")165try:166    cls_tokenizer = AutoTokenizer.from_pretrained(CLASSIFIER_ID)167    cls_model = AutoModelForSequenceClassification.from_pretrained(CLASSIFIER_ID)168    cls_model.eval()169    CLASSIFIER_LOADED = True170    print("Classifier loaded successfully")171    try:172        config_path = hf_hub_download(CLASSIFIER_ID, "label_config.json")173        with open(config_path) as f:174            label_config = json.load(f)175        if "optimized_thresholds" in label_config:176            THRESHOLDS = label_config["optimized_thresholds"]177            print(f"Per-class thresholds loaded ({len(THRESHOLDS)} classes)")178        if "temperature" in label_config:179            TEMPERATURE = label_config["temperature"]180            print(f"Temperature calibration loaded (T={TEMPERATURE:.4f})")181    except Exception as e:182        print(f"Could not load label_config: {e}. Using defaults.")183except Exception as e:184    print(f"Classifier not available: {e}")185    cls_tokenizer = AutoTokenizer.from_pretrained("huggingface/CodeBERTa-small-v1")186    cls_model = AutoModelForSequenceClassification.from_pretrained(187        "huggingface/CodeBERTa-small-v1", num_labels=31, problem_type="multi_label_classification",188    )189    cls_model.eval()190    CLASSIFIER_LOADED = False191 192print("Loading fix generator...")193try:194    fix_tokenizer = AutoTokenizer.from_pretrained(FIXER_ID)195    fix_model = T5ForConditionalGeneration.from_pretrained(FIXER_ID)196    fix_model.eval()197    FIXER_LOADED = True198    print("Fix generator loaded successfully")199except Exception as e:200    print(f"Fix generator not available: {e}")201    fix_tokenizer = AutoTokenizer.from_pretrained("Salesforce/codet5p-220m")202    fix_model = T5ForConditionalGeneration.from_pretrained("Salesforce/codet5p-220m")203    fix_model.eval()204    FIXER_LOADED = False205 206 207def detect_language(code: str) -> str:208    code_lower = code[:500].lower()209    if "<?php" in code_lower: return "PHP"210    if "package main" in code_lower and "func " in code_lower: return "Go"211    if "#include" in code_lower:212        if "class " in code_lower or "std::" in code_lower or "cout" in code_lower: return "C++"213        return "C"214    if "import java" in code_lower or "public class" in code_lower: return "Java"215    if re.search(r'\b(const |let |var |function |=>|require\(|module\.exports)', code_lower): return "JavaScript"216    if re.search(r'\b(def |import |from |class |self\.|print\()', code_lower): return "Python"217    return "Unknown"218 219 220def classify_code(code):221    inputs = cls_tokenizer(code, return_tensors="pt", max_length=512, truncation=True, padding=True)222    with torch.no_grad():223        logits = cls_model(**inputs).logits.squeeze()224        calibrated_logits = logits / TEMPERATURE225        probs = torch.sigmoid(calibrated_logits).numpy()226    detected = []227    for i, (cwe, p) in enumerate(zip(TARGET_CWES, probs)):228        if cwe == "safe":229            continue230        threshold = THRESHOLDS.get(cwe, 0.3)231        if p > threshold:232            detected.append((cwe, float(p)))233    detected.sort(key=lambda x: x[1], reverse=True)234    return detected, float(probs[0]), {cwe: float(p) for cwe, p in zip(TARGET_CWES, probs)}235 236 237def generate_fix(code, language, cwe_id=None):238    if cwe_id:239        cwe_name = CWE_NAMES.get(cwe_id, cwe_id)240        prefix = f"fix {cwe_name} vulnerability in {language.lower()}: "241    else:242        prefix = f"fix {language.lower()}: "243    input_ids = fix_tokenizer(prefix + code, return_tensors="pt", max_length=512, truncation=True).input_ids244    with torch.no_grad():245        out = fix_model.generate(input_ids, max_length=512, num_beams=5, early_stopping=True, no_repeat_ngram_size=3)246    return fix_tokenizer.decode(out[0], skip_special_tokens=True)247 248 249def build_json_report(code):250    language = detect_language(code)251    detected, safe_prob, all_probs = classify_code(code)252    if not detected:253        overall_risk = max(0, int(100 - 100 * safe_prob))254        risk_level = "Low"255    else:256        max_sev = max(SEVERITY_MAP.get(c, ("Low", 30))[1] for c, _ in detected)257        avg_conf = sum(p for _, p in detected) / len(detected)258        overall_risk = min(100, int(max_sev * avg_conf * 1.2))259        risk_level = "Critical" if overall_risk >= 80 else "High" if overall_risk >= 60 else "Medium" if overall_risk >= 40 else "Low"260    vulns = []261    for cwe, conf in detected:262        sev, score = SEVERITY_MAP.get(cwe, ("Medium", 50))263        threshold_used = THRESHOLDS.get(cwe, 0.3)264        vulns.append({265            "cwe_id": cwe, "name": CWE_NAMES.get(cwe, cwe),266            "owasp_category": CWE_TO_OWASP.get(cwe, "N/A"),267            "severity": sev, "severity_score": score,268            "detection_confidence": round(conf, 4),269            "threshold_used": round(threshold_used, 3),270            "exploit_likelihood": min(100, int(conf * score)),271            "explanation": EXPLANATIONS.get(cwe, "Security risk detected.").replace("**", ""),272        })273    chain = None274    if len(detected) > 1:275        steps = []276        cats = {c for c, _ in detected}277        if cats & {"CWE-20","CWE-89","CWE-79","CWE-78","CWE-94"}:278            steps.append({"step": len(steps)+1, "phase": "Initial Access", "description": "Exploit input validation weakness"})279        if cats & {"CWE-264","CWE-269","CWE-284","CWE-287"}:280            steps.append({"step": len(steps)+1, "phase": "Privilege Escalation", "description": "Bypass access controls"})281        if cats & {"CWE-200","CWE-22","CWE-125"}:282            steps.append({"step": len(steps)+1, "phase": "Data Exfiltration", "description": "Read sensitive files or memory"})283        if cats & {"CWE-119","CWE-416","CWE-787","CWE-502"}:284            steps.append({"step": len(steps)+1, "phase": "Code Execution", "description": "Exploit memory corruption"})285        if steps: chain = steps286    fix = None287    try:288        top_cwe = detected[0][0] if detected else None289        f = generate_fix(code, language, top_cwe)290        if f and f.strip(): fix = f291    except: pass292    return {293        "language": language,294        "model_status": {295            "classifier": "trained_v2" if CLASSIFIER_LOADED else "base_model",296            "fix_generator": "trained_v2" if FIXER_LOADED else "base_model",297            "calibration": f"T={TEMPERATURE:.4f}" if TEMPERATURE != 1.0 else "none",298            "thresholds": "per_class_optimized" if any(v != 0.3 for v in THRESHOLDS.values()) else "global_0.3",299        },300        "overall_risk_score": overall_risk, "risk_level": risk_level,301        "safe_probability": round(safe_prob, 4), "num_vulnerabilities": len(vulns),302        "vulnerabilities": vulns, "attack_chain": chain, "suggested_fix": fix,303        "all_class_probabilities": all_probs,304        "timestamp": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),305    }306 307 308def analyze_code(code):309    if not code or not code.strip(): return "Please paste some code to analyze."310    data = build_json_report(code)311    r = ["# Code Security Analysis Report\n"]312    r.append(f"**Language:** {data['language']}")313    cls_status = "Trained v2 (GraphCodeBERT + ASL)" if data['model_status']['classifier'] == 'trained_v2' else "Base Model"314    fix_status = "Trained v2 (CodeT5+ CWE-aware)" if data['model_status']['fix_generator'] == 'trained_v2' else "Base Model"315    r.append(f"**Classifier:** {cls_status}")316    r.append(f"**Fix Generator:** {fix_status}")317    if data['model_status']['calibration'] != 'none':318        r.append(f"**Calibration:** {data['model_status']['calibration']} | **Thresholds:** {data['model_status']['thresholds']}")319    r.append("")320    if data['num_vulnerabilities'] == 0:321        r.append("## No Vulnerabilities Detected")322        r.append(f"**Risk Score:** {data['overall_risk_score']}/100 | **Safe Confidence:** {data['safe_probability']:.1%}\n")323        r.append("Code appears safe. Always supplement with manual review and SAST tools.")324        return "\n".join(r)325    emoji = {"Critical":"๐Ÿ”ด","High":"๐ŸŸ ","Medium":"๐ŸŸก","Low":"๐ŸŸข"}.get(data['risk_level'],"โšช")326    r.append(f"## {emoji} {data['num_vulnerabilities']} Vulnerability(ies) Detected\n")327    r.append(f"**Risk Score:** {data['overall_risk_score']}/100 ({data['risk_level']}) | **Safe Probability:** {data['safe_probability']:.1%}\n---\n")328    for i, v in enumerate(data['vulnerabilities'], 1):329        se = {"Critical":"๐Ÿ”ด","High":"๐ŸŸ ","Medium":"๐ŸŸก","Low":"๐ŸŸข"}.get(v['severity'],"โšช")330        r.append(f"### {i}. {se} {v['name']}")331        r.append("| Property | Value |\n|----------|-------|")332        r.append(f"| **CWE ID** | {v['cwe_id']} |")333        r.append(f"| **OWASP** | {v['owasp_category']} |")334        r.append(f"| **Severity** | {v['severity']} ({v['severity_score']}/100) |")335        r.append(f"| **Confidence** | {v['detection_confidence']:.1%} (calibrated) |")336        r.append(f"| **Threshold** | {v['threshold_used']:.3f} (per-class optimized) |")337        r.append(f"| **Exploit Likelihood** | {v['exploit_likelihood']}% |")338        r.append(f"\n**Why Dangerous:** {v['explanation']}\n")339    if data['attack_chain']:340        r.append("---\n## Attack Chain\n")341        for s in data['attack_chain']:342            r.append(f"{s['step']}. **{s['phase']}** โ€” {s['description']}")343    r.append("\n---\n## Suggested Fix\n")344    if data['suggested_fix']:345        r.append(f"```{data['language'].lower()}\n{data['suggested_fix']}\n```")346    else:347        r.append("*Fix generation unavailable. Please review manually.*")348    r.append("\n---\n*AI-generated report (v2: calibrated probabilities + per-class thresholds). Verify with manual review and SAST tools.*")349    return "\n".join(r)350 351 352def get_json_report(code):353    if not code or not code.strip(): return {"error": "No code provided"}354    return build_json_report(code)355 356 357EXAMPLES = [358    ["""import sqlite3\n\ndef get_user(username):\n    conn = sqlite3.connect('users.db')\n    query = f"SELECT * FROM users WHERE username = '{username}'"\n    return conn.execute(query).fetchone()\n"""],359    ["""#include <stdio.h>\n#include <string.h>\n\nvoid process_input(char *user_input) {\n    char buffer[64];\n    strcpy(buffer, user_input);\n    printf("Processed: %s\\n", buffer);\n}\n"""],360    ["""const express = require('express');\nconst app = express();\n\napp.get('/search', (req, res) => {\n    const query = req.query.q;\n    res.send(`<h1>Results for: ${query}</h1>`);\n});\n"""],361    ["""import requests, hashlib\n\nAPI_KEY = "sk-proj-abc123def456"\nDB_PASSWORD = "admin123"\n\ndef hash_password(password):\n    return hashlib.md5(password.encode()).hexdigest()\n"""],362    ["""import sqlite3\nfrom hashlib import sha256\nimport hmac, secrets\n\ndef get_user(username):\n    conn = sqlite3.connect('users.db')\n    conn.execute("SELECT * FROM users WHERE username = ?", (username,))\n    return conn.fetchone()\n"""],363]364 365with gr.Blocks(366    title="Code Security Risk Analyzer v2",367    theme=gr.themes.Soft(),368    css=".gradio-container { max-width: 1200px; margin: auto; }",369) as demo:370    gr.Markdown("""371    # ๐Ÿ”’ AI-Powered Code Security Risk Analyzer v2372    ### Detect OWASP Top 10 & CWE vulnerabilities with calibrated confidence + per-class thresholds373 374    Paste code in Python, JavaScript, Java, C, C++, PHP, or Go.375 376    **Models:** [GraphCodeBERT](https://huggingface.co/ayshajavd/graphcodebert-vuln-classifier) (detection, Macro F1=0.476) + [CodeT5+](https://huggingface.co/ayshajavd/codet5p-vuln-fixer) (fixes, BLEU=81.0) | **Dataset:** [175K samples](https://huggingface.co/datasets/ayshajavd/code-security-vulnerability-dataset)377 378    **v2 Improvements:** Per-class threshold optimization | Temperature-calibrated probabilities | Asymmetric Loss training | GraphCodeBERT-base (125M params) | CodeT5+ 220M CWE-aware fixer379    """)380 381    with gr.Row():382        with gr.Column(scale=1):383            code_input = gr.Code(label="Paste Your Code Here", language="python", lines=20)384            with gr.Row():385                analyze_btn = gr.Button("๐Ÿ” Analyze Security", variant="primary", size="lg")386                json_btn = gr.Button("๐Ÿ“‹ JSON Report", variant="secondary", size="lg")387        with gr.Column(scale=1):388            report_output = gr.Markdown(label="Security Report")389            json_output = gr.JSON(label="JSON Report", visible=False)390 391    gr.Examples(examples=EXAMPLES, inputs=[code_input], label="Example Code Snippets")392 393    def show_json(code):394        return gr.update(visible=True, value=get_json_report(code))395 396    analyze_btn.click(fn=analyze_code, inputs=[code_input], outputs=[report_output], api_name="analyze")397    json_btn.click(fn=show_json, inputs=[code_input], outputs=[json_output])398 399    with gr.Row(visible=False):400        api_json_btn = gr.Button("get_json", visible=False)401        api_json_btn.click(fn=get_json_report, inputs=[code_input], outputs=[json_output], api_name="get_json_report")402 403    with gr.Accordion("๐ŸŒ REST API Documentation", open=False):404        gr.Markdown("""405### Python Client406```python407from gradio_client import Client408client = Client("ayshajavd/code-security-analyzer")409report = client.predict(code="your code here", api_name="/analyze")410json_report = client.predict(code="your code here", api_name="/get_json_report")411```412 413### cURL414```bash415curl -X POST https://ayshajavd-code-security-analyzer.hf.space/call/analyze \\416  -H "Content-Type: application/json" -d '{"data": ["your code here"]}'417```418        """)419 420    gr.Markdown("""421---422### 30 CWE Vulnerability Classes โ†’ OWASP Top 10423 424| OWASP Category | CWEs |425|---|---|426| **A01: Broken Access Control** | CWE-22, 200, 264, 269, 276, 284, 352, 601 |427| **A02: Cryptographic Failures** | CWE-310, 327, 330 |428| **A03: Injection** | CWE-20, 78, 79, 89, 94, 119, 125, 190, 401, 416, 476, 787 |429| **A04: Insecure Design** | CWE-362, 399, 434 |430| **A07: Auth Failures** | CWE-287, 798 |431| **A08: Integrity Failures** | CWE-502 |432| **A10: SSRF** | CWE-918 |433    """)434 435if __name__ == "__main__":436    demo.launch()437