NeikiDev/jlab-desktop
GitHub: NeikiDev/jlab-desktop
JLab Desktop 是一个跨平台的 JAR 静态恶意软件扫描桌面客户端,拖放文件即可通过云端签名库快速获取威胁分析结果。
Stars: 3 | Forks: 0
# JLab 桌面版
[](#license)
[](https://github.com/NeikiDev/jlab-desktop/releases/latest)
[](https://github.com/NeikiDev/jlab-desktop/actions/workflows/ci.yml)
[](#download)
公共的 [JLab 静态 JAR 扫描器](https://jlab.threat.rip)的原生桌面客户端。拖放一个 `.jar`(或者是包含它的 `.zip`、`.mcpack` 或 `.mrpack`),应用程序会将文件上传到 JLab API,并按严重程度分组显示匹配到的签名。HTTP 上传在 Rust 中运行,因此不会有文件字节通过 JavaScript 层泄露。
## 功能特性
- 拖放 `.jar`、`.zip`、`.mcpack` 或 `.mrpack`。对于容器档案,会提取并扫描最大的内部 `.jar`。
- 从 Rust (`reqwest` + `rustls`) 发起的原生 multipart 上传。关键路径上没有浏览器 fetch。
- 严格的 CSP。Webview 只能与 Rust 端通信。JavaScript 无法进行任何出站网络请求。
- 按严重程度(`critical`、`high`、`medium`、`low`、`info`)分组的签名视图,包含文件元数据、家族标签以及易于复制的卡片布局。
- 内联错误提示栏,为速率限制 (HTTP 429) 提供实时 `Retry-After` 倒计时。
- 在任何网络调用之前,进行本地大小验证 (50 MB) 和 zip 魔数检查。
- 可取消的扫描,具有阶段感知的进度 UI 和实时事件日志。
- 本地扫描历史记录(最近 100 次扫描,仅包含摘要)。存储在您的设备上,从不上传。文件字节和签名载荷不会被持久化保存。
- 体积小(远低于 10 MB),启动快,无遥测,无需身份验证。
## 下载
每次推送到 `main` 分支时,都会在 GitHub Releases 页面上发布预构建的安装程序。
- macOS(通用版,支持 Apple Silicon 和 Intel):`JLab.Desktop_x.y.z_universal.dmg`
- Windows (MSI):`JLab.Desktop_x.y.z_x64_en-US.msi`
[下载最新版本](https://github.com/NeikiDev/jlab-desktop/releases/latest)。
### 在 macOS 上首次运行
当前的构建尚未使用 Apple Developer ID 进行签名。macOS Gatekeeper 会警告该应用程序来自身份不明的开发者,或者提示该应用程序已“损坏”。对于从互联网下载的未签名二进制文件,这是正常现象。
请使用以下方法之一来允许该应用:
1. 在“应用程序”中右键单击该应用,选择 `Open`,然后在对话框中确认。macOS 会记住您的选择。
2. 或者在终端中移除隔离属性:
xattr -dr com.apple.quarantine "/Applications/JLab Desktop.app"
签名构建将在后续版本中提供。
### 在 Windows 上首次运行
当前的构建未使用代码签名证书进行签名。Windows SmartScreen 将显示“Windows 已保护你的电脑”。点击 `More info`,然后选择 `Run anyway`。Windows 会记住针对该文件的选择。
签名构建将在后续版本中提供。
## 更新
更新是手动进行的。应用程序在启动时会检查一次 GitHub Releases API,如果有更新的版本可用,会在页眉显示一个小的“更新到 vX”按钮,并在您的浏览器中打开发布页面。不会自动下载或安装任何内容。要进行更新,请从 [Releases 页面](https://github.com/NeikiDev/jlab-desktop/releases/latest) 获取新的安装程序并运行。您可以关闭更新提示;在下一个版本发布之前,它会保持隐藏状态。
## 工作原理
1. 您选择一个文件(或者将其拖放到窗口中)。
2. Rust 端验证扩展名并读取前几个字节,以确认该文件确实是一个 zip 档案。
3. 对于容器档案(`.zip`、`.mcpack`、`.mrpack`),会根据未压缩大小在内存中提取最大的内部 `.jar`。超过 50 MB 的内部 jar 会被提前拒绝,这可以防范 zip 炸弹。
4. Rust 通过 `multipart/form-data` 将 jar 上传到 `https://jlab.threat.rip/api/public/static-scan`。没有文件字节通过 IPC 边界传递到 webview 中。
5. 前端渲染响应结果,并按严重程度分组。
桌面客户端阻止 JavaScript 端进行网络调用。内容安全策略 (CSP) 被限制为 `connect-src ipc:`,因此未来任何 `fetch()` 调用都会在运行时失败。
## 从源代码构建
您需要:
- [Node.js](https://nodejs.org/) 20 或更新版本
- [Rust](https://rustup.rs/) 1.85 或更新版本(项目固定了 `rust-version = "1.85"`)
- 您操作系统对应的 Tauri 2 平台先决条件:
安装并运行:
```
npm install
npm run tauri dev
```
常用命令:
```
npm run check # TypeScript type-check
cargo check --manifest-path src-tauri/Cargo.toml # Rust type-check
cargo fmt --manifest-path src-tauri/Cargo.toml # format Rust
cargo clippy --manifest-path src-tauri/Cargo.toml -- -D warnings
npm run tauri build # release bundle
```
发布包将生成在 `src-tauri/target/release/bundle/`。
### 图标
仓库中包含了 `src-tauri/tauri.conf.json` 中引用的图标。要从 1024 x 1024 的 PNG 重新生成它们:
```
npm run tauri icon path/to/source.png
```
这会使用所有需要的尺寸和格式(`.png`、`.icns`、`.ico`)填充 `src-tauri/icons/`。
## API
应用程序与单个端点通信:
```
POST https://jlab.threat.rip/api/public/static-scan
Content-Type: multipart/form-data
Field: file (max 50 MB, .jar archive)
Rate limit: 15 requests / minute / IP
```
对于 `.zip`、`.mcpack` 和 `.mrpack` 的拖放操作,桌面客户端会在本地打开档案,挑选出最大的内部 `.jar`,并且仅上传该文件。该端点本身只接受 `.jar`。
无需身份验证。有关完整的 schema,请参阅 。
## 安全
如果您发现了安全问题,请私下报告。有关披露流程,请参阅 [SECURITY.md](SECURITY.md)。请勿针对漏洞提交公开的 Issue。
## 许可证
根据以下两项许可之一授权:
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE))
- MIT license ([LICENSE-MIT](LICENSE-MIT))
由您选择。
除非您明确声明,否则任何有意提交以包含在本作品中的贡献(如 Apache-2.0 许可中所定义),均应按上述方式双重许可,无需任何额外的条款或条件。
## 功能特性
- 拖放 `.jar`、`.zip`、`.mcpack` 或 `.mrpack`。对于容器档案,会提取并扫描最大的内部 `.jar`。
- 从 Rust (`reqwest` + `rustls`) 发起的原生 multipart 上传。关键路径上没有浏览器 fetch。
- 严格的 CSP。Webview 只能与 Rust 端通信。JavaScript 无法进行任何出站网络请求。
- 按严重程度(`critical`、`high`、`medium`、`low`、`info`)分组的签名视图,包含文件元数据、家族标签以及易于复制的卡片布局。
- 内联错误提示栏,为速率限制 (HTTP 429) 提供实时 `Retry-After` 倒计时。
- 在任何网络调用之前,进行本地大小验证 (50 MB) 和 zip 魔数检查。
- 可取消的扫描,具有阶段感知的进度 UI 和实时事件日志。
- 本地扫描历史记录(最近 100 次扫描,仅包含摘要)。存储在您的设备上,从不上传。文件字节和签名载荷不会被持久化保存。
- 体积小(远低于 10 MB),启动快,无遥测,无需身份验证。
## 下载
每次推送到 `main` 分支时,都会在 GitHub Releases 页面上发布预构建的安装程序。
- macOS(通用版,支持 Apple Silicon 和 Intel):`JLab.Desktop_x.y.z_universal.dmg`
- Windows (MSI):`JLab.Desktop_x.y.z_x64_en-US.msi`
[下载最新版本](https://github.com/NeikiDev/jlab-desktop/releases/latest)。
### 在 macOS 上首次运行
当前的构建尚未使用 Apple Developer ID 进行签名。macOS Gatekeeper 会警告该应用程序来自身份不明的开发者,或者提示该应用程序已“损坏”。对于从互联网下载的未签名二进制文件,这是正常现象。
请使用以下方法之一来允许该应用:
1. 在“应用程序”中右键单击该应用,选择 `Open`,然后在对话框中确认。macOS 会记住您的选择。
2. 或者在终端中移除隔离属性:
xattr -dr com.apple.quarantine "/Applications/JLab Desktop.app"
签名构建将在后续版本中提供。
### 在 Windows 上首次运行
当前的构建未使用代码签名证书进行签名。Windows SmartScreen 将显示“Windows 已保护你的电脑”。点击 `More info`,然后选择 `Run anyway`。Windows 会记住针对该文件的选择。
签名构建将在后续版本中提供。
## 更新
更新是手动进行的。应用程序在启动时会检查一次 GitHub Releases API,如果有更新的版本可用,会在页眉显示一个小的“更新到 vX”按钮,并在您的浏览器中打开发布页面。不会自动下载或安装任何内容。要进行更新,请从 [Releases 页面](https://github.com/NeikiDev/jlab-desktop/releases/latest) 获取新的安装程序并运行。您可以关闭更新提示;在下一个版本发布之前,它会保持隐藏状态。
## 工作原理
1. 您选择一个文件(或者将其拖放到窗口中)。
2. Rust 端验证扩展名并读取前几个字节,以确认该文件确实是一个 zip 档案。
3. 对于容器档案(`.zip`、`.mcpack`、`.mrpack`),会根据未压缩大小在内存中提取最大的内部 `.jar`。超过 50 MB 的内部 jar 会被提前拒绝,这可以防范 zip 炸弹。
4. Rust 通过 `multipart/form-data` 将 jar 上传到 `https://jlab.threat.rip/api/public/static-scan`。没有文件字节通过 IPC 边界传递到 webview 中。
5. 前端渲染响应结果,并按严重程度分组。
桌面客户端阻止 JavaScript 端进行网络调用。内容安全策略 (CSP) 被限制为 `connect-src ipc:`,因此未来任何 `fetch()` 调用都会在运行时失败。
## 从源代码构建
您需要:
- [Node.js](https://nodejs.org/) 20 或更新版本
- [Rust](https://rustup.rs/) 1.85 或更新版本(项目固定了 `rust-version = "1.85"`)
- 您操作系统对应的 Tauri 2 平台先决条件:标签:API客户端, DNS 反向解析, JAR文件分析, Minecraft模组安全, MITM代理, Rust语言, Tauri, TLS加密, Webview, ZIP解析, 代码生成, 前后端分离, 可视化界面, 威胁情报, 安全扫描, 开发者工具, 拖放操作, 文件上传扫描, 时序注入, 本地历史记录, 渗透测试工具, 自动化攻击, 跨平台桌面客户端, 软件供应链安全, 远程方法调用, 逆向分析, 静态扫描器