需要允许当前页面弹报告窗,修改your-api-key
// ==UserScript==
// @name DeepSeek页面Vuln分析
// @namespace http://tampermonkey.net/
// @version 0.1
// @description 将当前页面资源提交到DeepSeek API进行安全分析
// @author Trae AI
// @match *://*/*
// @grant GM_xmlhttpRequest
// @grant GM_setValue
// @grant GM_getValue
// @connect api.deepseek.com
// ==/UserScript==
(function() {
'use strict';
// 配置区域
const API_KEY = 'you-api-key';
const API_ENDPOINT = 'https://api.deepseek.com/v1/chat/completions'; // 调整为实际存在的API路径
// 创建分析按钮
// 在createUI函数中添加动画样式
function createUI() {
const btn = document.createElement('button');
btn.style.position = 'fixed';
btn.style.right = '20px';
btn.style.bottom = '20px';
// 新增样式代码
btn.style.padding = '12px 24px';
btn.style.background = 'linear-gradient(135deg, #4299e1, #3182ce)';
btn.style.color = 'white';
btn.style.border = 'none';
btn.style.borderRadius = '25px';
btn.style.fontSize = '16px';
btn.style.fontWeight = '600';
btn.style.cursor = 'pointer';
btn.style.boxShadow = '0 4px 6px rgba(0, 0, 0, 0.1)';
btn.style.transition = 'all 0.3s ease';
// 悬停效果
btn.onmouseover = () => {
btn.style.transform = 'translateY(-2px)';
btn.style.boxShadow = '0 6px 8px rgba(0, 0, 0, 0.2)';
}
btn.onmouseout = () => {
btn.style.transform = 'translateY(0)';
btn.style.boxShadow = '0 4px 6px rgba(0, 0, 0, 0.1)';
}
// 保持原有点击事件
btn.textContent = '🔍 分析页面缺陷';
btn.onclick = collectPageData;
document.body.appendChild(btn);
// 新增点击状态管理
btn.addEventListener('click', function(e) {
e.target.innerHTML = `
<div class="loader">
<svg class="spinner" viewBox="0 0 50 50">
<circle class="path" cx="25" cy="25" r="20" fill="none" stroke-width="5"></circle>
</svg>
</div>
正在扫描...
`;
e.target.disabled = true;
});
// 添加SVG加载动画样式
const style = document.createElement('style');
style.textContent = `
.loader {
display: inline-flex;
align-items: center;
gap: 8px;
}
.spinner {
animation: rotate 2s linear infinite;
height: 20px;
width: 20px;
}
.path {
stroke: #ffffff;
stroke-linecap: round;
animation: dash 1.5s ease-in-out infinite;
}
@keyframes rotate { 100% { transform: rotate(360deg); } }
@keyframes dash {
0% { stroke-dasharray: 1,150; stroke-dashoffset: 0; }
50% { stroke-dasharray: 90,150; stroke-dashoffset: -35; }
100% { stroke-dasharray: 90,150; stroke-dashoffset: -124; }
}
`;
document.head.appendChild(style);
}
// 收集页面数据
// 修改后的收集函数
async function collectPageData(event) {
const btn = event.target;
const fileTypes = ['html', 'htm', 'js', 'css', 'jsp', 'php', 'py', 'xml', 'json'];
try {
const pageContent = {
html: document.documentElement.outerHTML,
resources: []
};
// 通用资源收集器
const collectors = Array.from(document.querySelectorAll('script[src], link[href], img[src]'))
.map(async element => {
const url = element.src || element.href;
const ext = url.split('.').pop().toLowerCase();
if (fileTypes.includes(ext)) {
try {
const response = await fetch(url);
return {
type: ext,
content: await response.text(),
url: url
};
} catch (e) {
console.warn(`加载失败: ${url}`);
return null;
}
}
return null;
});
// 等待所有资源加载
const results = await Promise.all(collectors);
pageContent.resources = results.filter(r => r !== null);
// 发送数据并恢复按钮
sendToDeepSeek(pageContent, () => {
btn.innerHTML = '🔍 分析页面缺陷';
btn.disabled = false;
});
} catch (error) {
console.error('收集错误:', error);
btn.innerHTML = '🔍 分析页面缺陷';
btn.disabled = false;
}
}
// 修改后的发送函数
function sendToDeepSeek(data, callback) {
// 构建标准API请求格式
const requestData = {
model: "deepseek-reasoner",
messages: [{
role: "user",
content: `安全分析请求:请分析以下网页安全状况:
URL: ${window.location.href}
主HTML片段: ${data.html.substring(0, 3000)}
关联资源: ${data.resources.map(r => `
[${r.type.toUpperCase()}] ${r.url}
内容片段: ${r.content.substring(0, 500)}`).join('\n')}`
}],
temperature: 0.3
};
GM_xmlhttpRequest({
method: 'POST',
url: API_ENDPOINT,
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${API_KEY}`
},
data: JSON.stringify(requestData),
onload: function(response) {
callback();
// 创建专业报告窗口
const reportWindow = window.open('', '_blank', 'width=1000,height=800');
const reportContent = `
<html>
<head>
<title>DeepSeek安全报告 - ${window.location.hostname}</title>
<style>
body {
font-family: 'Segoe UI', system-ui;
margin: 0;
padding: 2rem;
background: #f8fafc;
}
.header {
background: linear-gradient(135deg, #3182ce, #63b3ed);
color: white;
padding: 2rem;
border-radius: 1rem;
margin-bottom: 2rem;
}
.vuln-card {
background: white;
border-radius: 0.5rem;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
padding: 1.5rem;
margin-bottom: 1rem;
}
.severity {
display: inline-block;
padding: 0.25rem 0.75rem;
border-radius: 1rem;
font-weight: 600;
margin-right: 1rem;
}
// 在报告窗口的<style>中添加
.risk-badge {
padding: 8px 20px;
border-radius: 20px;
font-weight: 600;
margin: 15px 0;
}
.critical { background: #ff4757; color: white; }
.medium { background: #ffa502; color: white; }
.analysis-card {
background: white;
border-radius: 8px;
padding: 20px;
margin: 15px 0;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.risk-item {
padding: 10px;
margin: 8px 0;
background: #fff9f9;
border-left: 3px solid #ff4757;
}
.reasoning-content {
background: #f8f9fa;
padding: 15px;
border-radius: 8px;
margin-top: 10px;
}
.metadata-section {
margin-top: 25px;
padding: 15px;
background: #f1f3f5;
border-radius: 8px;
}
pre {
background: #1a202c;
color: #cbd5e0;
padding: 1rem;
border-radius: 0.5rem;
overflow-x: auto;
}
</style>
</head>
<body>
<div class="header">
<h1>🔒 安全分析报告</h1>
<p>目标网址:${window.location.href}</p>
<p>扫描时间:${new Date().toLocaleString()}</p>
</div>
${formatApiResponse(response.responseText)}
</body>
</html>
`;
reportWindow.document.write(reportContent);
reportWindow.document.close();
}
});
}
// 新增响应格式化函数
function formatApiResponse(jsonResponse) {
try {
const result = JSON.parse(jsonResponse);
console.log('[DEBUG] API完整响应:', JSON.stringify(result, null, 2));
// 解析核心内容
const analysisContent = result.choices[0]?.message?.content || "无分析内容";
const reasoning = result.choices[0]?.message?.reasoning_content || "";
// 转换Markdown为HTML
const convertMarkdown = (text) => {
return text
.replace(/### (.*?)\n/g, '<h3>$1</h3>')
.replace(/#### (.*?)\n/g, '<h4>$1</h4>')
.replace(/`([^`]+)`/g, '<code>$1</code>')
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
.replace(/(\d+\.\s.*?)(?=\n\d+\.|\n$)/gs, (_, item) =>
`<li class="risk-item">${item.replace(/\d+\.\s/, '')}</li>`)
.replace(/```(\w+)?\n([\s\S]*?)```/g, (_, lang, code) =>
`<pre><code class="language-${lang || ''}">${code}</code></pre>`);
};
// 构建报告主体
return `
<div class="report-container">
<div class="header-section">
<h2>🛡️ 综合安全评级</h2>
${analysisContent.includes('高风险') ?
'<div class="risk-badge critical">高风险</div>' :
'<div class="risk-badge medium">中等风险</div>'}
</div>
<div class="analysis-section">
${convertMarkdown(analysisContent).split('\n\n').map(section => `
<div class="analysis-card">
${section.includes('<h3>') ? section : `<p>${section}</p>`}
</div>
`).join('')}
</div>
${reasoning ? `
<div class="reasoning-section">
<h3>🧠 分析过程</h3>
<div class="reasoning-content">${convertMarkdown(reasoning)}</div>
</div>` : ''}
<div class="metadata-section">
<h4>🔧 技术参数</h4>
<p>模型版本: ${result.model}</p>
<p>请求ID: ${result.id}</p>
<p>Tokens用量: ${result.usage?.total_tokens || '未知'}</p>
</div>
</div>
`;
} catch (e) {
console.error('[ERROR] 响应解析失败:', e);
return `<div class="error-card">
<h3>⚠️ 报告解析错误</h3>
<pre>${jsonResponse.substring(0, 2000)}</pre>
</div>`;
}
}
// 初始化
window.addEventListener('load', () => {
GM_setValue('api_key', API_KEY);
createUI();
});
})();