ishaanman7898/ShareSecure

GitHub: ishaanman7898/ShareSecure

一个注重隐私保护的临时文件分享平台,支持无痕转发链路、自动过期和加密存储,可自托管部署。

Stars: 0 | Forks: 0

# ShareSecure ![ShareSecure](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/fd1ff195cd001700.png) 一种极其简单且真正尊重您隐私的文件分享方式。 上传 PDF 或 Word 文档,获取链接,分享它。每个打开链接的人都会获得自己独立的链接——之间没有痕迹关联。当过期时间归零,文件即彻底消失。无需管理账户,没有跟踪。 ## 您将获得什么 **隐私至上** - 每个链接都是完全独立的。分享给 Alice,她获得自己的链接。如果她分享给 Bob,Bob 会获得一个不同的链接。没有链条,无法追踪谁从谁那里获得了文件。 - 数据库的设计使得每一行看起来都一样——没有时间戳链接转发记录,没有精确的文件大小,没有内容指纹。即使数据库完全泄露,攻击者也几乎得不到任何信息。 - 无 Cookies,无用户跟踪。匿名上传无需账户。 - **IP 地址提示:** 您的 IP 地址本质上对服务器及您与服务器之间的任何网络基础设施可见。ShareSecure 不会在其应用程序代码中显式记录 IP 地址,但底层操作系统、Web 服务器或托管服务商可能会在此应用程序控制之外保留连接日志。如果您的威胁模型要求 IP 匿名,请通过 **Tor** 或可信的 **VPN** 访问此服务。 **切实可行** - 仅接受 PDF 和 DOCX 文件。文件类型通过魔数(实际二进制签名)验证,而非文件名或用户提供的 MIME 类型——欺骗是不可能的。 - 每个文件都通过 SHA-256 验证。如果有人试图篡改,您会立即知道。 - 每个访问文件的人都会获得自己独立的删除 token。您可以控制自己能删除的内容。 - 文件自动过期(1 分钟到 24 小时)。时间一到,它们将永远消失。 **注释** - 使用画笔、荧光笔或橡皮擦标记 PDF。您的注释仅保留在您的链接中。 - 保存与否——取决于您。如果您即将丢失未保存的工作,浏览器会警告您。 **内置保护** - 无法右键单击,无法打印,无法保存。我们屏蔽了 Ctrl+S、Ctrl+P 等所有操作。 - 永不缓存。设备不会保留副本。 ## 架构 ``` sharesecure/ ├── db/ # Database schemas (reference only — server auto-creates tables) │ ├── schema.sql # Files table schema │ └── auth_schema.sql # Users table schema ├── docs/ # Documentation │ ├── SECURITY.md # Security policy & vulnerability reporting │ └── TERMS_AND_CONDITIONS.md # Legal terms (source document) ├── public/ # Static frontend (served at root) │ ├── index.html # Upload page │ ├── app.js # Upload page logic │ ├── style.css # Upload page styles │ ├── viewer.html # File viewer page │ ├── viewer.js # Viewer logic (PDF.js, annotations, sharing) │ ├── viewer.css # Viewer styles │ ├── terms.html # Terms & Conditions page │ ├── 404.html # Not found page │ ├── expired.html # Expired file page │ ├── icon.ico # Favicon │ ├── ShareSecure.png # Logo / banner │ └── qrcode.min.js # Client-side QR generation (no third-party calls) ├── server/ # Express.js server │ ├── index.js # Main server entry point │ ├── db.js # SQLite database setup & migrations │ ├── utils.js # Encryption, compression, pseudonymous ID utilities │ └── routes/ │ ├── files.js # Upload/download/delete/reshare routes │ └── auth.js # Authentication routes ├── functions/ # Cloudflare Pages Functions (serverless API) │ ├── _middleware.js # Security headers (applied to ALL responses) │ └── api/ │ ├── upload.js # POST - Upload file │ ├── info/[shortId].js # GET - File metadata │ ├── raw/[shortId].js # GET - Raw file bytes │ ├── download/[shortId].js # GET - Force-download │ ├── reshare/[shortId].js # POST - Untraceable reshare link │ ├── delete/[shortId].js # POST - Delete file │ ├── annotations/[shortId].js # GET/POST - PDF annotations │ └── r/[shortId].js # Viewer route handler ├── .env.example # Example environment configuration └── package.json ``` ## 实际工作原理 ``` You Friend A Friend B | | | | upload document | | | get link: /r/ABC123 | | | (keep it) | | | | | | send /r/ABC123 ------> | | | | they open it | | | get new link: /r/XYZ | | | (completely separate) | | | | | | share /r/XYZ -------> | | | | they open it | | | get link: /r/QRS | | | (totally independent) V V V DB Row ABC123 DB Row XYZ DB Row QRS [identical structure] [identical structure] [identical structure] Even if the database leaks, nobody can figure out who shared with who. All the rows look the same. ``` ## 安全性 我们剥离所有身份识别头,在各处阻止缓存,强制 HTTPS,阻止搜索引擎索引,并阻止您不需要的浏览器 API。没有 Referrer 泄露,没有指纹识别,没有 iframe 嵌入。每次上传都通过魔数验证文件类型。每次访问都根据 SHA-256 哈希值验证文件。如果出现问题,您会知道。 ## 自托管 运行您自己的私有 ShareSecure 实例。您拥有数据,您控制密钥。 ### 前置条件 - **Node.js 18 或更高版本** — [nodejs.org](https://nodejs.org) - **Git** — [git-scm.com](https://git-scm.com) - 一个加密密钥(说明如下——无需额外工具) ### 步骤 1 — 克隆仓库 ``` git clone https://github.com/ishaanman7898/ShareSecure.git cd ShareSecure npm install ``` ### 步骤 2 — 生成加密密钥 加密密钥是一个 64 字符的十六进制字符串(32 个随机字节)。您有多种生成方式: #### 选项 A — 使用 Node.js(无需额外工具) ``` node -e "console.log('ENCRYPTION_KEY=' + require('crypto').randomBytes(32).toString('hex'))" ``` 这适用于安装了 Node.js 的所有平台。复制整行 `ENCRYPTION_KEY=...`。 #### 选项 B — 使用 OpenSSL OpenSSL 是标准的加密工具包。它可能预装了,也可能没有。 **检查是否已安装:** ``` openssl version ``` **如果缺少请安装 OpenSSL:** | 平台 | 命令 | |---|---| | **Windows** (winget) | `winget install ShiningLight.OpenSSL` | | **Windows** (Chocolatey) | `choco install openssl` | | **Windows** (手动) | 从 [slproweb.com/products/Win32OpenSSL.html](https://slproweb.com/products/Win32OpenSSL.html) 下载 — 下载 "Light" 安装程序 | | **macOS** (Homebrew) | `brew install openssl` | | **Ubuntu / Debian** | `sudo apt-get install openssl` | | **Fedora / RHEL / CentOS** | `sudo dnf install openssl` | | **Arch Linux** | `sudo pacman -S openssl` | | **Alpine Linux** | `apk add openssl` | **生成密钥:** ``` openssl rand -hex 32 ``` 为其添加前缀:`ENCRYPTION_KEY=` #### 选项 C — 使用 npm 脚本 ``` npm run generate-key ``` 这在内部使用 Node.js——与选项 A 相同,但为了方便而打包。 ### 步骤 3 — 配置环境 复制示例文件并填写: ``` cp .env.example .env ``` 使用任意文本编辑器打开 `.env`: ``` PORT=3000 BASE_URL=http://localhost:3000 # 粘贴第 2 步中的 ENCRYPTION_KEY 行 ENCRYPTION_KEY=your64hexcharskeyhere # 设置为 false 以禁用 localtunnel 公网 URL USE_LOCAL_TUNNEL=true # 可选:通过 localtunnel 预留一个稳定的公网子域名 # TUNNEL_SUBDOMAIN=my-sharesecure # 可选:自定义数据目录(默认:./data) # DATA_DIR=/var/lib/sharesecure ``` **首次运行快捷方式:** 如果您跳过此步骤,服务器将在首次运行时自动生成带有随机密钥的 `.env`。检查控制台输出并备份生成的密钥。 ### 步骤 4 — 运行服务器 ``` npm start ``` 服务器在 `http://localhost:3000` 上启动。 如果设置了 `USE_LOCAL_TUNNEL=true`,控制台会打印一个公共 HTTPS URL——将该 URL 分享给不同设备或网络上的任何人。 用于开发并在代码更改时自动重启: ``` npm run dev ``` ### 方法 2 — Cloudflare Pages (Serverless) 利用 Cloudflare 的全球边缘网络进行零维护的无服务器部署。 **您需要:** - 一个免费的 [Cloudflare](https://cloudflare.com) 账户 - 一个免费的 [Turso](https://turso.tech) 数据库(托管在边缘的 SQLite) **步骤:** 1. 将此仓库 Fork 到您的 GitHub 账户 2. 在 Cloudflare → Pages → Create project → Connect your fork 3. 将构建输出目录设置为 `public`(不需要构建命令) 4. 在 Pages → Settings → Environment Variables 中添加: - `TURSO_TOKEN` — 您的 Turso 数据库认证 token - `ENCRYPTION_KEY` — 64 个十六进制字符(来自上面的步骤 2) - `BASE_URL` — 您的 Pages URL(例如 `https://sharesecure.pages.dev`) 5. 在您的 Turso 数据库中,运行 schema: turso db shell YOUR_DB_NAME < db/schema.sql 6. 部署 所有文件数据在存入数据库前均经过 AES-256-GCM 加密。即使拥有完整的数据库访问权限,没有密钥也无法获取任何信息。 ### 方法 3 — 反向代理 (生产环境) 用于在 Nginx 或 Caddy 后面的生产环境使用: **Nginx 示例:** ``` server { listen 80; server_name sharesecure.yourdomain.com; return 301 https://$host$request_uri; } server { listen 443 ssl; server_name sharesecure.yourdomain.com; ssl_certificate /etc/letsencrypt/live/sharesecure.yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/sharesecure.yourdomain.com/privkey.pem; location / { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 12M; } } ``` **Caddy 示例(自动 HTTPS):** ``` sharesecure.yourdomain.com { reverse_proxy localhost:3000 request_body { max_size 12MB } } ``` 在 `.env` 中设置 `BASE_URL=https://sharesecure.yourdomain.com` 和 `USE_LOCAL_TUNNEL=false`。 ### 作为系统服务运行 为了在重启后保持 ShareSecure 运行: ``` sudo nano /etc/systemd/system/sharesecure.service ``` ``` [Unit] Description=ShareSecure After=network.target [Service] Type=simple User=www-data WorkingDirectory=/opt/sharesecure ExecStart=/usr/bin/node server/index.js Restart=on-failure Environment=NODE_ENV=production [Install] WantedBy=multi-user.target ``` ``` sudo systemctl daemon-reload sudo systemctl enable sharesecure sudo systemctl start sharesecure sudo systemctl status sharesecure ``` ### 配置参考 | 变量 | 默认值 | 描述 | |---|---|---| | `PORT` | `3000` | 要监听的 HTTP 端口 | | `BASE_URL` | `http://localhost:3000` | 生成链接的面向公众的基础 URL | | `ENCRYPTION_KEY` | *(无)* | 64 个十六进制字符 — AES-256-GCM 密钥。如果为空则自动生成。 | | `USE_LOCAL_TUNNEL` | `true` | 设置为 `false` 以禁用 localtunnel | | `TUNNEL_SUBDOMAIN` | *(随机)* | localtunnel 的可选固定子域 | | `DATA_DIR` | `./data` | SQLite 数据库和上传文件的目录 | | `DB_PATH` | `/sharesecure.db` | 覆盖数据库路径 | ### 故障排除 **"ENCRYPTION_KEY not set" 警告** 文件将以未加密形式存储在磁盘上。使用 `npm run generate-key` 生成密钥并将其添加到 `.env`。 **端口已被占用** 在 `.env` 中设置不同的端口:`PORT=3001`。 **localtunnel 未启动** 在 `.env` 中设置 `USE_LOCAL_TUNNEL=false`。生产环境请使用反向代理。 **启动时出现 "Cannot find module"** 在项目目录中运行 `npm install`。 ## API 参考 ### `POST /api/upload` 上传文件并接收唯一的链接。仅接受 PDF 和 DOCX;文件类型由服务器端的魔数验证。 **请求**: `multipart/form-data` - `file` — 要上传的文件(最大 10 MB,仅限 PDF 或 DOCX) - `expires_hours` — 过期时间(小时)(最小:1 分钟,最大:24 小时) - `allow_annotations` — `1` 启用 PDF 注释 - `allow_download` — `1` 启用下载按钮 **响应**: ``` { "shortId": "ABC12345", "shortUrl": "https://example.com/r/ABC12345", "filename": "document.pdf", "size": 245760, "expiresAt": "2024-01-01T13:00:00.000Z", "deleteToken": "x9Kp2mQ7..." } ``` ### `GET /api/info/:shortId` 获取文件元数据(不含文件内容)。 ### `GET /api/raw/:shortId` 获取用于渲染的原始文件字节。在提供服务前验证 SHA-256 完整性。返回 `application/octet-stream`(隐私——头中无 MIME)。 ### `POST /api/reshare/:shortId` 生成指向相同文件内容的新的、不可追踪的链接。 ### `POST /api/delete/:shortId` 删除文件。请求体中需要 `{ deleteToken: "..." }`。触发整个集群的级联删除。 ### `GET /api/annotations/:shortId` / `POST /api/annotations/:shortId` 加载或保存特定链接的 PDF 注释笔画。注释经过加密并按链接隔离。 ## 如果……会发生什么 **有人入侵了数据库?** 每一行都是相同的。他们不会知道谁上传了、谁查看了或谁转发了。 **他们修改了文件?** SHA-256 验证会检测到。查看器会向您显示篡改警报。 **他们试图追踪谁分享给了谁?** 不可能。每次分享都会生成一个新的、独立的链接。 **他们嗅探您的流量?** HTTPS 加密内容。ShareSecure 的响应中没有 Referrer 数据或身份识别头。您的 IP 地址在网络层可见——如果您在意这一点,请使用 Tor 或 VPN。 **他们上传了恶意文件?** 魔数验证会拒绝任何实际上不是 PDF 或 DOCX 的内容。文件类型由二进制内容决定,而不是文件名或 MIME 头。 **您的浏览器缓存了它?** 不会。我们告诉它不要缓存。 ## 文档 - [条款与条件](/terms) — 法律免责声明和使用政策 - [安全策略](docs/SECURITY.md) — 漏洞报告 - [数据库 Schema](db/schema.sql) — 文件表 - [认证 Schema](db/auth_schema.sql) — 用户表 ## 许可证 MIT
标签:Cloudflare Pages, JSONLines, MITM代理, PDF批注, SHA-256, 匿名分享, 去中心化, 数据泄露, 数据防泄露, 文件共享, 文件完整性校验, 无追踪, 端到端加密, 网络安全, 自定义脚本, 自托管, 阅后即焚, 隐私保护, 零信任