YueLink ships a network client with VPN privileges. Security regressions have outsized blast radius. This file is the contract.
If you believe you have found a security issue:
- Do not open a public issue.
- Email
onesyue@gmail.comwith subject prefix[SECURITY]. Include:- YueLink version (
Settings → About). - Platform + OS version.
- Reproduction steps.
- Whether the issue is exploitable in default settings.
- YueLink version (
- We acknowledge within 72 hours and aim to fix within 14 days for critical issues, 30 days for high, 90 days for medium.
For public CVE assignment, we will request from MITRE after a fix is shipped and a coordinated disclosure window has passed.
| Channel | Supported |
|---|---|
Latest stable (vX.Y.Z) |
✅ Active support. |
Previous stable (vX.Y.(Z-1)) |
✅ Critical fixes only, until next stable ships. |
| Older stable | ❌ Not supported. Upgrade. |
Pre-release (pre / vX.Y.Z-pre) |
|
| Forks / unofficial builds | ❌ Not supported. |
These are enforced by scripts/security_scan.sh (pre-commit + release
gate) and .github/workflows/security.yml:
- No secrets in repo. No tokens, signing keys, API passwords, subscription URLs, or private node configurations. The scanner has FAIL patterns for the historic prod DB password and CloudFront tokens.
- No PII in logs. All log export paths must go through
redactDiagnosticPiiinlib/shared/diagnostic_report.dart. Redaction covers 13 classes — see that file for the canonical list.tool/automation/pii_redaction_guard.dartruns in CI. - No subscription tokens in URL query strings. Tokens go in the
Authorization: Bearerheader._buildClientinlib/infrastructure/datasources/xboard/client.dartis the only sanctioned HTTP client for XBoard calls. - WebSocket secrets via header, not URL —
MihomoStreamusesIOWebSocketChannel.connect(uri, headers: {Authorization: ...}). - No credential persistence in plain JSON unless it is in
flutter_secure_storageor — on macOS —SecureStorageService's AES-256-GCM file (the only sanctioned exception, see CLAUDE.md). - No bypassing platform restrictions. No anti-detection, no fake
profile signatures, no help-evade-VPN-checks code. App-store builds
compile with
STANDALONE=falseand disable in-app updater.
| Source | Policy |
|---|---|
pubspec.yaml (Dart/pub) |
Dependabot, weekly. Patch may auto-merge with green CI. Minor / major manual. |
core/go.mod, service/go.mod (Go) |
Dependabot, weekly. govulncheck on every PR + weekly schedule. Patch may auto-merge. |
.github/workflows/* (Actions) |
Dependabot, weekly. SHA-pinned where the action is third-party. |
core/mihomo (submodule) |
Manual bump per governance/mihomo-bump-cadence.md. Stay on Meta, never Alpha. |
| Native binary deps (Wintun, geo data) | Pinned by SHA-256 in repo. CI verifies on every Windows leg. Bumps go through a tracked PR. |
CVE response SLA:
- Critical with fix available: ship within 7 days.
- High with fix available: ship within 14 days.
- Medium: ship in next planned release.
- No fix available: open a tracking issue, document mitigation, watch upstream.
govulncheck and dependency-review-action block PRs that introduce
high-severity vulnerabilities without a follow-up plan in the PR body.
- GitHub native secret scanning + push protection: enabled. Maintain this in repo settings; not configurable per-PR.
- Working-tree scanner:
scripts/security_scan.sh(run by pre-commit hook +release-gate.yml). Patterns include Postgres DSNs, XBoard subscription URLs, Bearer tokens, the historic leaked password. - A FAIL finding blocks commits and releases. Allowlisting is via
scripts/security_scan.allowlistwith a comment explaining why.
gitleaksruns on every PR (security.yml).govulncheckruns againstcore/andservice/Go modules.dependency-review-actionruns on every PR with a config gating new high-severity dependencies.- CodeQL is not currently configured for Dart (unsupported language). Go
CodeQL coverage is opt-in via
security.ymland considered SHOULD-have.
- Telemetry is opt-in (default off) and clearly disclosed in Settings.
- Telemetry events are anonymous —
client_idis a random UUID stored inSettingsService, never linked to user account. Joiningclient_idtouser_idis forbidden byfeedback_north_star_two_layerpolicy. - Diagnostic exports redact 13 PII classes before any file leaves the
device. Validated in CI by
pii_redaction_guard.dart.
masterandreleaseare protected branches. PR + CI required.- Required status checks:
analyze,release-gate,security(where configured). - Force pushes to protected branches are blocked at the repo settings level. Do not enable, even temporarily.
- Signing keys live outside the repo; CI uses repo / org secrets only.
- Rotating any signing key follows
docs/security/credential_rotation_sop.md.
Every security-relevant change leaves a record:
- Commits land via PR.
- Workflow runs are retained for 90 days.
governance/archives sprint-level investigation notes.docs/security/history_scan_report.mdis the canonical record of past history scans.