projectdetail3-0 / index.html
capta1n's picture
Add 3 files
88b7531 verified
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>风险项目告警系统</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/mermaid@10/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">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/codemirror.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/codemirror.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/javascript/javascript.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/sql/sql.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/xml/xml.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/clike/clike.min.js"></script>
<style>
.risk-highlight {
background-color: #fef3c7;
padding: 2px 4px;
border-radius: 4px;
font-weight: 500;
cursor: pointer;
}
.risk-highlight:hover {
background-color: #fde68a;
}
.architecture-diagram {
border: 1px solid #e5e7eb;
border-radius: 0.5rem;
overflow: auto;
background-color: white;
}
.threat-model {
height: 400px;
border: 1px solid #e5e7eb;
border-radius: 0.5rem;
background-color: white;
}
.attack-animation {
position: relative;
height: 300px;
background-color: #f8fafc;
border-radius: 0.5rem;
overflow: hidden;
}
.attack-path {
position: absolute;
height: 2px;
background-color: #3b82f6;
top: 50%;
left: 0;
width: 0;
transition: width 1s ease-in-out;
}
.attack-point {
position: absolute;
width: 16px;
height: 16px;
border-radius: 50%;
background-color: #ef4444;
top: 50%;
transform: translateY(-50%);
opacity: 0;
transition: opacity 0.5s ease-in-out;
}
.threat-node {
cursor: pointer;
transition: all 0.3s ease;
}
.threat-node:hover {
transform: scale(1.05);
}
.flow-diagram {
position: relative;
height: 300px;
background-color: #f8fafc;
border-radius: 0.5rem;
margin: 2rem 0;
}
.flow-line {
position: absolute;
height: 2px;
background-color: #3b82f6;
top: 50%;
left: 0;
right: 0;
transform: translateY(-50%);
}
.flow-node {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 80px;
height: 80px;
border-radius: 50%;
background-color: white;
border: 2px solid #3b82f6;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}
.flow-arrow {
position: absolute;
top: 50%;
right: -10px;
width: 0;
height: 0;
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
border-left: 10px solid #3b82f6;
transform: translateY(-50%);
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
}
.payload-block {
font-family: monospace;
background-color: #1e293b;
color: #f8fafc;
padding: 1rem;
border-radius: 0.5rem;
margin-bottom: 1rem;
}
.CodeMirror {
height: 400px;
border: 1px solid #e5e7eb;
border-radius: 0.5rem;
}
.file-tree {
border-right: 1px solid #e5e7eb;
height: 400px;
overflow-y: auto;
}
.file-item {
padding: 0.5rem 1rem;
cursor: pointer;
border-radius: 0.25rem;
}
.file-item:hover {
background-color: #f3f4f6;
}
.file-item.active {
background-color: #e0e7ff;
color: #4f46e5;
}
.risk-line {
background-color: #fee2e2;
}
.risk-marker {
position: absolute;
left: 0;
width: 10px;
background-color: #ef4444;
}
.gantt-bar {
height: 20px;
border-radius: 4px;
margin-bottom: 0.5rem;
}
.gantt-bar.completed {
background-color: #10b981;
}
.gantt-bar.pending {
background-color: #f59e0b;
}
.gantt-bar.failed {
background-color: #ef4444;
}
.markdown-content {
max-height: 500px;
overflow-y: auto;
padding: 1rem;
border: 1px solid #e5e7eb;
border-radius: 0.5rem;
}
.markdown-content h1,
.markdown-content h2,
.markdown-content h3 {
margin-top: 1rem;
margin-bottom: 0.5rem;
font-weight: bold;
}
.markdown-content h1 {
font-size: 1.5rem;
border-bottom: 1px solid #e5e7eb;
padding-bottom: 0.3rem;
}
.markdown-content h2 {
font-size: 1.3rem;
}
.markdown-content h3 {
font-size: 1.1rem;
}
.markdown-content p {
margin-bottom: 1rem;
}
.markdown-content ul,
.markdown-content ol {
margin-left: 1.5rem;
margin-bottom: 1rem;
}
.markdown-content pre {
background-color: #f3f4f6;
padding: 1rem;
border-radius: 0.5rem;
overflow-x: auto;
margin-bottom: 1rem;
}
.markdown-content code {
background-color: #f3f4f6;
padding: 0.2rem 0.4rem;
border-radius: 0.25rem;
font-family: monospace;
}
.sidebar {
width: 250px;
border-right: 1px solid #e5e7eb;
overflow-y: auto;
}
.sidebar-item {
padding: 0.5rem 1rem;
cursor: pointer;
border-radius: 0.25rem;
}
.sidebar-item:hover {
background-color: #f3f4f6;
}
.sidebar-item.active {
background-color: #e0e7ff;
color: #4f46e5;
}
</style>
</head>
<body class="bg-gray-50">
<div class="flex h-screen overflow-hidden">
<!-- 侧边栏 -->
<div class="sidebar bg-white">
<div class="p-4 border-b border-gray-200">
<h2 class="text-lg font-semibold text-gray-800">风险项目</h2>
</div>
<div class="p-2">
<div class="sidebar-item active">
<i class="fas fa-project-diagram mr-2"></i>
<span>支付宝国补项目</span>
</div>
<div class="sidebar-item">
<i class="fas fa-project-diagram mr-2"></i>
<span>微信支付商户平台</span>
</div>
<div class="sidebar-item">
<i class="fas fa-project-diagram mr-2"></i>
<span>银行核心系统</span>
</div>
</div>
</div>
<!-- 主内容区 -->
<div class="flex-1 flex flex-col overflow-hidden">
<!-- 顶部导航 -->
<header class="bg-white shadow-sm z-10">
<div class="px-6 py-4 flex items-center justify-between">
<h1 class="text-xl font-semibold text-gray-800">风险项目告警系统</h1>
<div class="flex items-center space-x-4">
<button id="riskProjectsBtn" class="flex items-center space-x-2 bg-indigo-50 text-indigo-600 px-4 py-2 rounded-lg hover:bg-indigo-100 transition">
<i class="fas fa-exclamation-triangle"></i>
<span>风险项目</span>
</button>
<div class="relative">
<img src="https://randomuser.me/api/portraits/women/44.jpg" alt="User" class="w-10 h-10 rounded-full cursor-pointer">
</div>
</div>
</div>
</header>
<!-- 主内容 -->
<main class="flex-1 overflow-auto p-6">
<!-- 项目详情 -->
<div id="projectDetail" class="bg-white rounded-xl shadow-sm p-6">
<div class="flex items-center justify-between mb-6">
<div>
<h2 class="text-2xl font-bold text-gray-800">支付宝国补项目</h2>
<p class="text-gray-500">最后更新时间: 2023-06-15 14:30</p>
</div>
<div class="flex space-x-2">
<span class="px-3 py-1 bg-red-100 text-red-800 rounded-full text-sm font-medium">高风险</span>
<span class="px-3 py-1 bg-yellow-100 text-yellow-800 rounded-full text-sm font-medium">越权</span>
<span class="px-3 py-1 bg-yellow-100 text-yellow-800 rounded-full text-sm font-medium">SQL注入</span>
</div>
</div>
<!-- 选项卡导航 -->
<div class="border-b border-gray-200 mb-6">
<nav class="-mb-px flex space-x-8">
<button data-tab="requirements" class="tab-btn whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm border-indigo-500 text-indigo-600">需求</button>
<button data-tab="code" class="tab-btn whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300">代码</button>
<button data-tab="testing" class="tab-btn whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300">安全测试</button>
<button data-tab="release" class="tab-btn whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300">发布</button>
<button data-tab="production" class="tab-btn whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300">线上</button>
</nav>
</div>
<!-- 需求分析内容 -->
<div id="requirements" class="tab-content active">
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<!-- 侧边栏目录 -->
<div class="sidebar lg:col-span-1">
<div class="p-4 border-b border-gray-200">
<h3 class="font-medium text-gray-700">需求文档目录</h3>
</div>
<div class="p-2">
<div class="sidebar-item active" onclick="scrollToSection('section1')">
<i class="fas fa-file-alt mr-2"></i>
<span>项目概述</span>
</div>
<div class="sidebar-item" onclick="scrollToSection('section2')">
<i class="fas fa-file-alt mr-2"></i>
<span>功能需求</span>
</div>
<div class="sidebar-item" onclick="scrollToSection('section3')">
<i class="fas fa-file-alt mr-2"></i>
<span>技术架构</span>
</div>
<div class="sidebar-item" onclick="scrollToSection('section4')">
<i class="fas fa-file-alt mr-2"></i>
<span>安全要求</span>
</div>
</div>
</div>
<!-- 需求文档内容 -->
<div class="lg:col-span-2">
<div class="markdown-content">
<h1 id="section1">支付宝国补项目需求文档</h1>
<h2 id="section2">项目概述</h2>
<p>支付宝国补项目旨在为政府补贴资金发放提供数字化解决方案,通过支付宝平台实现补贴资金的精准发放和管理。</p>
<p><span class="risk-highlight" onclick="highlightRisk('risk1')">项目涉及用户身份认证、补贴资格审核、资金发放、使用监控等多个环节。</span>系统需要与政府数据库对接获取补贴人员名单,并通过支付宝账户完成资金发放。</p>
<h2>功能需求</h2>
<ul>
<li>用户注册与身份认证</li>
<li>补贴资格自动审核</li>
<li>资金批量发放</li>
<li>资金使用监控</li>
<li>监管报表生成</li>
</ul>
<h2 id="section3">技术架构</h2>
<p>技术架构采用微服务设计,主要包含以下组件:用户服务、认证服务、补贴审核服务、资金发放服务、监控服务。</p>
<p><span class="risk-highlight" onclick="highlightRisk('risk2')">用户服务负责处理用户注册、登录和个人信息管理。认证服务对接政府数据库验证用户补贴资格。</span>补贴审核服务处理补贴申请和审批流程。</p>
<!-- 技术架构图 -->
<div class="architecture-diagram p-4 my-4">
<div class="mermaid">
graph TD
A[用户端] --> B[API Gateway]
B --> C[用户服务]
B --> D[认证服务]
B --> E[补贴审核服务]
B --> F[资金发放服务]
B --> G[监控服务]
C --> H[MySQL集群]
D --> I[政府数据库]
E --> H
F --> J[支付宝接口]
G --> K[Redis缓存]
G --> L[监管报表]
</div>
</div>
<h2 id="section4">安全要求</h2>
<p>系统预计日处理交易量100万笔,峰值QPS要求达到500。数据存储采用MySQL集群和Redis缓存。</p>
<p><span class="risk-highlight" onclick="highlightRisk('risk3')">安全要求包括:用户身份严格验证、补贴资格防篡改、资金发放防重放、敏感数据加密存储。</span></p>
<p>项目计划开发周期3个月,测试周期1个月,预计2023年9月上线。</p>
</div>
</div>
</div>
<!-- 分析结果 -->
<div class="mt-8">
<h3 class="text-lg font-medium text-gray-900 mb-4">安全分析结果</h3>
<!-- STRIDE威胁建模 -->
<div class="mb-8">
<h4 class="font-medium text-gray-700 mb-2">STRIDE威胁建模</h4>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div class="threat-model p-4" id="threatModel">
<!-- 交互式威胁建模图将通过JavaScript动态生成 -->
</div>
<div>
<div class="bg-gray-50 p-4 rounded-lg h-full">
<h4 class="font-medium text-gray-700 mb-3">威胁分析结果</h4>
<div id="threatDetail" class="text-sm text-gray-700">
<p class="text-gray-500 italic">点击左侧图中的组件查看详细威胁分析</p>
</div>
</div>
</div>
</div>
</div>
<!-- 安全风险分析 -->
<div>
<h4 class="font-medium text-gray-700 mb-2">安全风险分析</h4>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">业务场景</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">风险点</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">风险类型</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">整改建议</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
<tr>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">补贴资格审核</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">认证服务未验证调用方身份</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">越权访问</td>
<td class="px-6 py-4 text-sm text-gray-900">增加服务间认证机制,使用双向TLS或JWT验证</td>
</tr>
<tr>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">资金发放</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">发放请求参数未过滤</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">SQL注入</td>
<td class="px-6 py-4 text-sm text-gray-900">使用参数化查询或ORM框架,对输入参数进行严格验证</td>
</tr>
<tr>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">用户信息管理</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">敏感数据未加密存储</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">数据泄露</td>
<td class="px-6 py-4 text-sm text-gray-900">对身份证号等敏感信息进行加密存储,使用AES-256算法</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- 代码模块内容 -->
<div id="code" class="tab-content">
<div class="grid grid-cols-1 lg:grid-cols-4 gap-6">
<!-- 文件树 -->
<div class="file-tree lg:col-span-1">
<div class="p-4 border-b border-gray-200">
<h3 class="font-medium text-gray-700">代码目录</h3>
</div>
<div class="p-2">
<div class="file-item active" onclick="loadCodeFile('file1')">
<i class="fas fa-file-code mr-2"></i>
<span>UserService.java</span>
</div>
<div class="file-item" onclick="loadCodeFile('file2')">
<i class="fas fa-file-code mr-2"></i>
<span>AuthService.java</span>
</div>
<div class="file-item" onclick="loadCodeFile('file3')">
<i class="fas fa-file-code mr-2"></i>
<span>SubsidyService.java</span>
</div>
<div class="file-item" onclick="loadCodeFile('file4')">
<i class="fas fa-file-code mr-2"></i>
<span>PaymentService.java</span>
</div>
</div>
</div>
<!-- 代码编辑器 -->
<div class="lg:col-span-2">
<div class="mb-4">
<h3 class="font-medium text-gray-700">代码内容</h3>
</div>
<textarea id="codeEditor" class="hidden">
// UserService.java
public class UserService {
public User getUserById(String userId) {
// 风险点: SQL注入漏洞
String sql = "SELECT * FROM users WHERE id = '" + userId + "'";
return jdbcTemplate.queryForObject(sql, User.class);
}
public void updateUser(User user) {
// 风险点: 敏感数据未加密
String sql = "UPDATE users SET name=?, id_card=?, phone=? WHERE id=?";
jdbcTemplate.update(sql, user.getName(), user.getIdCard(), user.getPhone(), user.getId());
}
// 风险点: 越权访问
public void deleteUser(String userId, String currentUserId) {
if (userId.equals(currentUserId)) {
String sql = "DELETE FROM users WHERE id = ?";
jdbcTemplate.update(sql, userId);
}
}
}</textarea>
<div id="codeMirrorEditor"></div>
</div>
<!-- 漏洞列表 -->
<div class="lg:col-span-1">
<div class="mb-4">
<h3 class="font-medium text-gray-700">安全漏洞</h3>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<div class="mb-4">
<h4 class="font-medium text-gray-700 mb-2">SQL注入</h4>
<p class="text-sm text-gray-600 mb-1">影响代码行: 4-5行</p>
<p class="text-sm text-gray-600 mb-2">直接拼接SQL语句,可能导致SQL注入攻击</p>
<button onclick="highlightCodeLines(4, 5)" class="text-xs bg-blue-100 text-blue-800 px-2 py-1 rounded hover:bg-blue-200">定位代码</button>
</div>
<div class="mb-4">
<h4 class="font-medium text-gray-700 mb-2">敏感数据泄露</h4>
<p class="text-sm text-gray-600 mb-1">影响代码行: 9-10行</p>
<p class="text-sm text-gray-600 mb-2">身份证号等敏感信息未加密存储</p>
<button onclick="highlightCodeLines(9, 10)" class="text-xs bg-blue-100 text-blue-800 px-2 py-1 rounded hover:bg-blue-200">定位代码</button>
</div>
<div>
<h4 class="font-medium text-gray-700 mb-2">越权访问</h4>
<p class="text-sm text-gray-600 mb-1">影响代码行: 13-16行</p>
<p class="text-sm text-gray-600 mb-2">权限检查不充分,可能允许用户删除其他用户</p>
<button onclick="highlightCodeLines(13, 16)" class="text-xs bg-blue-100 text-blue-800 px-2 py-1 rounded hover:bg-blue-200">定位代码</button>
</div>
</div>
</div>
</div>
</div>
<!-- 安全测试内容 -->
<div id="testing" class="tab-content">
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- 攻击流程图 -->
<div>
<h3 class="text-lg font-medium text-gray-900 mb-4">攻击流程图</h3>
<div class="flow-diagram">
<div class="flow-line"></div>
<!-- 攻击节点 -->
<div class="flow-node" style="left: 10%;">
<i class="fas fa-user-secret text-red-500 text-xl"></i>
</div>
<div class="flow-arrow"></div>
<div class="flow-node" style="left: 30%;">
<i class="fas fa-globe text-blue-500 text-xl"></i>
</div>
<div class="flow-arrow"></div>
<div class="flow-node" style="left: 50%;">
<i class="fas fa-server text-green-500 text-xl"></i>
</div>
<div class="flow-arrow"></div>
<div class="flow-node" style="left: 70%;">
<i class="fas fa-database text-purple-500 text-xl"></i>
</div>
<div class="flow-arrow"></div>
<div class="flow-node" style="left: 90%;">
<i class="fas fa-file-invoice-dollar text-yellow-500 text-xl"></i>
</div>
<!-- 标签 -->
<div class="absolute top-1/4 left-10% text-center text-xs font-medium">
<p>攻击者</p>
</div>
<div class="absolute top-1/4 left-30% text-center text-xs font-medium">
<p>API接口</p>
</div>
<div class="absolute top-1/4 left-50% text-center text-xs font-medium">
<p>业务服务</p>
</div>
<div class="absolute top-1/4 left-70% text-center text-xs font-medium">
<p>数据库</p>
</div>
<div class="absolute top-1/4 left-90% text-center text-xs font-medium">
<p>敏感数据</p>
</div>
</div>
</div>
<!-- 攻击步骤 -->
<div>
<h3 class="text-lg font-medium text-gray-900 mb-4">攻击步骤</h3>
<div class="bg-gray-50 p-4 rounded-lg">
<ol class="list-decimal pl-5 space-y-3 text-sm text-gray-700">
<li class="font-medium">
<span class="text-red-600">侦察阶段</span>
<p class="mt-1 font-normal">攻击者通过Burp Suite等工具拦截正常API请求,分析接口参数和响应结构</p>
</li>
<li class="font-medium">
<span class="text-red-600">武器化</span>
<p class="mt-1 font-normal">构造恶意SQL注入Payload: <code class="bg-gray-200 px-1 rounded">12345' OR 1=1;--</code></p>
</li>
<li class="font-medium">
<span class="text-red-600">攻击交付</span>
<p class="mt-1 font-normal">通过修改GET请求参数将Payload发送到补贴状态查询接口</p>
</li>
<li class="font-medium">
<span class="text-red-600">漏洞利用</span>
<p class="mt-1 font-normal">服务端未过滤参数直接拼接SQL语句,导致恶意查询被执行</p>
</li>
<li class="font-medium">
<span class="text-red-600">数据窃取</span>
<p class="mt-1 font-normal">数据库返回所有用户补贴信息,攻击者获取敏感数据</p>
</li>
</ol>
</div>
</div>
</div>
<!-- Payload展示 -->
<div class="mt-8 grid grid-cols-1 lg:grid-cols-2 gap-6">
<div>
<h3 class="text-lg font-medium text-gray-900 mb-4">攻击Payload</h3>
<div class="space-y-4">
<div>
<h4 class="font-medium text-gray-700 mb-2">SQL注入攻击</h4>
<div class="payload-block">
GET /api/subsidy/status/12345%27%20OR%201%3D1%3B-- HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
</div>
<button onclick="copyToClipboard('GET /api/subsidy/status/12345%27%20OR%201%3D1%3B-- HTTP/1.1\nHost: api.example.com\nAuthorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...')" class="text-sm bg-gray-200 text-gray-800 px-3 py-1 rounded hover:bg-gray-300">
<i class="fas fa-copy mr-1"></i>复制Payload
</button>
</div>
<div>
<h4 class="font-medium text-gray-700 mb-2">越权攻击</h4>
<div class="payload-block">
POST /api/subsidy/distribute HTTP/1.1
Host: api.example.com
Content-Type: application/json
{
"userId": "67890",
"amount": 1000
}
</div>
<button onclick="copyToClipboard('POST /api/subsidy/distribute HTTP/1.1\nHost: api.example.com\nContent-Type: application/json\n\n{\n \"userId\": \"67890\",\n \"amount\": 1000\n}')" class="text-sm bg-gray-200 text-gray-800 px-3 py-1 rounded hover:bg-gray-300">
<i class="fas fa-copy mr-1"></i>复制Payload
</button>
</div>
</div>
</div>
<div>
<h3 class="text-lg font-medium text-gray-900 mb-4">Payload分析</h3>
<div class="bg-gray-50 p-4 rounded-lg h-full">
<div class="mb-4">
<h4 class="font-medium text-gray-700 mb-2">SQL注入Payload分析</h4>
<p class="text-sm text-gray-700">该Payload通过构造恶意userId参数,利用单引号闭合SQL语句,添加OR 1=1条件使查询始终返回真,从而绕过认证获取所有补贴数据。</p>
<div class="mt-3 bg-white p-3 rounded border border-gray-200">
<p class="text-xs text-gray-500">原始SQL:</p>
<p class="text-sm font-mono">SELECT * FROM subsidies WHERE user_id = 12345</p>
<p class="text-xs text-gray-500 mt-2">注入后SQL:</p>
<p class="text-sm font-mono">SELECT * FROM subsidies WHERE user_id = 12345 OR 1=1;--</p>
</div>
</div>
<div>
<h4 class="font-medium text-gray-700 mb-2">越权攻击Payload分析</h4>
<p class="text-sm text-gray-700">该Payload模拟管理员请求格式,尝试直接调用补贴发放接口。由于权限检查不充分,普通用户可能成功执行资金发放操作。</p>
</div>
</div>
</div>
</div>
<!-- 攻击演示 -->
<div class="mt-8">
<h3 class="text-lg font-medium text-gray-900 mb-4">攻击演示</h3>
<div class="bg-white p-6 rounded-lg shadow-sm">
<div class="attack-animation" id="attackAnimation">
<div class="attack-path" id="attackPath"></div>
<div class="attack-point" id="attackPoint1" style="left: 20%;"></div>
<div class="attack-point" id="attackPoint2" style="left: 40%;"></div>
<div class="attack-point" id="attackPoint3" style="left: 60%;"></div>
<div class="attack-point" id="attackPoint4" style="left: 80%;"></div>
<div class="absolute top-1/4 left-1/4 w-16 h-16 bg-white rounded-full shadow-md flex items-center justify-center border-2 border-gray-300">
<i class="fas fa-user-secret text-red-500"></i>
</div>
<div class="absolute top-1/4 left-2/4 w-16 h-16 bg-white rounded-full shadow-md flex items-center justify-center border-2 border-gray-300">
<i class="fas fa-server text-blue-500"></i>
</div>
<div class="absolute top-1/4 left-3/4 w-16 h-16 bg-white rounded-full shadow-md flex items-center justify-center border-2 border-gray-300">
<i class="fas fa-database text-green-500"></i>
</div>
<div class="absolute top-3/4 left-1/4 w-16 h-16 bg-white rounded-full shadow-md flex items-center justify-center border-2 border-gray-300">
<i class="fas fa-file-code text-purple-500"></i>
</div>
<div class="absolute top-3/4 left-3/4 w-16 h-16 bg-white rounded-full shadow-md flex items-center justify-center border-2 border-gray-300">
<i class="fas fa-file-invoice-dollar text-yellow-500"></i>
</div>
</div>
<div class="text-center mt-4">
<button id="startAttackBtn" class="px-4 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700">开始攻击演示</button>
</div>
</div>
</div>
<!-- 防御措施 -->
<div class="mt-8">
<h3 class="text-lg font-medium text-gray-900 mb-4">防御措施</h3>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
<div class="bg-white p-4 rounded-lg shadow-sm border border-gray-200">
<div class="text-blue-500 mb-2">
<i class="fas fa-shield-alt text-2xl"></i>
</div>
<h4 class="font-medium text-gray-700 mb-1">输入验证</h4>
<p class="text-sm text-gray-600">对所有输入参数进行严格验证,使用正则表达式限制输入格式</p>
</div>
<div class="bg-white p-4 rounded-lg shadow-sm border border-gray-200">
<div class="text-green-500 mb-2">
<i class="fas fa-lock text-2xl"></i>
</div>
<h4 class="font-medium text-gray-700 mb-1">参数化查询</h4>
<p class="text-sm text-gray-600">使用预编译语句或ORM框架,避免SQL拼接</p>
</div>
<div class="bg-white p-4 rounded-lg shadow-sm border border-gray-200">
<div class="text-purple-500 mb-2">
<i class="fas fa-user-lock text-2xl"></i>
</div>
<h4 class="font-medium text-gray-700 mb-1">权限控制</h4>
<p class="text-sm text-gray-600">实现基于角色的访问控制(RBAC),检查每个操作的权限</p>
</div>
<div class="bg-white p-4 rounded-lg shadow-sm border border-gray-200">
<div class="text-red-500 mb-2">
<i class="fas fa-bell text-2xl"></i>
</div>
<h4 class="font-medium text-gray-700 mb-1">WAF防护</h4>
<p class="text-sm text-gray-600">部署Web应用防火墙,拦截常见攻击模式</p>
</div>
</div>
</div>
</div>
<!-- 发布环节内容 -->
<div id="release" class="tab-content">
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- 修复追踪看板 -->
<div>
<h3 class="text-lg font-medium text-gray-900 mb-4">修复追踪看板</h3>
<div class="bg-white p-4 rounded-lg shadow-sm">
<div class="mb-4">
<h4 class="font-medium text-gray-700 mb-2">修复进度</h4>
<div class="gantt-bar completed" style="width: 80%;">
<div class="text-xs text-white pl-2">需求环节 (80%)</div>
</div>
<div class="gantt-bar pending" style="width: 60%;">
<div class="text-xs text-white pl-2">代码环节 (60%)</div>
</div>
<div class="gantt-bar failed" style="width: 30%;">
<div class="text-xs text-white pl-2">安全测试 (30%)</div>
</div>
</div>
<div>
<h4 class="font-medium text-gray-700 mb-2">未修复风险</h4>
<div class="space-y-2">
<div class="p-3 bg-red-50 rounded border border-red-200">
<div class="flex justify-between items-center">
<span class="font-medium text-red-800">SQL注入漏洞</span>
<button onclick="navigateToTab('code')" class="text-xs bg-red-100 text-red-800 px-2 py-1 rounded hover:bg-red-200">查看详情</button>
</div>
<p class="text-sm text-red-600 mt-1">代码环节 - UserService.java</p>
</div>
<div class="p-3 bg-red-50 rounded border border-red-200">
<div class="flex justify-between items-center">
<span class="font-medium text-red-800">越权访问</span>
<button onclick="navigateToTab('testing')" class="text-xs bg-red-100 text-red-800 px-2 py-1 rounded hover:bg-red-200">查看详情</button>
</div>
<p class="text-sm text-red-600 mt-1">安全测试环节 - 补贴发放接口</p>
</div>
</div>
</div>
</div>
</div>
<!-- 修复对比 -->
<div>
<h3 class="text-lg font-medium text-gray-900 mb-4">修复对比</h3>
<div class="bg-white p-4 rounded-lg shadow-sm">
<div class="mb-4">
<h4 class="font-medium text-gray-700 mb-2">代码修复对比</h4>
<div class="bg-gray-50 p-3 rounded border border-gray-200">
<div class="flex justify-between mb-2">
<span class="text-sm font-medium">UserService.java</span>
<div class="flex space-x-2">
<button class="text-xs bg-gray-200 text-gray-800 px-2 py-1 rounded hover:bg-gray-300">原始代码</button>
<button class="text-xs bg-blue-100 text-blue-800 px-2 py-1 rounded hover:bg-blue-200">修复后代码</button>
</div>
</div>
<pre class="text-sm bg-white p-2 rounded overflow-x-auto">
<span class="text-red-500">- public User getUserById(String userId) {
- String sql = "SELECT * FROM users WHERE id = '" + userId + "'";
- return jdbcTemplate.queryForObject(sql, User.class);
- }</span>
<span class="text-green-500">+ public User getUserById(String userId) {
+ String sql = "SELECT * FROM users WHERE id = ?";
+ return jdbcTemplate.queryForObject(sql, new Object[]{userId}, User.class);
+ }</span></pre>
</div>
</div>
<div>
<h4 class="font-medium text-gray-700 mb-2">安全检查结果</h4>
<div class="space-y-3">
<div class="flex items-center">
<div class="w-8 h-8 rounded-full bg-green-100 text-green-800 flex items-center justify-center mr-3">
<i class="fas fa-check"></i>
</div>
<div>
<p class="font-medium">需求环节威胁建模</p>
<p class="text-sm text-gray-600">所有威胁已评估并记录</p>
</div>
</div>
<div class="flex items-center">
<div class="w-8 h-8 rounded-full bg-yellow-100 text-yellow-800 flex items-center justify-center mr-3">
<i class="fas fa-exclamation"></i>
</div>
<div>
<p class="font-medium">代码静态分析</p>
<p class="text-sm text-gray-600">发现3个高危漏洞,2个已修复</p>
</div>
</div>
<div class="flex items-center">
<div class="w-8 h-8 rounded-full bg-red-100 text-red-800 flex items-center justify-center mr-3">
<i class="fas fa-times"></i>
</div>
<div>
<p class="font-medium">渗透测试</p>
<p class="text-sm text-gray-600">发现2个未修复漏洞</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 线上环节内容 -->
<div id="production" class="tab-content">
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- 线上事件 -->
<div>
<h3 class="text-lg font-medium text-gray-900 mb-4">线上安全事件</h3>
<div class="space-y-4">
<div class="bg-white p-4 rounded-lg shadow-sm border border-red-200">
<div class="flex justify-between items-center mb-2">
<span class="font-medium text-red-800">SQL注入攻击</span>
<span class="text-xs bg-red-100 text-red-800 px-2 py-1 rounded">2023-06-10</span>
</div>
<p class="text-sm text-gray-700 mb-2">攻击者利用补贴查询接口的SQL注入漏洞,获取了约5000条用户补贴记录。</p>
<div class="flex justify-between items-center">
<span class="text-xs text-gray-500">影响范围: 用户补贴数据</span>
<button onclick="navigateToTab('testing')" class="text-xs bg-red-100 text-red-800 px-2 py-1 rounded hover:bg-red-200">查看漏洞详情</button>
</div>
</div>
<div class="bg-white p-4 rounded-lg shadow-sm border border-yellow-200">
<div class="flex justify-between items-center mb-2">
<span class="font-medium text-yellow-800">越权发放补贴</span>
<span class="text-xs bg-yellow-100 text-yellow-800 px-2 py-1 rounded">2023-06-12</span>
</div>
<p class="text-sm text-gray-700 mb-2">攻击者利用权限检查缺陷,冒充管理员发放了3笔补贴,总计3000元。</p>
<div class="flex justify-between items-center">
<span class="text-xs text-gray-500">影响范围: 资金安全</span>
<button onclick="navigateToTab('testing')" class="text-xs bg-yellow-100 text-yellow-800 px-2 py-1 rounded hover:bg-yellow-200">查看漏洞详情</button>
</div>
</div>
</div>
</div>
<!-- 修复情况 -->
<div>
<h3 class="text-lg font-medium text-gray-900 mb-4">漏洞修复情况</h3>
<div class="bg-white p-4 rounded-lg shadow-sm">
<div class="mb-4">
<h4 class="font-medium text-gray-700 mb-2">SQL注入漏洞</h4>
<div class="flex items-center mb-2">
<span class="text-sm mr-3">修复状态:</span>
<span class="px-2 py-1 bg-green-100 text-green-800 rounded-full text-xs font-medium">已修复</span>
</div>
<p class="text-sm text-gray-700 mb-2">修复措施: 使用参数化查询重构补贴查询接口,增加输入验证。</p>
<p class="text-sm text-gray-700">修复时间: 2023-06-11 03:15</p>
</div>
<div>
<h4 class="font-medium text-gray-700 mb-2">越权访问</h4>
<div class="flex items-center mb-2">
<span class="text-sm mr-3">修复状态:</span>
<span class="px-2 py-1 bg-yellow-100 text-yellow-800 rounded-full text-xs font-medium">部分修复</span>
</div>
<p class="text-sm text-gray-700 mb-2">修复措施: 增加角色检查,但部分历史接口仍需更新。</p>
<p class="text-sm text-gray-700">预计完成: 2023-06-15</p>
</div>
</div>
</div>
</div>
<!-- 监控图表 -->
<div class="mt-8">
<h3 class="text-lg font-medium text-gray-900 mb-4">安全监控</h3>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<div class="bg-white p-4 rounded-lg shadow-sm border border-gray-200">
<div class="flex justify-between items-center mb-2">
<span class="font-medium text-gray-700">异常请求</span>
<span class="text-xs bg-blue-100 text-blue-800 px-2 py-1 rounded">今日: 42</span>
</div>
<div class="h-32 bg-gray-50 rounded flex items-center justify-center">
<p class="text-gray-500">请求频率监控图表</p>
</div>
</div>
<div class="bg-white p-4 rounded-lg shadow-sm border border-gray-200">
<div class="flex justify-between items-center mb-2">
<span class="font-medium text-gray-700">敏感操作</span>
<span class="text-xs bg-blue-100 text-blue-800 px-2 py-1 rounded">今日: 8</span>
</div>
<div class="h-32 bg-gray-50 rounded flex items-center justify-center">
<p class="text-gray-500">操作审计日志图表</p>
</div>
</div>
<div class="bg-white p-4 rounded-lg shadow-sm border border-gray-200">
<div class="flex justify-between items-center mb-2">
<span class="font-medium text-gray-700">漏洞扫描</span>
<span class="text-xs bg-blue-100 text-blue-800 px-2 py-1 rounded">上次: 2小时前</span>
</div>
<div class="h-32 bg-gray-50 rounded flex items-center justify-center">
<p class="text-gray-500">漏洞趋势图表</p>
</div>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
</div>
<script>
// 初始化Mermaid
mermaid.initialize({
startOnLoad: true,
theme: 'default',
flowchart: {
useMaxWidth: false,
htmlLabels: true
}
});
// 初始化代码编辑器
const codeEditor = CodeMirror.fromTextArea(document.getElementById('codeEditor'), {
mode: 'text/x-java',
lineNumbers: true,
theme: 'default',
readOnly: true,
gutters: ["CodeMirror-linenumbers", "risk-gutter"]
});
// 标记风险代码行
codeEditor.setOption('gutters', ["CodeMirror-linenumbers", "risk-gutter"]);
codeEditor.addLineClass(3, 'background', 'risk-line');
codeEditor.addLineClass(4, 'background', 'risk-line');
codeEditor.addLineClass(8, 'background', 'risk-line');
codeEditor.addLineClass(9, 'background', 'risk-line');
codeEditor.addLineClass(13, 'background', 'risk-line');
codeEditor.addLineClass(14, 'background', 'risk-line');
codeEditor.addLineClass(15, 'background', 'risk-line');
codeEditor.addLineClass(16, 'background', 'risk-line');
// 选项卡切换
const tabButtons = document.querySelectorAll('.tab-btn');
const tabContents = document.querySelectorAll('.tab-content');
tabButtons.forEach(button => {
button.addEventListener('click', () => {
const tabId = button.getAttribute('data-tab');
// 更新按钮状态
tabButtons.forEach(btn => {
btn.classList.remove('border-indigo-500', 'text-indigo-600');
btn.classList.add('border-transparent', 'text-gray-500');
});
button.classList.remove('border-transparent', 'text-gray-500');
button.classList.add('border-indigo-500', 'text-indigo-600');
// 更新内容显示
tabContents.forEach(content => {
content.classList.remove('active');
});
document.getElementById(tabId).classList.add('active');
});
});
// STRIDE威胁建模图交互
document.addEventListener('DOMContentLoaded', () => {
const threatModelContainer = document.getElementById('threatModel');
threatModelContainer.innerHTML = `
<div class="p-4">
<div class="text-center text-gray-500 mb-4">
<p>STRIDE威胁建模 - 点击组件节点查看风险详情</p>
</div>
<div class="relative h-64 bg-gray-100 rounded-lg">
<!-- 用户服务 -->
<div class="threat-node absolute top-1/4 left-1/4 w-16 h-16 bg-white rounded-full shadow-md flex items-center justify-center border-2 border-blue-300" onclick="showThreatDetail('用户服务', 'Spoofing', '缺乏强身份认证机制,可能被冒充')">
<span class="text-xs font-medium">用户服务</span>
</div>
<!-- 认证服务 -->
<div class="threat-node absolute top-1/4 right-1/4 w-16 h-16 bg-white rounded-full shadow-md flex items-center justify-center border-2 border-red-300" onclick="showThreatDetail('认证服务', 'Tampering', '认证令牌未签名,可能被篡改')">
<span class="text-xs font-medium">认证服务</span>
</div>
<!-- 补贴审核 -->
<div class="threat-node absolute bottom-1/3 left-1/3 w-16 h-16 bg-white rounded-full shadow-md flex items-center justify-center border-2 border-yellow-300" onclick="showThreatDetail('补贴审核', 'Repudiation', '操作日志不完整,无法追溯')">
<span class="text-xs font-medium">补贴审核</span>
</div>
<!-- 资金发放 -->
<div class="threat-node absolute bottom-1/3 right-1/3 w-16 h-16 bg-white rounded-full shadow-md flex items-center justify-center border-2 border-green-300" onclick="showThreatDetail('资金发放', 'Information Disclosure', '交易详情未加密,可能泄露')">
<span class="text-xs font-medium">资金发放</span>
</div>
<!-- 监控服务 -->
<div class="threat-node absolute top-1/2 left-1/2 w-16 h-16 bg-white rounded-full shadow-md flex items-center justify-center border-2 border-purple-300" onclick="showThreatDetail('监控服务', 'Denial of Service', '缺乏限流机制,可能被攻击')">
<span class="text-xs font-medium">监控服务</span>
</div>
<!-- 连接线 -->
<svg class="absolute inset-0 w-full h-full" xmlns="http://www.w3.org/2000/svg">
<!-- 用户服务 -> 认证服务 -->
<path d="M25% 25% L50% 25%" stroke="#3b82f6" stroke-width="2" fill="none" marker-end="url(#arrowhead)"/>
<!-- 认证服务 -> 补贴审核 -->
<path d="M75% 25% L75% 40% L50% 40% L50% 55%" stroke="#3b82f6" stroke-width="2" fill="none" marker-end="url(#arrowhead)"/>
<!-- 补贴审核 -> 资金发放 -->
<path d="M50% 55% L75% 55%" stroke="#3b82f6" stroke-width="2" fill="none" marker-end="url(#arrowhead)"/>
<!-- 资金发放 -> 监控服务 -->
<path d="M75% 55% L50% 55% L50% 65%" stroke="#3b82f6" stroke-width="2" fill="none" marker-end="url(#arrowhead)"/>
<defs>
<marker id="arrowhead" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="#3b82f6"/>
</marker>
</defs>
</svg>
</div>
</div>
`;
});
// 显示威胁详情函数
function showThreatDetail(component, threatType, threatDesc) {
const threatDetail = document.getElementById('threatDetail');
threatDetail.innerHTML = `
<div class="mb-3">
<h5 class="font-medium text-gray-700">组件名称</h5>
<p>${component}</p>
</div>
<div class="mb-3">
<h5 class="font-medium text-gray-700">威胁类型 (STRIDE)</h5>
<p class="text-red-600">${threatType}</p>
</div>
<div class="mb-3">
<h5 class="font-medium text-gray-700">威胁描述</h5>
<p>${threatDesc}</p>
</div>
<div>
<h5 class="font-medium text-gray-700">缓解措施</h5>
<ul class="list-disc pl-5 mt-1 text-sm">
<li>实现多因素身份验证</li>
<li>使用数字签名保护关键数据</li>
<li>完善审计日志记录</li>
</ul>
</div>
`;
}
// 攻击演示动画
document.getElementById('startAttackBtn').addEventListener('click', function() {
const attackPath = document.getElementById('attackPath');
const attackPoints = [
document.getElementById('attackPoint1'),
document.getElementById('attackPoint2'),
document.getElementById('attackPoint3'),
document.getElementById('attackPoint4')
];
// 重置状态
attackPath.style.width = '0';
attackPoints.forEach(point => point.style.opacity = '0');
// 开始动画
attackPath.style.width = '100%';
// 分步显示攻击点
setTimeout(() => {
attackPoints[0].style.opacity = '1';
}, 500);
setTimeout(() => {
attackPoints[1].style.opacity = '1';
}, 1000);
setTimeout(() => {
attackPoints[2].style.opacity = '1';
}, 1500);
setTimeout(() => {
attackPoints[3].style.opacity = '1';
}, 2000);
});
// 高亮风险点
function highlightRisk(riskId) {
// 这里可以添加高亮风险点的逻辑
alert(`高亮风险点: ${riskId}`);
}
// 滚动到文档部分
function scrollToSection(sectionId) {
const section = document.getElementById(sectionId);
if (section) {
section.scrollIntoView({ behavior: 'smooth' });
}
}
// 加载代码文件
function loadCodeFile(fileId) {
// 这里可以添加加载不同代码文件的逻辑
const fileItems = document.querySelectorAll('.file-item');
fileItems.forEach(item => item.classList.remove('active'));
event.currentTarget.classList.add('active');
// 模拟加载不同文件
let codeContent = '';
switch(fileId) {
case 'file1':
codeContent = `// UserService.java
public class UserService {
public User getUserById(String userId) {
// 风险点: SQL注入漏洞
String sql = "SELECT * FROM users WHERE id = '" + userId + "'";
return jdbcTemplate.queryForObject(sql, User.class);
}
public void updateUser(User user) {
// 风险点: 敏感数据未加密
String sql = "UPDATE users SET name=?, id_card=?, phone=? WHERE id=?";
jdbcTemplate.update(sql, user.getName(), user.getIdCard(), user.getPhone(), user.getId());
}
// 风险点: 越权访问
public void deleteUser(String userId, String currentUserId) {
if (userId.equals(currentUserId)) {
String sql = "DELETE FROM users WHERE id = ?";
jdbcTemplate.update(sql, userId);
}
}
}`;
break;
case 'file2':
codeContent = `// AuthService.java
public class AuthService {
public boolean verifyUser(String userId, String idCard) {
// 风险点: 未验证调用方身份
String govUrl = "http://gov-api/verify?id=" + userId + "&idCard=" + idCard;
return restTemplate.getForObject(govUrl, Boolean.class);
}
public String generateToken(User user) {
// 风险点: JWT未签名
return JWT.create()
.withClaim("userId", user.getId())
.withClaim("role", user.getRole())
.sign(Algorithm.none());
}
}`;
break;
case 'file3':
codeContent = `// SubsidyService.java
public class SubsidyService {
public List<Subsidy> getSubsidiesByUserId(String userId) {
// 风险点: SQL注入
String sql = "SELECT * FROM subsidies WHERE user_id = '" + userId + "'";
return jdbcTemplate.query(sql, new SubsidyRowMapper());
}
public void approveSubsidy(String subsidyId, String approverId) {
// 风险点: 未记录操作日志
String sql = "UPDATE subsidies SET status = 'APPROVED' WHERE id = ?";
jdbcTemplate.update(sql, subsidyId);
}
}`;
break;
case 'file4':
codeContent = `// PaymentService.java
public class PaymentService {
public void distributeSubsidy(String userId, BigDecimal amount) {
// 风险点: 未验证调用权限
String sql = "INSERT INTO payments (user_id, amount) VALUES (?, ?)";
jdbcTemplate.update(sql, userId, amount);
// 调用支付宝接口
alipayClient.transfer(userId, amount);
}
}`;
break;
}
codeEditor.setValue(codeContent);
// 标记风险代码行
codeEditor.eachLine(line => {
codeEditor.removeLineClass(line, 'background', 'risk-line');
});
if (fileId === 'file1') {
codeEditor.addLineClass(3, 'background', 'risk-line');
codeEditor.addLineClass(4, 'background', 'risk-line');
codeEditor.addLineClass(8, 'background', 'risk-line');
codeEditor.addLineClass(9, 'background', 'risk-line');
codeEditor.addLineClass(13, 'background', 'risk-line');
codeEditor.addLineClass(14, 'background', 'risk-line');
codeEditor.addLineClass(15, 'background', 'risk-line');
codeEditor.addLineClass(16, 'background', 'risk-line');
} else if (fileId === 'file2') {
codeEditor.addLineClass(3, 'background', 'risk-line');
codeEditor.addLineClass(4, 'background', 'risk-line');
codeEditor.addLineClass(9, 'background', 'risk-line');
codeEditor.addLineClass(10, 'background', 'risk-line');
codeEditor.addLineClass(11, 'background', 'risk-line');
} else if (fileId === 'file3') {
codeEditor.addLineClass(3, 'background', 'risk-line');
codeEditor.addLineClass(4, 'background', 'risk-line');
codeEditor.addLineClass(9, 'background', 'risk-line');
codeEditor.addLineClass(10, 'background', 'risk-line');
} else if (fileId === 'file4') {
codeEditor.addLineClass(3, 'background', 'risk-line');
codeEditor.addLineClass(4, 'background', 'risk-line');
codeEditor.addLineClass(7, 'background', 'risk-line');
}
}
// 高亮代码行
function highlightCodeLines(startLine, endLine) {
codeEditor.eachLine(line => {
codeEditor.removeLineClass(line, 'background', 'risk-line');
});
for (let i = startLine - 1; i < endLine; i++) {
codeEditor.addLineClass(i, 'background', 'risk-line');
}
codeEditor.scrollIntoView({line: startLine - 1, ch: 0}, 100);
}
// 复制到剪贴板
function copyToClipboard(text) {
navigator.clipboard.writeText(text).then(() => {
alert('Payload已复制到剪贴板');
}).catch(err => {
console.error('复制失败: ', err);
});
}
// 导航到指定选项卡
function navigateToTab(tabId) {
const tabButton = document.querySelector(`.tab-btn[data-tab="${tabId}"]`);
if (tabButton) {
tabButton.click();
}
}
// 初始化加载第一个代码文件
loadCodeFile('file1');
</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/projectdetail3-0" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>