GemSec MCP服务器
GemSec是一个模型上下文协议(MCP)工具,它扫描JavaScript/TypeScript代码库(Next.js/React-friendly)以查找常见的安全隐患,然后生成具有上下文片段、调试提示和深度链接的可操作CLI和HTML报告。
🚀 快速开始
在游标中配置(设置→ 特性→ MCP服务器):
"gemsec-local": {
"command": "npx",
"args": [
"-y",
"gemsec-security-analyzer-mcp@latest"
]
},就是这样!没有克隆,没有构建,没有手动设置。只需安装和使用。
主要特点
- 递归分析 –扫描单个文件或整个目录(跳过
node_modules、点文件夹和非JS/TS扩展)。 - 规则库 –检测XSS风险、缺少CSRF令牌、硬编码秘密、SQL注入模式、弱加密、不安全存储等(请参阅
src/config/securityPatterns.ts). - 丰富的报告
- 带有严重性标记、代码片段、VS代码深度链接和建议调试提示的终端输出。 - 样式化HTML报告(reports/security-report-*/index.html)在分析项目的根中生成。
- 最佳实践助手 –强化Next.js/RReact部署的快速参考指南。
安全模式
GemSec扫描JavaScript/TypeScript代码库中的14个常见安全漏洞。每个模式都是使用基于正则表达式的匹配来检测的,包括严重性分类、详细解释和可操作的建议。
图案概述
| 模式名称 | 严重性 | 描述 |
|---|---|---|
| XSS-eval() | 🔴 关键 | 检测使用 eval() 可以执行任意代码 |
| 硬编码的秘密 | 🔴 关键 | 查找源代码中硬编码的API密钥、密码、机密或令牌 |
| SQL注入风险 | 🔴 关键 | 识别存在字符串插值漏洞的SQL查询 |
| XSS-危险的SetInnerHTML | 🟠 High | 检测React组件中不安全的HTML注入 |
| 缺少输入验证 | 🟠 高 | 标记请求参数中未验证的用户输入 |
| CORS配置错误 | 🟠 高 | 查找配置为接受所有来源的CORS(*) |
| 缺少CSRF保护 | 🟠 高 | 检测没有CSRF令牌保护的表单 |
| 弱加密 | 🟠 高 | 标识弱哈希算法(MD5/SHA1)的使用 |
| 本地存储不安全 | 🟡 Medium | 标记使用localStorage进行敏感数据存储 |
| 不安全随机 | 🟡 Medium | 检测使用 Math.random() 用于安全敏感操作 |
| 不安全的HTTP | 🟡 Medium | 查找HTTP URL(应使用HTTPS) |
| 缺少安全标头 | 🟡 中等 | 检查丢失的CSP、X-Frame-Options或HSTS标头 |
| 不安全重定向 | 🟡 Medium | 检测未经URL验证的重定向 |
| 暴露的服务器信息 | 🔵 低 | 查找暴露服务器技术的X-Powered-By标头 |
详细图案说明
🔴 严重性
XSS-eval()
- 问题:
eval()将字符串作为JavaScript代码执行,允许任意代码执行 - 风险:如果输入来自不受信任的来源,则在浏览器或服务器中远程执行代码
- 推荐:避免
eval(),使用JSON.parse()或更安全的替代品
硬编码的秘密
- 问题:源代码中硬编码的API密钥、密码、机密或令牌
- 风险:存储库、构建工件或共享代码中暴露的秘密可被攻击者用来访问API、数据库或服务
- 推荐:使用环境变量(
.env)永远不要将秘密提交给版本控制
SQL注入风险
- 问题:使用字符串插值而不是参数化查询构造的SQL查询
- 风险:攻击者可以注入SQL代码来读取敏感数据、修改数据或在数据库服务器上执行远程代码
- 推荐:使用参数化查询或类似Prisma的ORM
🟠 高严重性
XSS-危险的SetInnerHTML
- 问题:React的
dangerouslySetInnerHTML允许直接将HTML注入DOM而无需净化 - 风险:如果内容来自用户输入或不受信任的来源,攻击者可以注入恶意脚本,导致cookie被盗、会话劫持或污损
- 推荐:使用DOMPurify进行HTML净化或完全避免innerHTML
缺少输入验证
- 问题:用户输入来自
req.body,req.query,或req.params未经验证使用 - 风险:可能导致注入攻击(SQL、NoSQL、Command)、类型混淆、缓冲区溢出或业务逻辑绕过
- 推荐:使用以下库验证所有输入
zod或joi
CORS配置错误
- 问题:CORS配置为接受所有来源(
*) - 风险:任何网站都可以向您的API发出经过身份验证的请求,从而启用CSRF攻击或未经授权的数据访问
- 推荐:仅将CORS限制为受信任的域
缺少CSRF保护
- 问题:没有CSRF令牌保护的表单
- 风险:攻击者可以代表经过身份验证的用户发出请求,在用户不知情的情况下执行更改密码或删除数据等操作
- 推荐:为所有形式的突变实施CSRF令牌
弱加密
- 问题:使用弱哈希算法(MD5/SHA1)
- 风险:易受碰撞攻击,密码哈希速度过快;攻击者可以使用彩虹表或暴力
- 推荐:使用bcrypt、scrypt或Argon2进行密码散列
🟡 中等严重性
本地存储不安全
- 问题:使用
localStorage用于存储敏感数据 - 风险:可由同一来源的JavaScript访问(包括XSS攻击);没有httpOnly保护;如果发生XSS,令牌可能会被盗
- 推荐:不要在localStorage中存储令牌或敏感数据;请改用httpOnly Cookie
不安全随机
- 问题:使用
Math.random()用于安全敏感操作 - 风险:伪随机数生成器是可预测的;攻击者可以猜测或预测令牌、会话ID或加密密钥的生成值
- 推荐:使用
crypto.randomBytes()或crypto.getRandomValues()出于安全考虑
不安全的HTTP
- 问题:使用HTTP URL而不是HTTPS
- 风险:以纯文本形式发送的数据;同一网络上的攻击者可以拦截、读取和修改通信,包括凭据和令牌
- 推荐:对所有通信使用HTTPS
缺少安全标头
- 问题:可能未配置重要的安全标头(CSP、X-Frame-Options、HSTS)
- 风险:更容易受到XSS、点击劫持和中间人攻击
- 推荐:实现CSP、X-Frame-Options和HSTS标头
不安全重定向
- 问题:重定向时不进行URL验证
- 风险:攻击者可以将用户重定向到恶意网站进行网络钓鱼或绕过安全控制
- 推荐:根据域白名单验证重定向URL
🔵 低严重性
暴露的服务器信息
- 问题:X-Powered-By标头公开服务器技术信息
- 风险:帮助攻击者在侦察过程中发现特定技术的漏洞
- 推荐:禁用X-Powered-By标头以尽量减少信息泄露
扩展安全模式
要添加新的安全模式,请编辑 src/config/securityPatterns.ts:
{
name: "Your Pattern Name",
pattern: /your-regex-pattern/g,
severity: "high" | "medium" | "low" | "critical",
message: "Brief description of the issue",
recommendation: "Actionable fix suggestion",
explanation: "Detailed explanation of the vulnerability and its risks"
}可用的MCP工具
| 工具名称 | 描述 | 参数 |
|---|---|---|
analyze_file | 扫描单个文件 | { "file_path": "/abs/path/to/file.tsx", "file_content"?: "..." } |
analyze_directory | 递归扫描文件夹中的JS/TS文件 | { "directory_path": "/abs/path/to/project", "files"?: [...] } |
get_security_best_practices | 返回精心策划的最佳实践清单 | 无 |
注: 对于远程MCP服务器,您可以提供 file_content (为 analyze_file)或 files 数组(for analyze_directory)直接发送文件内容,而不是从文件系统读取。
典型工作流程
- 启动MCP服务器
- 标准IO/CLI
node ./build/index.js- Express+SSE后端
npm start
# or: PORT=4000 node ./build/httpServer.js- 呼叫
analyze_directory
对于本地服务器:
{
"name": "analyze_directory",
"arguments": { "directory_path": "/Users/me/projects/test-project" }
}对于远程服务器(包含文件内容):
{
"name": "analyze_directory",
"arguments": {
"directory_path": "/Users/me/projects/test-project",
"files": [
{
"path": "/Users/me/projects/test-project/src/App.tsx",
"content": "// file content here..."
}
]
}
}- 打开HTML报告
- GemSec确定项目根(是否存在 package.json, .git, pnpm-workspace.yaml,或 yarn.lock)并根据以下内容撰写报告 /reports/security-report-*/. - CLI响应包括 index.html 路径加上每个发现的嵌入式VS代码链接。
IDE/光标集成
GemSec是一个MCP服务器,因此任何支持MCP的IDE(如Cursor)都可以直接调用它。
使用StdIO进行设置(手动/开发)
- 在Cursor中注册服务器
- 打开 Settings → Features → MCP Servers.
- 使用以下配置添加新的自定义服务器:
如果全局安装:
{
"mcpServers": {
"gemsec": {
"command": "gemsec-mcp"
}
}
}如果本地安装:
{
"mcpServers": {
"gemsec": {
"command": "npx",
"args": ["gemsec-mcp"]
}
}
}或者使用完整路径(如果需要):
{
"mcpServers": {
"gemsec": {
"command": "node",
"args": ["/absolute/path/to/node_modules/gemsec-mcp/build/index.js"]
}
}
}- 姓名: gemsec
- 保存;如果系统提示,请重新启动Cursor。
- 提示助手
- 提及GemSec或您想要的工具,例如“运行GemSec analyze_directory 上 src/features/log-activity“或”使用GemSec进行分析 FormAddNewUser.tsx." - 光标将显示GemSec工具(analyze_file, analyze_directory, get_security_best_practices)在工具选择器中。
- 处理结果
- 响应包括Markdown摘要和HTML路径。打开 index.html 在你的项目中(例如。 …/reports/security-report-*/index.html). - 使用VS代码 vscode://file/... 嵌入在文本或HTML报告中的链接可以直接跳转到相关行。
安装SSE(服务器发送事件)
要使用SSE传输,您需要先运行HTTP服务器,然后使用HTTP端点从客户端连接。
1.运行HTTP服务器
# Build the project first
npm run build
# Run HTTP server (default port 3030)
npm start
# Or with a custom port
PORT=8080 npm start服务器将在以下时间运行 http://localhost:3030 (或您指定的端口)。
2.验证服务器是否正在运行
# Test health endpoint
curl http://localhost:3030/healthz
# Response:
# {
# "status": "ok",
# "name": "GemSec",
# "transport": "sse"
# }3.连接流式HTTP客户端
流式HTTP传输使用一个同时处理GET和POST的端点:
- 获取/发布
/mcp-主要终点(现代标准)
- GET:打开SSE流(服务器→ 客户) - POST:向服务器(客户端)发送请求→ 服务器)
- 传统端点 (为了向后兼容性):
- 获取/发布 /sse -传统SSE端点 - 发布 /messages -传统消息端点
使用curl进行测试的示例:
# 1. Open SSE connection (will get sessionId from response headers)
curl -N http://localhost:3030/sse
# 2. In another terminal, send message (replace with ID from step 1)
curl -X POST http://localhost:3030/messages?sessionId= \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}'4.基于Web的MCP客户端配置
如果您使用的是支持SSE的基于web的MCP客户端,配置通常如下:
{
"mcpServers": {
"gemsec-streamable": {
"type": "streamable-http",
"url": "http://localhost:3030/mcp"
}
}
}对于远程部署(带身份验证):
{
"mcpServers": {
"gemsec-remote": {
"type": "streamable-http",
"url": "https://your-server.com/mcp",
"headers": {
"Authorization": "Bearer your-secret-token"
}
}
}
}对于传统的SSE客户:
{
"mcpServers": {
"gemsec-sse": {
"url": "http://localhost:3030/sse",
"transport": "sse"
}
}
}对于具有身份验证的传统SSE:
{
"mcpServers": {
"gemsec-sse": {
"url": "http://localhost:3030/sse",
"transport": "sse",
"headers": {
"Authorization": "Bearer your-secret-token"
}
}
}
}注: Cursor目前与StdIO传输配合使用效果更好。SSE运输更适合:
- 基于Web的MCP客户端
- 远程部署(Azure、Docker等)
- 与基于HTTP的工具集成
- 多客户端场景
开发指南
- 源布局
- src/gemsecServer.ts –MCP服务器引导(注册工具、处理路由、解析项目根)。 - src/index.ts –面向CLI的MCP客户端的StdIO入口点。 - src/httpServer.ts –Express+SSE传输,因此HTTP客户端可以通过 /sse 和 /messages. - src/services/securityAnalyzer.ts –岩芯扫描仪;读取文件并应用中定义的基于正则表达式的规则 src/config/securityPatterns.ts. - src/reporters/*.ts –文本和HTML报告管道。 - src/types.ts –共享接口(SecurityIssue, SecurityPattern等等)。
- 命令
- npm run build –编译TypeScript build/. - npm run dev –TypeScript监视模式。
- 扩展规则
- 向添加新条目 securityPatterns.ts. - 每个模式都需要一个名称、正则表达式、严重性、消息和建议。
- 添加工具
- 更新 registerListToolsHandler + registerCallToolHandler 在 src/gemsecServer.ts.
Express+SSE后端
HTTP传输与Build5Nines描述的Azure就绪蓝图相一致,该蓝图用于使用Express、Docker和Azure Developer CLI部署基于TypeScript的MCP服务器 [\[来源\]](https://build5nines.com/how-to-build-and-deploy-an-mcp-server-with-typescript-and-azure-developer-cli-azd-using-azure-container-apps-and-docker/).
📖 完整的SSE设置文档:参见 SSE_SETUP.md 详细指南。
- 端点
- GET/POST /mcp –主要流式HTTP端点(现代标准)。在单个端点上处理SSE流(GET)和请求(POST)。 - GET/POST /sse –传统SSE端点(用于向后兼容性)。 - POST /messages –旧消息端点(用于向后兼容性)。 - GET /healthz –报告工具名称和运输类型的轻量级准备就绪探头。
- 在本地运行
npm start # defaults to port 3030
PORT=8080 npm start # override the port- 快速测试
# Test health endpoint
curl http://localhost:3030/healthz
# Expected: {"status":"ok","name":"GemSec","transport":"sse"}- 身份验证(可选)
- 默认情况下,服务器在没有身份验证的情况下运行(适用于本地开发) - 要启用基于令牌的身份验证,请设置 GEMSEC_AUTH_TOKEN 环境变量:
GEMSEC_AUTH_TOKEN=your-secret-token npm start- 客户端必须在请求中包含令牌: - 头球 Authorization: Bearer your-secret-token - 或查询参数: ?token=your-secret-token - 注意:禁用身份验证时,来自客户端的“未找到存储的令牌”消息是正常的
- 部署提示
- 暴露您经过的同一端口 $PORT 并确保你的入口保留了SSE报头。 - 当扩展到单个副本之外时(例如,多个Azure容器应用程序Pod),请配置会话相关性,以便 /messages 请求到达拥有 /sse 溪流。 - 包括 Dockerfile 已经产生了适合ACA或其他容器目标的最小节点20运行时。 - 对于生产部署,考虑通过以下方式启用身份验证 GEMSEC_AUTH_TOKEN. - 看 部署.md 获取完整的Docker部署指南。
输出解剖
每个发现都包含:
- 严重性和类型 例如。,
HIGH — Missing CSRF Protection. - 行+代码 –源代码行和特定代码段。
- 上下文块 –多行摘录,突出显示,便于快速查看。
- 推荐 –建议补救措施。
- 调试提示 –适用于AI配对编程或问题跟踪的纯文本指令。
- VS代码深度链接 – `vscode://file/
: ` 直接跳到文件中。
自动打开浏览器
生成HTML报告后,它将在默认浏览器中自动打开。此功能适用于:
- macOS:用途
open命令 - 视窗:用途
start命令 - Linux:用途
xdg-open命令
要禁用自动打开,请设置环境变量:
GEMSEC_NO_AUTO_OPEN=true npm start如果自动打开失败(例如,没有可用的浏览器),报告路径仍将显示在响应中,您可以手动打开它。
故障排除
- 报告路径不在您的仓库下? 确保分析的目录包含项目标记(
package.json,.git等等)。GemSec向上遍历文件系统,直到找到一个。 - 缺失的发现? 仅
.ts,.tsx,.js,以及.jsx文件被扫描。 - 自定义报告位置? 通过绝对路径
analyze_directory或analyze_file;GemSec将自动推断出最近的项目根。
远程MCP服务器支持
⚠️ 重要提示: 当使用远程MCP服务器(部署在云中)时,服务器 无法访问本地文件系统上的文件 默认情况下。但是,GemSec现在支持 直接发送文件内容 到远程服务器!
选项1:直接发送文件内容(建议用于远程服务器)
您可以直接在工具调用中提供文件内容,允许远程服务器分析您的本地文件:
对于单文件分析:
{
"name": "analyze_file",
"arguments": {
"file_path": "/Users/me/project/src/App.tsx",
"file_content": "import React from 'react';\n\nexport default function App() {\n return
Hello
;\n}"
}
}对于目录分析:
{
"name": "analyze_directory",
"arguments": {
"directory_path": "/Users/me/project/src",
"files": [
{
"path": "/Users/me/project/src/App.tsx",
"content": "import React from 'react';\n\nexport default function App() {\n return
Hello
;\n}"
},
{
"path": "/Users/me/project/src/components/Button.tsx",
"content": "export function Button() { return Click; }"
}
]
}
}它是如何工作的:
- 客户端从本地文件系统读取文件
- 文件内容在工具调用中发送到远程服务器
- 远程服务器在不需要文件系统访问的情况下分析内容
- 结果与原始文件路径一起返回,以便正确报告
选项2:使用本地MCP服务器(建议用于本地开发)
对于本地开发,请在本地服务器上使用StdIO传输:
{
"mcpServers": {
"gemsec": {
"command": "node",
"args": ["/absolute/path/to/security-analyzer-mcp/build/index.js"]
}
}
}选项3:分析远程服务器上的文件
如果你的文件已经在远程服务器的文件系统上,你可以直接使用远程服务器的路径:
{
"name": "analyze_directory",
"arguments": {
"directory_path": "/remote/path/to/project"
}
}最佳实践:
- 使用 选项1 (文件内容)当您想使用远程服务器分析本地文件时
- 使用 选项2 (本地服务器)用于本地开发(效率最高)
- 使用 选项3 (远程路径)当文件已在远程服务器上时
使用 mcp-remote 与GemSec合作
如果你正在使用 npx mcp-remote 要连接到远程GemSec服务器(如PostHog示例),您需要知道以下内容:
配置示例:
{
"mcpServers": {
"gemsec-remote": {
"command": "npx",
"args": [
"-y",
"mcp-remote@latest",
"https://your-gemsec-server.com/sse",
"--header",
"Authorization:Bearer your-token"
],
"env": {
"GEMSEC_AUTH_TOKEN": "your-token"
}
}
}
}它是如何工作的:
mcp-remote充当本地客户端和远程GemSec服务器之间的代理- 当你打电话的时候
analyze_file或analyze_directory,AI助手(Cursor)应读取本地文件并将其内容包含在工具调用中 - 远程服务器接收文件内容,并可以在不需要文件系统访问的情况下对其进行分析
重要提示:
- ✅ 与智能AI助手配合使用:如果你的AI助手(如Cursor)可以读取本地文件并包含
file_content/files在工具调用中,这将无缝工作 - ⚠️ 手动文件读取:如果AI没有自动读取文件,您可能需要明确提供文件内容
- 💡 推荐:对于本地开发,请使用本地StdIO服务器。使用
mcp-remote当您想利用云资源或分析远程服务器上已有的文件时
使用mcp-remote的示例工具调用:
{
"name": "analyze_file",
"arguments": {
"file_path": "/Users/me/project/src/App.tsx",
"file_content": "// AI assistant reads this from local file and includes it"
}
}许可证
麻省理工学院——见 LICENSE (如果缺少,请添加一个)。
