Spaces:
Running
Running
| <html lang="zh-CN"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>AI SDL 数字分身 - 风险项目详情</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/atom-one-dark.min.css"> | |
| <style> | |
| .risk-critical { | |
| background-color: #fef2f2; | |
| border-left: 4px solid #ef4444; | |
| } | |
| .risk-high { | |
| background-color: #fff7ed; | |
| border-left: 4px solid #f97316; | |
| } | |
| .risk-medium { | |
| background-color: #eff6ff; | |
| border-left: 4px solid #3b82f6; | |
| } | |
| .risk-low { | |
| background-color: #f0fdf4; | |
| border-left: 4px solid #22c55e; | |
| } | |
| .risk-highlight { | |
| background-color: #fee2e2; | |
| color: #b91c1c; | |
| padding: 0.1rem 0.2rem; | |
| border-radius: 0.25rem; | |
| } | |
| .code-line-highlight { | |
| background-color: #fee2e2; | |
| display: block; | |
| margin: 0 -1rem; | |
| padding: 0 1rem; | |
| border-left: 3px solid #ef4444; | |
| } | |
| .tab-content { | |
| display: none; | |
| } | |
| .tab-content.active { | |
| display: block; | |
| } | |
| .architecture-diagram { | |
| width: 100%; | |
| height: 500px; | |
| overflow: auto; | |
| border: 1px solid #e5e7eb; | |
| border-radius: 0.5rem; | |
| } | |
| .code-container { | |
| height: 600px; | |
| overflow-y: auto; | |
| } | |
| .file-tree { | |
| height: 600px; | |
| overflow-y: auto; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-50"> | |
| <div class="container mx-auto px-4 py-8"> | |
| <!-- Header --> | |
| <header class="mb-8"> | |
| <h1 class="text-3xl font-bold text-gray-800">AI SDL 数字分身 - 风险项目详情</h1> | |
| <div class="flex items-center mt-4"> | |
| <span class="bg-blue-100 text-blue-800 text-sm font-medium px-2.5 py-0.5 rounded">支付宝国补项目</span> | |
| <span class="ml-4 text-sm text-gray-600">风险等级: <span class="font-medium text-red-600">高危</span></span> | |
| </div> | |
| </header> | |
| <!-- Project Summary --> | |
| <div class="bg-white rounded-lg shadow-md p-6 mb-8"> | |
| <h2 class="text-xl font-semibold text-gray-800 mb-4">项目概要</h2> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> | |
| <div> | |
| <h3 class="text-lg font-medium text-gray-700 mb-2">项目名称</h3> | |
| <p class="text-gray-800">支付宝国补项目</p> | |
| <h3 class="text-lg font-medium text-gray-700 mt-4 mb-2">风险概述</h3> | |
| <ul class="list-disc pl-5 text-gray-800"> | |
| <li>需求环节: 越权风险</li> | |
| <li>代码环节: SQL注入风险</li> | |
| <li>安全测试环节: 订单ID枚举风险</li> | |
| </ul> | |
| </div> | |
| <div> | |
| <h3 class="text-lg font-medium text-gray-700 mb-2">项目参与人</h3> | |
| <div class="flex flex-wrap gap-2"> | |
| <span class="bg-green-100 text-green-800 text-sm px-3 py-1 rounded-full">形知</span> | |
| <span class="bg-blue-100 text-blue-800 text-sm px-3 py-1 rounded-full">铸梦</span> | |
| <span class="bg-purple-100 text-purple-800 text-sm px-3 py-1 rounded-full">洞悉</span> | |
| <span class="bg-yellow-100 text-yellow-800 text-sm px-3 py-1 rounded-full">隐迹</span> | |
| <span class="bg-red-100 text-red-800 text-sm px-3 py-1 rounded-full">晨熙</span> | |
| </div> | |
| <h3 class="text-lg font-medium text-gray-700 mt-4 mb-2">风险状态</h3> | |
| <div class="flex items-center"> | |
| <div class="w-full bg-gray-200 rounded-full h-2.5"> | |
| <div class="bg-red-600 h-2.5 rounded-full" style="width: 65%"></div> | |
| </div> | |
| <span class="ml-2 text-sm font-medium text-gray-700">65% 风险未修复</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Navigation Tabs --> | |
| <div class="border-b border-gray-200 mb-6"> | |
| <nav class="flex flex-wrap -mb-px"> | |
| <button class="tab-button mr-2 py-4 px-4 border-b-2 font-medium text-sm active" data-tab="requirements"> | |
| 需求环节 | |
| </button> | |
| <button class="tab-button mr-2 py-4 px-4 border-b-2 font-medium text-sm border-transparent" data-tab="code"> | |
| 代码环节 | |
| </button> | |
| <button class="tab-button mr-2 py-4 px-4 border-b-2 font-medium text-sm border-transparent" data-tab="testing"> | |
| 安全测试 | |
| </button> | |
| <button class="tab-button mr-2 py-4 px-4 border-b-2 font-medium text-sm border-transparent" data-tab="release"> | |
| 发布环节 | |
| </button> | |
| <button class="tab-button mr-2 py-4 px-4 border-b-2 font-medium text-sm border-transparent" data-tab="production"> | |
| 线上环节 | |
| </button> | |
| </nav> | |
| </div> | |
| <!-- Requirements Tab --> | |
| <div id="requirements" class="tab-content active"> | |
| <div class="grid grid-cols-1 lg:grid-cols-2 gap-6"> | |
| <!-- Left Column - Requirements Content --> | |
| <div class="bg-white rounded-lg shadow-md p-6"> | |
| <h3 class="text-lg font-semibold text-gray-800 mb-4">需求文档内容</h3> | |
| <div class="prose max-w-none"> | |
| <h3>支付宝国补项目需求文档</h3> | |
| <p>本项目旨在为支付宝用户提供国家补贴申请功能,用户可以通过支付宝APP申请各类政府补贴...</p> | |
| <p class="risk-highlight">1. 用户权限管理:用户可以通过输入其他用户的身份证号查询补贴申请状态(存在越权风险)...</p> | |
| <p>2. 补贴申请流程:用户需要填写个人信息、上传证明材料并提交申请...</p> | |
| <p>3. 审核流程:后台管理员审核用户提交的材料,审核通过后补贴金额将直接打入用户支付宝账户...</p> | |
| <p class="risk-highlight">4. 数据查询接口:提供补贴申请状态查询接口,接口参数为身份证号(未做权限校验)...</p> | |
| <p>5. 数据存储:用户信息将存储在MySQL数据库中,使用阿里云RDS服务...</p> | |
| <p>6. 安全要求:所有敏感数据传输必须加密,用户密码必须哈希存储...</p> | |
| <p>7. 性能要求:系统需要支持每秒1000次查询请求...</p> | |
| <p>8. 日志记录:所有敏感操作需要记录操作日志...</p> | |
| <p>9. 异常处理:系统需要妥善处理各种异常情况...</p> | |
| <p>10. 监控报警:系统需要集成监控报警功能...</p> | |
| <!-- More content would go here --> | |
| </div> | |
| </div> | |
| <!-- Right Column - Security Analysis --> | |
| <div class="bg-white rounded-lg shadow-md p-6"> | |
| <h3 class="text-lg font-semibold text-gray-800 mb-4">安全分析结果</h3> | |
| <div class="mb-6"> | |
| <h4 class="font-medium text-gray-700 mb-2">STRIDE威胁建模</h4> | |
| <div class="mermaid"> | |
| graph LR | |
| A[支付宝客户端] -- 欺骗 --> B[API网关] | |
| B -- 信息泄露 --> C[补贴服务] | |
| C -- 篡改 --> D[MySQL补贴库] | |
| C -- 拒绝服务 --> E[Redis缓存] | |
| B -- 否认 --> F[日志服务] | |
| style A fill:#f9f,stroke:#333 | |
| style B fill:#bbf,stroke:#333,stroke-width:4px | |
| style C fill:#f96,stroke:#333,stroke-width:4px | |
| style D fill:#9f9,stroke:#333 | |
| style E fill:#99f,stroke:#333 | |
| style F fill:#f9f,stroke:#333 | |
| </div> | |
| </div> | |
| <div class="risk-critical p-4 mb-4 rounded"> | |
| <h4 class="font-medium text-red-700 mb-2">1. 越权风险</h4> | |
| <p class="text-sm text-gray-700"><span class="font-medium">业务场景:</span> 补贴申请状态查询</p> | |
| <p class="text-sm text-gray-700"><span class="font-medium">风险点:</span> 用户可以通过输入其他用户的身份证号查询补贴申请状态</p> | |
| <p class="text-sm text-gray-700"><span class="font-medium">风险类型:</span> 水平越权</p> | |
| <p class="text-sm text-gray-700"><span class="font-medium">整改建议:</span> 增加权限校验,确保用户只能查询自己的补贴申请状态</p> | |
| <button class="mt-2 text-sm text-blue-600 hover:underline" onclick="scrollToHighlight('requirements', 1)">定位到需求文档</button> | |
| </div> | |
| <div class="risk-high p-4 rounded"> | |
| <h4 class="font-medium text-orange-700 mb-2">2. 数据泄露风险</h4> | |
| <p class="text-sm text-gray-700"><span class="font-medium">业务场景:</span> 补贴申请数据存储</p> | |
| <p class="text-sm text-gray-700"><span class="font-medium">风险点:</span> 补贴申请数据未加密存储</p> | |
| <p class="text-sm text-gray-700"><span class="font-medium">风险类型:</span> 信息泄露</p> | |
| <p class="text-sm text-gray-700"><span class="font-medium">整改建议:</span> 对敏感字段进行加密存储</p> | |
| <button class="mt-2 text-sm text-blue-600 hover:underline" onclick="scrollToHighlight('requirements', 4)">定位到需求文档</button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Code Tab --> | |
| <div id="code" class="tab-content"> | |
| <div class="grid grid-cols-1 lg:grid-cols-2 gap-6"> | |
| <!-- Left Column - Code Content --> | |
| <div class="bg-white rounded-lg shadow-md p-6"> | |
| <div class="flex items-center mb-4"> | |
| <h3 class="text-lg font-semibold text-gray-800 mr-4">代码内容</h3> | |
| <div class="relative"> | |
| <button class="flex items-center text-sm text-gray-700 bg-gray-100 hover:bg-gray-200 px-3 py-1 rounded"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" /> | |
| </svg> | |
| 文件目录 | |
| </button> | |
| <div class="absolute z-10 mt-1 w-48 bg-white rounded-md shadow-lg py-1 hidden"> | |
| <div class="file-tree p-2"> | |
| <ul class="text-sm text-gray-700"> | |
| <li class="py-1 pl-2 hover:bg-gray-100 rounded cursor-pointer">📁 controllers/ | |
| <ul class="pl-4"> | |
| <li class="py-1 hover:bg-gray-100 rounded cursor-pointer">🔹 SubsidyController.java</li> | |
| <li class="py-1 hover:bg-gray-100 rounded cursor-pointer">🔹 UserController.java</li> | |
| </ul> | |
| </li> | |
| <li class="py-1 pl-2 hover:bg-gray-100 rounded cursor-pointer">📁 services/ | |
| <ul class="pl-4"> | |
| <li class="py-1 hover:bg-gray-100 rounded cursor-pointer">🔹 SubsidyService.java</li> | |
| </ul> | |
| </li> | |
| <li class="py-1 pl-2 hover:bg-gray-100 rounded cursor-pointer">📁 repositories/ | |
| <ul class="pl-4"> | |
| <li class="py-1 hover:bg-gray-100 rounded cursor-pointer">🔹 SubsidyRepository.java</li> | |
| </ul> | |
| </li> | |
| </ul> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="code-container"> | |
| <pre><code class="language-java hljs">package com.alipay.subsidy.controller; | |
| import org.springframework.web.bind.annotation.*; | |
| import java.sql.*; | |
| @RestController | |
| @RequestMapping("/api/subsidy") | |
| public class SubsidyController { | |
| @GetMapping("/status") | |
| public String getSubsidyStatus(@RequestParam String idCard) { | |
| // 漏洞点: SQL注入风险 | |
| String query = "SELECT status FROM subsidy_applications WHERE id_card = '" + idCard + "'"; | |
| try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/subsidy", "user", "pass"); | |
| Statement stmt = conn.createStatement(); | |
| ResultSet rs = stmt.executeQuery(query)) { | |
| if (rs.next()) { | |
| return rs.getString("status"); | |
| } | |
| return "Not found"; | |
| } catch (SQLException e) { | |
| return "Error"; | |
| } | |
| } | |
| @PostMapping("/apply") | |
| public String applySubsidy(@RequestBody SubsidyApplication application) { | |
| // 业务逻辑处理 | |
| return "Success"; | |
| } | |
| // 其他方法... | |
| }</code></pre> | |
| </div> | |
| </div> | |
| <!-- Right Column - Security Analysis --> | |
| <div class="bg-white rounded-lg shadow-md p-6"> | |
| <h3 class="text-lg font-semibold text-gray-800 mb-4">安全分析结果</h3> | |
| <div class="risk-critical p-4 mb-4 rounded"> | |
| <h4 class="font-medium text-red-700 mb-2">SQL注入漏洞</h4> | |
| <p class="text-sm text-gray-700"><span class="font-medium">风险接口:</span> GET /api/subsidy/status</p> | |
| <p class="text-sm text-gray-700"><span class="font-medium">漏洞类型:</span> SQL注入</p> | |
| <p class="text-sm text-gray-700"><span class="font-medium">漏洞级别:</span> 严重</p> | |
| <p class="text-sm text-gray-700"><span class="font-medium">漏洞描述:</span> 直接拼接用户输入的身份证号到SQL查询中,攻击者可以构造恶意输入执行任意SQL命令</p> | |
| <p class="text-sm text-gray-700"><span class="font-medium">漏洞代码:</span> Line 10-12</p> | |
| <button class="mt-2 text-sm text-blue-600 hover:underline" onclick="highlightCodeLine(10)">定位到代码</button> | |
| <div class="mt-3 p-3 bg-gray-50 rounded border border-gray-200"> | |
| <h5 class="text-sm font-medium text-gray-700 mb-1">修复建议:</h5> | |
| <pre class="text-xs bg-gray-800 text-gray-100 p-2 rounded"><code>@GetMapping("/status") | |
| public String getSubsidyStatus(@RequestParam String idCard) { | |
| String query = "SELECT status FROM subsidy_applications WHERE id_card = ?"; | |
| try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/subsidy", "user", "pass"); | |
| PreparedStatement stmt = conn.prepareStatement(query)) { | |
| stmt.setString(1, idCard); | |
| try (ResultSet rs = stmt.executeQuery()) { | |
| if (rs.next()) { | |
| return rs.getString("status"); | |
| } | |
| return "Not found"; | |
| } | |
| } catch (SQLException e) { | |
| return "Error"; | |
| } | |
| }</code></pre> | |
| </div> | |
| </div> | |
| <div class="risk-high p-4 rounded"> | |
| <h4 class="font-medium text-orange-700 mb-2">越权访问</h4> | |
| <p class="text-sm text-gray-700"><span class="font-medium">风险接口:</span> GET /api/subsidy/status</p> | |
| <p class="text-sm text-gray-700"><span class="font-medium">漏洞类型:</span> 水平越权</p> | |
| <p class="text-sm text-gray-700"><span class="font-medium">漏洞级别:</span> 高危</p> | |
| <p class="text-sm text-gray-700"><span class="font-medium">漏洞描述:</span> 接口未校验当前用户是否有权限查询该身份证号的补贴状态</p> | |
| <p class="text-sm text-gray-700"><span class="font-medium">漏洞代码:</span> 整个方法</p> | |
| <button class="mt-2 text-sm text-blue-600 hover:underline" onclick="highlightCodeLine(8)">定位到代码</button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Testing Tab --> | |
| <div id="testing" class="tab-content"> | |
| <div class="grid grid-cols-1 lg:grid-cols-2 gap-6"> | |
| <!-- Left Column - Testing Content --> | |
| <div class="bg-white rounded-lg shadow-md p-6"> | |
| <h3 class="text-lg font-semibold text-gray-800 mb-4">测试内容</h3> | |
| <div class="mb-6"> | |
| <h4 class="font-medium text-gray-700 mb-2">风险接口</h4> | |
| <div class="bg-gray-800 text-gray-100 p-3 rounded"> | |
| <code>GET /api/subsidy/status?idCard=11010119900307753X</code> | |
| </div> | |
| </div> | |
| <div> | |
| <h4 class="font-medium text-gray-700 mb-2">攻击Payload</h4> | |
| <pre class="bg-gray-800 text-gray-100 p-3 rounded text-sm"><code>GET /api/subsidy/status?idCard=11010119900307753X' OR '1'='1 HTTP/1.1 | |
| Host: api.alipay.com | |
| User-Agent: Mozilla/5.0 | |
| Accept: application/json | |
| Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...</code></pre> | |
| </div> | |
| </div> | |
| <!-- Right Column - Security Analysis --> | |
| <div class="bg-white rounded-lg shadow-md p-6"> | |
| <h3 class="text-lg font-semibold text-gray-800 mb-4">安全分析结果</h3> | |
| <div class="risk-critical p-4 mb-4 rounded"> | |
| <h4 class="font-medium text-red-700 mb-2">订单ID枚举漏洞</h4> | |
| <p class="text-sm text-gray-700"><span class="font-medium">风险接口地址:</span> GET /api/subsidy/status</p> | |
| <p class="text-sm text-gray-700"><span class="font-medium">风险描述:</span> 攻击者可以通过枚举身份证号查询任意用户的补贴申请状态</p> | |
| <div class="mt-3"> | |
| <h5 class="text-sm font-medium text-gray-700 mb-1">攻击payload请求内容:</h5> | |
| <pre class="bg-gray-100 p-2 rounded text-xs"><code>GET /api/subsidy/status?idCard=11010119900307753X' OR '1'='1 HTTP/1.1 | |
| Host: api.alipay.com | |
| ...</code></pre> | |
| </div> | |
| </div> | |
| <div class="risk-high p-4 rounded"> | |
| <h4 class="font-medium text-orange-700 mb-2">测试结果</h4> | |
| <p class="text-sm text-gray-700">成功利用漏洞获取了1000+用户的补贴申请状态信息</p> | |
| <p class="text-sm text-gray-700">响应时间: 200ms</p> | |
| <p class="text-sm text-gray-700">成功率: 100%</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Release Tab --> | |
| <div id="release" class="tab-content"> | |
| <div class="grid grid-cols-1 lg:grid-cols-2 gap-6"> | |
| <!-- Left Column - Release Content --> | |
| <div class="bg-white rounded-lg shadow-md p-6"> | |
| <h3 class="text-lg font-semibold text-gray-800 mb-4">发布检查内容</h3> | |
| <div class="space-y-4"> | |
| <div class="p-4 border border-gray-200 rounded-lg"> | |
| <h4 class="font-medium text-gray-700 mb-2">需求环节风险检查</h4> | |
| <div class="flex items-center"> | |
| <div class="w-4 h-4 rounded-full bg-green-500 mr-2"></div> | |
| <span class="text-sm text-gray-700">越权风险 - 已修复</span> | |
| </div> | |
| </div> | |
| <div class="p-4 border border-gray-200 rounded-lg"> | |
| <h4 class="font-medium text-gray-700 mb-2">代码环节风险检查</h4> | |
| <div class="flex items-center mb-1"> | |
| <div class="w-4 h-4 rounded-full bg-red-500 mr-2"></div> | |
| <span class="text-sm text-gray-700">SQL注入风险 - 未修复</span> | |
| </div> | |
| <div class="flex items-center"> | |
| <div class="w-4 h-4 rounded-full bg-red-500 mr-2"></div> | |
| <span class="text-sm text-gray-700">越权访问风险 - 未修复</span> | |
| </div> | |
| </div> | |
| <div class="p-4 border border-gray-200 rounded-lg"> | |
| <h4 class="font-medium text-gray-700 mb-2">安全测试环节风险检查</h4> | |
| <div class="flex items-center"> | |
| <div class="w-4 h-4 rounded-full bg-red-500 mr-2"></div> | |
| <span class="text-sm text-gray-700">订单ID枚举风险 - 未修复</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Right Column - Security Analysis --> | |
| <div class="bg-white rounded-lg shadow-md p-6"> | |
| <h3 class="text-lg font-semibold text-gray-800 mb-4">发布决策</h3> | |
| <div class="risk-critical p-4 mb-4 rounded"> | |
| <h4 class="font-medium text-red-700 mb-2">未修复的风险</h4> | |
| <ul class="list-disc pl-5 text-sm text-gray-700 space-y-1"> | |
| <li>代码环节的SQL注入风险未修复</li> | |
| <li>代码环节的越权访问风险未修复</li> | |
| <li>安全测试环节的订单ID枚举风险未修复</li> | |
| </ul> | |
| </div> | |
| <div class="p-6 bg-red-50 border border-red-200 rounded-lg text-center"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-12 w-12 mx-auto text-red-500" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" /> | |
| </svg> | |
| <h4 class="text-xl font-medium text-red-700 mt-4">拒绝发布</h4> | |
| <p class="text-sm text-gray-700 mt-2">存在严重安全风险,不符合发布标准</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Production Tab --> | |
| <div id="production" class="tab-content"> | |
| <div class="grid grid-cols-1 lg:grid-cols-2 gap-6"> | |
| <!-- Left Column - Production Content --> | |
| <div class="bg-white rounded-lg shadow-md p-6"> | |
| <h3 class="text-lg font-semibold text-gray-800 mb-4">线上风险事件</h3> | |
| <div class="space-y-4"> | |
| <div class="p-4 border border-red-200 rounded-lg bg-red-50"> | |
| <div class="flex justify-between items-start"> | |
| <h4 class="font-medium text-red-700 mb-2">SQL注入攻击</h4> | |
| <span class="text-xs bg-red-100 text-red-800 px-2 py-1 rounded">2023-06-15</span> | |
| </div> | |
| <p class="text-sm text-gray-700">攻击者利用SQL注入漏洞获取了补贴申请数据库中的敏感信息</p> | |
| </div> | |
| <div class="p-4 border border-orange-200 rounded-lg bg-orange-50"> | |
| <div class="flex justify-between items-start"> | |
| <h4 class="font-medium text-orange-700 mb-2">批量枚举攻击</h4> | |
| <span class="text-xs bg-orange-100 text-orange-800 px-2 py-1 rounded">2023-06-18</span> | |
| </div> | |
| <p class="text-sm text-gray-700">攻击者通过枚举身份证号批量查询用户补贴申请状态</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Right Column - Security Analysis --> | |
| <div class="bg-white rounded-lg shadow-md p-6"> | |
| <h3 class="text-lg font-semibold text-gray-800 mb-4">漏洞修复情况</h3> | |
| <div class="space-y-4"> | |
| <div class="p-4 border border-gray-200 rounded-lg"> | |
| <div class="flex justify-between items-center mb-2"> | |
| <h4 class="font-medium text-gray-700">SQL注入漏洞</h4> | |
| <span class="text-xs bg-green-100 text-green-800 px-2 py-1 rounded">已修复</span> | |
| </div> | |
| <p class="text-sm text-gray-700">修复方式: 使用预编译语句替换字符串拼接</p> | |
| <p class="text-sm text-gray-700">修复时间: 2023-06-16 02:15</p> | |
| </div> | |
| <div class="p-4 border border-gray-200 rounded-lg"> | |
| <div class="flex justify-between items-center mb-2"> | |
| <h4 class="font-medium text-gray-700">越权访问漏洞</h4> | |
| <span class="text-xs bg-green-100 text-green-800 px-2 py-1 rounded">已修复</span> | |
| </div> | |
| <p class="text-sm text-gray-700">修复方式: 增加权限校验逻辑</p> | |
| <p class="text-sm text-gray-700">修复时间: 2023-06-16 2:15</p> | |
| </div> | |
| <div class="p-4 border border-gray-200 rounded-lg"> | |
| <div class="flex justify-between items-center mb-2"> | |
| <h4 class="font-medium text-gray-700">订单ID枚举漏洞</h4> | |
| <span class="text-xs bg-yellow-100 text-yellow-800 px-2 py-1 rounded">修复中</span> | |
| </div> | |
| <p class="text-sm text-gray-700">预计修复时间: 2023-06-20</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Initialize Mermaid | |
| mermaid.initialize({ | |
| startOnLoad: true, | |
| theme: 'default', | |
| flowchart: { | |
| useMaxWidth: false, | |
| htmlLabels: true | |
| } | |
| }); | |
| // Initialize syntax highlighting | |
| document.addEventListener('DOMContentLoaded', (event) => { | |
| document.querySelectorAll('pre code').forEach((block) => { | |
| hljs.highlightElement(block); | |
| }); | |
| }); | |
| // Tab switching | |
| document.querySelectorAll('.tab-button').forEach(button => { | |
| button.addEventListener('click', () => { | |
| // Remove active class from all tabs and buttons | |
| document.querySelectorAll('.tab-button').forEach(btn => { | |
| btn.classList.remove('active'); | |
| btn.classList.remove('border-blue-500'); | |
| btn.classList.add('border-transparent'); | |
| }); | |
| document.querySelectorAll('.tab-content').forEach(tab => { | |
| tab.classList.remove('active'); | |
| }); | |
| // Add active class to clicked button and corresponding tab | |
| button.classList.add('active'); | |
| button.classList.add('border-blue-500'); | |
| button.classList.remove('border-transparent'); | |
| const tabId = button.getAttribute('data-tab'); | |
| document.getElementById(tabId).classList.add('active'); | |
| }); | |
| }); | |
| // File tree toggle | |
| document.querySelector('.file-tree').parentElement.previousElementSibling.addEventListener('click', () => { | |
| const menu = document.querySelector('.file-tree').parentElement; | |
| menu.classList.toggle('hidden'); | |
| }); | |
| // Highlight code line | |
| function highlightCodeLine(lineNumber) { | |
| document.querySelectorAll('.hljs-ln-numbers tr').forEach(row => { | |
| row.classList.remove('code-line-highlight'); | |
| const lineNum = row.querySelector('.hljs-ln-line').getAttribute('data-line-number'); | |
| if (lineNum == lineNumber) { | |
| row.classList.add('code-line-highlight'); | |
| row.scrollIntoView({ behavior: 'smooth', block: 'center' }); | |
| } | |
| }); | |
| } | |
| // Scroll to highlighted text in requirements | |
| function scrollToHighlight(subtabId, paragraphIndex) { | |
| const subtab = document.getElementById(subtabId); | |
| if (subtab) { | |
| const paragraphs = subtab.querySelectorAll('p'); | |
| if (paragraphs.length >= paragraphIndex) { | |
| paragraphs[paragraphIndex - 1].scrollIntoView({ behavior: 'smooth', block: 'center' }); | |
| // Flash the highlighted paragraph | |
| paragraphs[paragraphIndex - 1].style.backgroundColor = '#fee2e2'; | |
| setTimeout(() => { | |
| paragraphs[paragraphIndex - 1].style.backgroundColor = ''; | |
| }, 2000); | |
| } | |
| } | |
| } | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=capta1n/projectdetail7-0" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |