diff --git a/.github/workflows/release-builds.yml b/.github/workflows/release-builds.yml index e71af3e..84c58b3 100644 --- a/.github/workflows/release-builds.yml +++ b/.github/workflows/release-builds.yml @@ -64,10 +64,10 @@ jobs: node-version: "20" - name: Install Wails - run: go install github.com/wailsapp/wails/v2/cmd/wails@latest + run: go install github.com/wailsapp/wails/v2/cmd/wails@$(go list -m -f '{{.Version}}' github.com/wailsapp/wails/v2) - name: Install frontend dependencies - run: npm install + run: npm ci working-directory: frontend - name: Install Linux build dependencies diff --git a/audits/20260615-1934-functionalityNextSteps.md b/audits/20260615-1934-functionalityNextSteps.md new file mode 100644 index 0000000..2716458 --- /dev/null +++ b/audits/20260615-1934-functionalityNextSteps.md @@ -0,0 +1,126 @@ +# Functionality and Next Steps Report + +## 1. Executive Summary + +This fix-mode audit improved immediate security and robustness around profile validation, imports, drag-drop upload, frontend encoding, dependencies, and release reproducibility. + +The most useful next work is to turn these fixes into durable product quality: add frontend interaction tests, make large file upload streaming and consistent, warn users about intentionally insecure protocol choices, and strengthen release provenance. + +## 2. Current Functional Risks + +Direct VNC can still be used without SSH tunnelling. That is valid for trusted networks, but the UI should make the risk visible when profiles are saved or connected. + +Drag-drop SFTP upload is now capped at 25 MiB because it still uses an in-memory browser-to-Go base64 path. Larger files should use the existing native SFTP upload flow or a future streaming drag-drop implementation. + +Profile import now rejects malformed or unsafe profiles before storage. That is safer, but older third-party exports with missing defaults may need a clearer import error UI or a migration/repair preview. + +RAW session history and recordings can still grow over long sessions. Users need limits, retention controls, and clear storage management. + +## 3. Code Quality Improvements + +Profile validation is now centralized enough for create/update/import, but profile normalization is still split between frontend defaults, Go defaults, and import-time cleanup. A schema-versioned import normalizer would make future protocol additions safer. + +Frontend still has many `innerHTML` templates. Some are static or escaped, but a small helper pattern for safe modal construction would reduce future XSS mistakes. + +Release scripts and CI now use pinned Wails and `npm ci`; follow-up work should avoid duplicate release logic between `build.sh`, `release.sh`, and GitHub Actions. + +## 4. Frontend Interaction and Error-Handling Improvements + +Add Wails/browser interaction tests for: + +- Dropping a file with HTML metacharacters in its filename. +- Dropping a file over 25 MiB. +- Importing malformed and oversized profile bundles. +- Saving GitHub profiles with HTTP and HTTPS API base URLs. +- Creating direct VNC profiles and seeing a warning. + +Improve import UX by showing which profile entry failed validation without exposing secret values. + +## 5. Testing Roadmap + +Immediate tests to add: + +- Frontend DOM regression for file-drop title rendering. +- API tests for successful valid GitHub Enterprise HTTPS profile creation. +- Import tests for mixed valid/invalid profile arrays. + +Short-term tests: + +- End-to-end Wails smoke tests for create profile, connect prompt flow, import/export, SFTP upload, and VNC tunnel setup. +- Load tests for large SFTP directories, RAW captures, and recordings. +- CI security job with `npm audit`, govulncheck, and secret scanning. + +Longer-term tests: + +- Release workflow dry-run or artifact validation tests. +- Migration tests for profile schema changes. + +## 6. Recommended New Functionality + +Add a direct-VNC safety warning and a per-profile “prefer SSH tunnel” nudge. + +Add streaming drag-drop SFTP upload for larger files, or route drag-drop files above 25 MiB into the native upload flow. + +Add import preview: list profile names, protocols, validation warnings, and duplicate handling before writing. + +Add recording retention settings: max recording size, max age, and one-click cleanup. + +Add security diagnostics in settings: dependency check status, known-host summary, direct insecure profile count, and last audit-log events. + +## 7. Next-Level Opportunities + +Release hardening: + +- Sign and notarize release artifacts where platform-appropriate. +- Publish checksums and provenance. +- Pin or cache dependency sources in CI. + +Observability: + +- Add structured non-sensitive debug logs for import rejection, update checks, VNC proxy lifecycle, and SFTP transfer failures. +- Add audit entries for validation failures that indicate suspicious imports, without storing payload contents. + +Developer experience: + +- Consolidate release/build dependency resolution into one reusable script. +- Add a frontend lint rule or custom check for unsafe `innerHTML` with dynamic values. + +Accessibility/product quality: + +- Ensure modal error states are keyboard reachable and announced. +- Add clearer status messages for blocked uploads and import validation failures. + +## 8. Prioritised Action Plan + +Immediate: + +- Add direct VNC warning copy and tests. +- Add frontend file-drop XSS and oversize tests. +- Add CI jobs for `go test ./...`, `npm run build`, `npm audit`, and govulncheck. + +Short-term: + +- Replace deprecated `xterm` packages with maintained `@xterm/*` packages. +- Build import preview and validation repair UI. +- Add recording and RAW capture storage limits. + +Medium-term: + +- Implement streaming drag-drop upload. +- Add release signing, checksums, and provenance. +- Add schema-versioned profile import/export. + +Long-term: + +- Build a security/settings dashboard for insecure profiles, known hosts, audit status, and update health. +- Add comprehensive Wails end-to-end smoke coverage for core workflows. + +## 9. Caveats and Validation Needed + +The fixes were verified with automated local checks, but not with live Wails UI automation. + +The new import validation may reject malformed legacy profiles that were previously accepted. That is intentional for safety, but the UX should help users repair old data. + +The 25 MiB drag-drop upload cap is a guardrail, not a final large-file strategy. Streaming support would be the better long-term user experience. + +Direct VNC was left open because some users need it on trusted networks; the next step is product warning and safer defaults, not silent removal. diff --git a/audits/20260615-1934-securityAudit.md b/audits/20260615-1934-securityAudit.md new file mode 100644 index 0000000..e7b9eeb --- /dev/null +++ b/audits/20260615-1934-securityAudit.md @@ -0,0 +1,752 @@ +# Security Audit Report + +## 1. Executive Summary + +This fix-mode audit reviewed Nexus Terminal, a Wails desktop client with a Go backend and JavaScript frontend for SSH, Telnet, RAW TCP, VNC, SFTP, GitHub, recordings, local shells, encrypted secrets, and profile import/export. + +The highest-risk issues fixed in this run were unsafe profile persistence/import validation, a local DOM XSS trigger in the file-drop modal, memory-exhaustion paths in import and drag-drop upload flows, vulnerable dependency versions, and release tooling that installed unpinned build dependencies. I also removed the stale insecure SSH connection helper so future code cannot silently bypass host-key verification. + +Post-fix verification passed: `go test ./...`, focused Go tests, `npm run build`, `npm audit --json`, `go run golang.org/x/vuln/cmd/govulncheck@latest ./...`, `bash -n build.sh release.sh`, and `git diff --check`. + +Residual risk remains where users intentionally choose insecure protocols or workflows, especially direct VNC without SSH tunnelling. No high-confidence secrets or private keys were found in the repository search performed during this audit. + +## 2. Scope Reviewed + +Reviewed code and configuration: + +- Go backend under `internal/`: API bindings, sessions, SSH, VNC, SFTP, storage, secrets, export/import, validation, updater, recordings, local shell, GitHub client, raw and telnet clients. +- Frontend JavaScript under `frontend/src/js`, especially file drop, terminal, settings, GitHub, profile, SFTP, VNC, notification, and import/export flows. +- Dependency manifests and lockfiles: `go.mod`, `go.sum`, `frontend/package.json`, `frontend/package-lock.json`. +- Build/release configuration: `build.sh`, `release.sh`, `.github/workflows/release-builds.yml`, `wails.json`. +- Existing tests under `internal/**/*_test.go`. + +Not reviewed with live external testing: + +- Real SSH/VNC/GitHub endpoints. +- Packaged binaries and platform installers. +- Manual UI testing inside a running Wails app. + +## 3. Methodology + +I used a two-pass review: + +- Attack-surface mapping of Wails API methods, import/export paths, file handling, DOM sinks, dependency/build chain, protocol clients, local proxy behavior, and credential flows. +- Defensive validation from source and tests, followed by smallest safe fixes with regression tests. + +Tools/checks used: + +- Static review with `rg`, direct source reads, and line evidence. +- `go test ./...`. +- Focused tests for API, storage, export/import, validation, SSH client, and sessions. +- `npm audit --json`. +- `npm run build`. +- `go run golang.org/x/vuln/cmd/govulncheck@latest ./...`. +- `bash -n build.sh release.sh`. +- `git diff --check`. + +## 4. Risk Rating Method + +Severity considered attacker position, exploit preconditions, likely impact, and whether sensitive credentials or code execution could be affected. + +- Critical: practical remote compromise or credential disclosure with minimal preconditions. +- High: credible dependency, credential, or supply-chain compromise. +- Medium: user-assisted or renderer/local attack that can affect confidentiality, integrity, or availability. +- Low: hardening, defense-in-depth, or intentionally insecure user-selected modes. +- Informational: verified area, non-exploitable issue, or test gap. + +Confidence is High where source evidence and regression checks directly support the finding. + +## 5. Attack Surface Map + +Entry points: + +- Wails-bound Go API methods in `internal/api/api.go`. +- Profile create/update/import/export and encrypted `.nexus` imports. +- Drag-and-drop file upload/paste in `frontend/src/js/terminal.js`. +- SSH, Telnet, RAW TCP, VNC, SFTP, GitHub API, and local shell sessions. +- Local VNC WebSocket proxy on loopback. +- Build/release automation and dependency installation. + +Trust boundaries: + +- Frontend renderer to Wails API. +- User-selected/imported local files to backend parsers. +- Saved/imported profiles to outbound network clients. +- Remote hosts and GitHub/GitHub Enterprise APIs to frontend rendering. +- Local filesystem/keychain/vault to application process. +- CI/release environment to dependency registries and Go module proxy. + +Attacker starting positions considered: + +- Malicious imported profile bundle. +- Crafted local file or filename dropped into the terminal. +- Compromised renderer or malicious frontend input reaching Wails APIs. +- Network attacker on SSH/VNC/GitHub paths. +- Dependency registry or release-time supply-chain manipulation. + +## 6. Findings Summary Table + +| ID | Severity | Confidence | Title | Component | Status | +|---|---:|---:|---|---|---| +| SEC-20260615-001 | Medium | High | Profile persistence and imports accepted unsafe or malformed profiles | API, validation, import | Fixed | +| SEC-20260615-002 | Medium | High | Import and drag-drop upload paths allowed memory exhaustion | Import/export, SFTP upload | Fixed | +| SEC-20260615-003 | Medium | High | Dropped filenames were rendered through `innerHTML` | Frontend terminal file-drop modal | Fixed | +| SEC-20260615-004 | Medium | High | Unused SSH helper still defaulted to insecure host-key verification | SSH client | Fixed | +| SEC-20260615-005 | High | High | Dependency advisories affected `esbuild` and required `x/net` module versions | Dependencies | Fixed | +| SEC-20260615-006 | Medium | High | Release automation installed unpinned build dependencies | CI/release supply chain | Fixed | +| SEC-20260615-007 | Low | High | Direct VNC remains unencrypted when SSH tunnelling is disabled | VNC client | Open | + +## 7. Detailed Findings + +### Finding ID: SEC-20260615-001 + +#### Title + +Profile persistence and imports accepted unsafe or malformed profiles + +#### Severity + +Medium + +#### Confidence + +High + +#### Affected Files / Components + +- `internal/api/api.go`, `CreateProfile`, `UpdateProfile`, `ImportProfiles`, `ImportProfilesEncrypted`, lines 94-131, 715-728, 1176-1189, 1754-1791. +- `internal/validation/validation.go`, profile, GitHub, and VNC validation, lines 51-140 and 325-410. +- `internal/storage/store.go`, `ImportProfiles`, lines 365-380. + +#### Description + +The API comment said profile creation validates input, but the Wails API previously persisted profiles without calling the validation package. Plain JSON import also decoded into `[]*models.Profile` and dereferenced entries without rejecting `null`. A malicious or corrupt import could therefore crash the app or store profiles with unsafe GitHub API base URLs that would later receive a saved or prompted token. + +#### Evidence + +The fixed code now calls `validation.ValidateProfile` before create/update and validates every imported profile before writing. GitHub API base URLs must be HTTPS unless loopback, must be absolute, and must not include URL credentials. Import strategy and null entries are rejected before persistence. + +Regression tests were added in `internal/api/api_test.go` and `internal/storage/storage_test.go`. + +#### Attack Scenario + +A user imports a profile JSON containing a GitHub profile with `http://evil.example/api/v3` as the API base URL, or a `null` profile entry. Before the fix, malformed data could be saved or crash import handling. If the malicious GitHub profile were later used, the app could send a token to an attacker-controlled endpoint. + +#### Impact + +Possible token exposure through malicious profile configuration, app crash during import, and fragile persisted state. + +#### Recommendation + +Validate all Wails-bound persistence inputs and imported profiles before storage. Reject non-HTTPS remote GitHub API URLs and malformed entries. + +#### Safer Example + +Implemented: + +- `CreateProfile` and `UpdateProfile` call `validation.ValidateProfile`. +- `ValidateGitHubConfig` rejects remote HTTP and URL credentials. +- Import helpers reject oversized, null, or invalid entries before writes. + +#### Suggested Tests + +Implemented: + +- Unsafe GitHub base URL rejection. +- Null import entry rejection. +- Oversized JSON import rejection. +- Storage-level null import entry rejection. +- GitHub and VNC validation cases. + +#### References + +- CWE-20: Improper Input Validation. +- CWE-200: Exposure of Sensitive Information to an Unauthorized Actor. +- OWASP API Security Top 10: API3 Broken Object Property Level Authorization / unsafe object properties. + +#### Assumptions / Limitations + +GitHub Enterprise over non-loopback HTTP is now rejected. If a legitimate deployment needs HTTP, it should be placed behind local loopback or HTTPS. + +### Finding ID: SEC-20260615-002 + +#### Title + +Import and drag-drop upload paths allowed memory exhaustion + +#### Severity + +Medium + +#### Confidence + +High + +#### Affected Files / Components + +- `internal/api/api.go`, plain import and SFTP drag-drop upload, lines 715-718 and 1336-1350. +- `internal/exportimport/exportimport.go`, encrypted import file read, lines 37 and 131-144. +- `frontend/src/js/terminal.js`, drag-drop file upload cap, lines 10 and 829-849. + +#### Description + +Several local file paths loaded attacker-controlled or user-selected content fully into memory without a size cap. Plain profile JSON import accepted arbitrary string size from the renderer. Encrypted `.nexus` import used `os.ReadFile` on the selected path. Drag-drop SFTP upload read each browser `File` into an `ArrayBuffer`, converted it to base64, and sent it to the backend, where it was decoded into another byte slice. + +#### Evidence + +The fixed code adds: + +- 5 MiB cap for plain profile JSON import. +- 10 MiB cap for encrypted `.nexus` import files. +- 25 MiB frontend and backend caps for inline drag-drop SFTP uploads. + +Regression tests cover oversized plain import, encrypted import, and backend upload payload rejection. + +#### Attack Scenario + +A user drops or imports a very large crafted file. Before the fix, the renderer and backend could allocate multiple full copies, causing high memory pressure or an app crash. + +#### Impact + +Local denial of service against the desktop application. + +#### Recommendation + +Keep bounded inline payload paths and prefer streaming APIs for larger transfers. The existing native SFTP upload path streams local files and should remain the recommended path for large uploads. + +#### Safer Example + +Implemented size checks before decode/read where practical: + +- `base64.StdEncoding.DecodedLen` guard before decoding drag-drop upload payloads. +- `os.Stat` size check before encrypted import `os.ReadFile`. + +#### Suggested Tests + +Implemented: + +- `TestImportProfilesRejectsOversizedJSON`. +- `TestDecryptRejectsOversizedFile`. +- `TestSFTPUploadDataRejectsOversizedPayloadBeforeSessionLookup`. + +#### References + +- CWE-400: Uncontrolled Resource Consumption. +- OWASP ASVS 12.4: file and resource limits. + +#### Assumptions / Limitations + +The caps are conservative application-level limits. Larger profile bundles or drag-drop uploads now require a streaming implementation or the existing native SFTP upload flow. + +### Finding ID: SEC-20260615-003 + +#### Title + +Dropped filenames were rendered through `innerHTML` + +#### Severity + +Medium + +#### Confidence + +High + +#### Affected Files / Components + +- `frontend/src/js/terminal.js`, file-drop modal, lines 720-742. + +#### Description + +The file-drop modal interpolated the dropped filename into an `innerHTML` template. Local files can have names containing HTML metacharacters. In a Wails desktop app, DOM script execution is higher impact than a normal static page because the renderer can call privileged Wails APIs. + +#### Evidence + +The fixed modal escapes the file-drop title with `escapeHtml(title)` before injecting it into the template. + +#### Attack Scenario + +A user downloads or receives a file with a crafted name such as an HTML tag with an event handler, then drops it into a terminal. Before the fix, the modal could parse the filename as markup. + +#### Impact + +Potential renderer-side script execution and access to Wails-bound APIs from malicious DOM content. + +#### Recommendation + +Do not put user-controlled strings into `innerHTML`. Use `textContent` or escape before insertion. + +#### Safer Example + +Implemented `escapeHtml(title)` in the file-drop modal. + +#### Suggested Tests + +Add a frontend interaction test that drops a file named with ``-style metacharacters and asserts the modal text is rendered literally. Manual Wails/browser verification was not run in this audit. + +#### References + +- CWE-79: Improper Neutralization of Input During Web Page Generation. +- OWASP ASVS 5.3: output encoding. + +#### Assumptions / Limitations + +This fix covers the reviewed file-drop title sink. Other `innerHTML` templates were spot-checked; future work should add an automated DOM-sink lint or test pass. + +### Finding ID: SEC-20260615-004 + +#### Title + +Unused SSH helper still defaulted to insecure host-key verification + +#### Severity + +Medium + +#### Confidence + +High + +#### Affected Files / Components + +- `internal/sshclient/sshclient.go`, `Connect`, lines 72-75. +- `internal/sshclient/sshclient_test.go`, regression test, lines 12-19. + +#### Description + +Current production session code uses explicit host-key callbacks, and no remaining reviewed SSH/VNC path calls `ssh.InsecureIgnoreHostKey`. However, the internal `sshclient.Connect` helper still defaulted to an insecure host-key callback. That made future misuse easy. + +#### Evidence + +The helper now fails closed and instructs callers to use `ConnectWithHostKeyCallback`. `rg` found no remaining `InsecureIgnoreHostKey` references after the change. + +#### Attack Scenario + +A future feature calls the convenience method instead of `ConnectWithHostKeyCallback`. Before the fix, that new path would silently accept any SSH host key. + +#### Impact + +Potential SSH machine-in-the-middle exposure if the helper were reused. + +#### Recommendation + +Keep host-key policy explicit on every SSH path. Do not provide insecure convenience APIs in internal packages. + +#### Safer Example + +Implemented: `Connect` returns `sshclient: host key callback is required`. + +#### Suggested Tests + +Implemented `TestConnectRequiresHostKeyCallback`. + +#### References + +- CWE-295: Improper Certificate Validation, analogous to SSH host-key validation. +- OWASP ASVS 9.1.2: server authenticity validation. + +#### Assumptions / Limitations + +This is a preventive fix. The reviewed production paths already used explicit callbacks. + +### Finding ID: SEC-20260615-005 + +#### Title + +Dependency advisories affected `esbuild` and required `x/net` module versions + +#### Severity + +High + +#### Confidence + +High + +#### Affected Files / Components + +- `frontend/package.json`, `esbuild`, line 22. +- `frontend/package-lock.json`, `esbuild` and platform packages. +- `go.mod`, `golang.org/x/net`, line 15. +- `go.sum`. + +#### Description + +`npm audit` reported `esbuild 0.28.0` affected by a high-severity advisory and a low-severity advisory. `govulncheck -show verbose` reported six vulnerabilities in required `golang.org/x/net v0.54.0` modules, though no reachable symbols were called by this code. + +#### Evidence + +The fixed versions are: + +- `esbuild` bumped to `^0.28.1`. +- `golang.org/x/net` bumped to `v0.55.0`. + +Post-fix `npm audit --json` reports zero vulnerabilities and `govulncheck` reports `No vulnerabilities found.` + +#### Attack Scenario + +For `esbuild`, a compromised or manipulated package installation environment could exploit known build-tool weaknesses. For `x/net`, future code changes could start calling vulnerable symbols if the module stayed on an affected version. + +#### Impact + +Supply-chain compromise risk during build/development and latent dependency risk. + +#### Recommendation + +Keep audited dependency patch versions current and include `npm audit` and `govulncheck` in regular release checks. + +#### Safer Example + +Implemented package/module upgrades and lockfile updates. + +#### Suggested Tests + +Implemented verification: + +- `npm audit --json`. +- `go run golang.org/x/vuln/cmd/govulncheck@latest ./...`. +- `go test ./...`. +- `npm run build`. + +#### References + +- CWE-494: Download of Code Without Integrity Check. +- CWE-1104: Use of Unmaintained Third Party Components. +- Go vulnerability database advisories for `golang.org/x/net`. +- GitHub Advisory Database for `esbuild`. + +#### Assumptions / Limitations + +The `x/net` advisories were not reachable before the bump, according to govulncheck. The upgrade removes the latent module-level finding anyway. + +### Finding ID: SEC-20260615-006 + +#### Title + +Release automation installed unpinned build dependencies + +#### Severity + +Medium + +#### Confidence + +High + +#### Affected Files / Components + +- `.github/workflows/release-builds.yml`, Wails and npm install steps, lines 66-70. +- `release.sh`, Wails and npm install logic, lines 76-99. + +#### Description + +The release workflow installed the Wails CLI with `@latest` and used `npm install` rather than the lockfile-enforcing `npm ci`. Local release scripting also instructed or performed unpinned dependency installation in some paths. + +#### Evidence + +The fixed workflow installs the Wails CLI at the version resolved from `go.mod` and uses `npm ci`. `release.sh` now installs the pinned Wails CLI version from `go.mod` when needed and uses `npm ci` when `frontend/package-lock.json` exists. + +#### Attack Scenario + +A release build runs after a compromised or breaking upstream release, or after lockfile drift. Before the fix, release outputs could include unreviewed dependency changes. + +#### Impact + +Build reproducibility loss and supply-chain risk in release artifacts. + +#### Recommendation + +Use pinned module versions and lockfile-enforced installs in CI/release paths. + +#### Safer Example + +Implemented: + +- `go install ...@$(go list -m -f '{{.Version}}' github.com/wailsapp/wails/v2)`. +- `npm ci` in CI and release script. + +#### Suggested Tests + +Implemented: + +- `bash -n build.sh release.sh`. +- Frontend build after `npm ci`. + +#### References + +- SLSA build integrity principles. +- CWE-494. + +#### Assumptions / Limitations + +The workflow still allows network dependency retrieval during CI. Stronger controls would include dependency caching, provenance, and artifact signing. + +### Finding ID: SEC-20260615-007 + +#### Title + +Direct VNC remains unencrypted when SSH tunnelling is disabled + +#### Severity + +Low + +#### Confidence + +High + +#### Affected Files / Components + +- `internal/sessions/manager.go`, direct VNC branch, lines 1012-1062. +- `internal/vncclient/vncclient.go`, direct TCP dial, lines 139-144. + +#### Description + +When VNC SSH tunnelling is disabled, the client makes a direct TCP VNC connection. Classic VNC deployments often provide weak or no transport encryption. + +#### Evidence + +The VNC client intentionally supports both SSH-tunnelled and direct modes. The direct branch uses `net.DialTimeout` to the VNC address. + +#### Attack Scenario + +A user connects directly to VNC over an untrusted network. A network attacker observes or tampers with remote desktop traffic, depending on the VNC server's negotiated security type. + +#### Impact + +Potential confidentiality and integrity loss for remote desktop sessions. + +#### Recommendation + +Keep direct VNC available for trusted networks, but clearly warn users when SSH tunnelling is disabled and consider requiring explicit confirmation for saved direct-VNC profiles. + +#### Safer Example + +Prefer enabling `vnc.sshTunnel` and verifying the SSH host key for the tunnel host. + +#### Suggested Tests + +Add a UI test that direct VNC profiles show a warning, and an integration test that tunnelled VNC requires a host-key callback. + +#### References + +- OWASP ASVS 9.1: secure channel requirements. + +#### Assumptions / Limitations + +This was not changed in this run because direct VNC can be a deliberate user choice for isolated networks. + +## 8. Blackhat-Style Abuse Paths + +Path A: malicious profile import to token exfiltration, now blocked. + +1. Provide a profile bundle with a GitHub API base URL pointing to attacker infrastructure. +2. User imports and connects. +3. App prompts for or retrieves a token and sends it to the configured endpoint. +4. Defensive breakpoints now added: profile validation, HTTPS requirement for remote GitHub APIs, import validation before storage. + +Path B: crafted dropped filename to renderer script execution, now blocked. + +1. User receives a file with HTML metacharacters in the filename. +2. User drops it into a terminal. +3. Filename is rendered in the file-drop modal. +4. Defensive breakpoint now added: title is escaped before `innerHTML` insertion. + +Path C: oversized file to app memory exhaustion, now blocked for reviewed inline paths. + +1. User imports or drops an extremely large file. +2. Renderer/backend allocate full file contents and base64 copies. +3. App becomes slow or crashes. +4. Defensive breakpoints now added: import and inline upload size caps. + +Path D: direct VNC over hostile network, still open by design. + +1. User disables SSH tunnel and connects to a VNC server over an untrusted network. +2. Network attacker observes/tampers with VNC traffic if protocol security is weak. +3. Defensive breakpoint: use SSH tunnel; future UI warning recommended. + +## 9. Denial-of-Service Review + +Fixed DoS controls: + +- Plain profile import now rejects payloads over 5 MiB. +- Encrypted profile import now rejects files over 10 MiB before `os.ReadFile`. +- Drag-drop SFTP upload now rejects files over 25 MiB in the frontend and backend before base64 decode. +- Null profile entries no longer panic import paths. + +Checked and not found: + +- SQL queries use parameters for profile and audit operations reviewed. +- GitHub repo fetch has timeouts and caps repository listing at 5000 repos. +- SSH/Telnet/RAW connection setup uses dial timeouts. +- VNC local proxy binds to loopback and uses a per-session token in the current code. + +Residual DoS risks: + +- RAW session history and terminal recordings can grow with long sessions. +- SFTP directory listing still depends on remote server behavior and could return very large directories. +- Direct VNC proxy bridges long-lived streams by design. + +## 10. Dependency and Supply-Chain Review + +Fixed: + +- `esbuild` upgraded to `^0.28.1`; `npm audit --json` now reports zero vulnerabilities. +- `golang.org/x/net` upgraded to `v0.55.0`; govulncheck now reports no vulnerabilities. +- Release workflow uses `npm ci` and pinned Wails CLI version. +- `release.sh` uses `npm ci` when a lockfile exists and installs the Wails CLI at the version from `go.mod`. + +Checked: + +- `go.mod`, `go.sum`, `frontend/package.json`, `frontend/package-lock.json`. +- `.github/workflows/release-builds.yml`, `build.sh`, `release.sh`. + +Notes: + +- npm warns that `xterm` packages are deprecated in favor of the newer `@xterm/*` packages. That is not an active vulnerability from `npm audit`, but it is a maintenance risk. + +## 11. Secrets and Sensitive Data Review + +Checked: + +- Repository search for private key markers, common cloud tokens, GitHub token prefixes, and obvious password assignments. +- Secret store uses AES-GCM with Argon2id-derived keys and writes vault data with `0600`. +- Profile export redacts inline SSH proxy/TOTP secrets when non-secret export mode is used. + +No high-confidence committed secrets or private keys were found. + +Residual notes: + +- GitHub and remote connection tokens are still available to the running app process by design. +- Audit logging should continue to avoid logging raw secrets; reviewed audit messages do not include secret values. + +## 12. Authentication and Authorisation Review + +This is a desktop app, so there are no multi-user server authz roles in the reviewed code. + +Checked/fixed: + +- SSH host-key bypass helper removed by making `sshclient.Connect` fail closed. +- Current SSH and VNC tunnel paths use explicit host-key callbacks. +- GitHub API base URL validation now reduces token leakage to remote HTTP endpoints. + +Residual: + +- Users can still choose insecure protocols/modes such as direct VNC or legacy Telnet/RAW TCP. + +## 13. Input Validation and Output Encoding Review + +Fixed: + +- API create/update now validates profiles before persistence. +- Plain and encrypted import validate every profile before storage. +- GitHub API URLs now require HTTPS except loopback and reject URL credentials. +- VNC validation supports VNC-specific host fallback and validates tunnel fields. +- File-drop filename is escaped before template insertion. + +Checked: + +- SSH key management already rejects path traversal key names with alphanumeric, hyphen, and underscore constraints. +- SFTP dropped filenames use `filepath.Base` before remote path construction. + +## 14. Frontend HTML/JavaScript Robustness Review + +Fixed: + +- File-drop modal filename sink now uses `escapeHtml`. +- Drag-drop upload rejects files over 25 MiB before FileReader allocation. + +Checked: + +- Notifications render messages with `textContent`. +- GitHub repository card fields reviewed use `textContent` or escaping for remote metadata. + +Not fully exercised: + +- No live Wails UI/browser automation was run in this audit. Add frontend interaction tests for file-drop, import/export, and update UI in future work. + +## 15. Infrastructure and Deployment Review + +Fixed: + +- GitHub Actions release workflow now uses pinned Wails CLI and `npm ci`. +- Local `release.sh` now uses pinned Wails CLI and `npm ci`. + +Checked: + +- No Docker, Kubernetes, Terraform, or cloud deployment config was present in the reviewed file list. +- Wails config was reviewed for frontend build/install commands. + +Residual: + +- Release artifacts are not signed/notarized in the reviewed workflow. +- CI workflow has `contents: write`, required for release attachment, but should remain limited to release jobs. + +## 16. Logging, Monitoring, and Error Handling Review + +Checked: + +- Audit log records profile changes, import/export counts, connects/disconnects, and secret access without raw secret values. +- Fixed import validation returns actionable errors rather than panics. +- Frontend upload errors now surface a user-safe oversized-file message. + +Residual: + +- Some protocol errors are emitted directly to the UI. Continue avoiding credentials in error strings from remote services. +- Consider adding structured debug logs for rejected imports without dumping payloads. + +## 17. Test Coverage and Security Regression Gaps + +Added/updated tests: + +- API rejects unsafe GitHub base URL. +- API rejects null and oversized imports. +- API rejects oversized inline SFTP upload before session lookup. +- Export/import rejects oversized encrypted files. +- Storage import rejects null profile entries and invalid strategy before looping. +- Validation covers GitHub URL and VNC host/tunnel cases. +- SSH client `Connect` requires explicit host-key callback. + +Remaining gaps: + +- Browser/Wails interaction tests for file-drop XSS and upload cap. +- Load tests for very large SFTP directories, RAW history, and recordings. +- End-to-end import/export tests through the actual Wails UI. +- Release workflow provenance/signing tests. + +## 18. Prioritised Remediation Plan + +Immediate: + +- Keep the fixed tests in CI. +- Add `npm audit` and govulncheck to CI if not already present. +- Warn users when saving or connecting direct VNC profiles without SSH tunnelling. + +Short-term: + +- Replace deprecated `xterm` packages with maintained `@xterm/*` packages. +- Add frontend tests for DOM injection via filenames and imported profile metadata. +- Add streaming drag-drop upload support or route large drops through the native file upload path. + +Medium-term: + +- Add release artifact signing/notarization and checksums with provenance. +- Add application-level limits for RAW history, terminal recording size, SFTP listing size, and GitHub error body reads. + +Long-term: + +- Add a security-focused CI job: tests, `npm audit`, govulncheck, secret scanning, and static DOM-sink checks. +- Introduce a profile schema version and migration/normalization layer for imports. + +## 19. False Positives / Needs Manual Verification + +- `govulncheck -show verbose` initially reported module-level `x/net` advisories that were not reachable. The module was still upgraded to remove latent risk. +- Direct VNC is intentionally supported; risk depends on network trust and VNC server security type. +- File-drop XSS was fixed by code inspection; manual Wails UI verification should still be added. +- No live external service testing was performed. + +## 20. Final Notes + +The repo is in a materially better state after this run: profile data is validated before storage, local resource-consumption paths are bounded, the file-drop DOM sink is escaped, dependency scanners are clean, and release dependency installation is more reproducible. + +The main residual security posture issue is user-selected insecure connectivity: Telnet/RAW/direct VNC remain useful but should be presented with clear safety context. diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 268a7de..b57a63f 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -17,13 +17,13 @@ "xterm-addon-web-links": "0.9.0" }, "devDependencies": { - "esbuild": "^0.28.0" + "esbuild": "^0.28.1" } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz", - "integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", + "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", "cpu": [ "ppc64" ], @@ -38,9 +38,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz", - "integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", + "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", "cpu": [ "arm" ], @@ -55,9 +55,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz", - "integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", + "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", "cpu": [ "arm64" ], @@ -72,9 +72,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz", - "integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", + "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", "cpu": [ "x64" ], @@ -89,9 +89,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz", - "integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", + "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", "cpu": [ "arm64" ], @@ -106,9 +106,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz", - "integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", + "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", "cpu": [ "x64" ], @@ -123,9 +123,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz", - "integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", + "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", "cpu": [ "arm64" ], @@ -140,9 +140,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz", - "integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", + "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", "cpu": [ "x64" ], @@ -157,9 +157,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz", - "integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", + "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", "cpu": [ "arm" ], @@ -174,9 +174,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz", - "integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", + "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", "cpu": [ "arm64" ], @@ -191,9 +191,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz", - "integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", + "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", "cpu": [ "ia32" ], @@ -208,9 +208,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz", - "integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", + "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", "cpu": [ "loong64" ], @@ -225,9 +225,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz", - "integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", + "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", "cpu": [ "mips64el" ], @@ -242,9 +242,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz", - "integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", + "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", "cpu": [ "ppc64" ], @@ -259,9 +259,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz", - "integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", + "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", "cpu": [ "riscv64" ], @@ -276,9 +276,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz", - "integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", + "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", "cpu": [ "s390x" ], @@ -293,9 +293,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz", - "integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", + "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", "cpu": [ "x64" ], @@ -310,9 +310,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz", - "integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", + "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", "cpu": [ "arm64" ], @@ -327,9 +327,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz", - "integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", + "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", "cpu": [ "x64" ], @@ -344,9 +344,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz", - "integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", + "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", "cpu": [ "arm64" ], @@ -361,9 +361,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz", - "integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", + "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", "cpu": [ "x64" ], @@ -378,9 +378,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz", - "integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", + "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", "cpu": [ "arm64" ], @@ -395,9 +395,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz", - "integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", + "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", "cpu": [ "x64" ], @@ -412,9 +412,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz", - "integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", + "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", "cpu": [ "arm64" ], @@ -429,9 +429,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz", - "integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", + "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", "cpu": [ "ia32" ], @@ -446,9 +446,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz", - "integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", + "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", "cpu": [ "x64" ], @@ -469,9 +469,9 @@ "license": "MPL-2.0" }, "node_modules/esbuild": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz", - "integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", + "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -482,32 +482,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.28.0", - "@esbuild/android-arm": "0.28.0", - "@esbuild/android-arm64": "0.28.0", - "@esbuild/android-x64": "0.28.0", - "@esbuild/darwin-arm64": "0.28.0", - "@esbuild/darwin-x64": "0.28.0", - "@esbuild/freebsd-arm64": "0.28.0", - "@esbuild/freebsd-x64": "0.28.0", - "@esbuild/linux-arm": "0.28.0", - "@esbuild/linux-arm64": "0.28.0", - "@esbuild/linux-ia32": "0.28.0", - "@esbuild/linux-loong64": "0.28.0", - "@esbuild/linux-mips64el": "0.28.0", - "@esbuild/linux-ppc64": "0.28.0", - "@esbuild/linux-riscv64": "0.28.0", - "@esbuild/linux-s390x": "0.28.0", - "@esbuild/linux-x64": "0.28.0", - "@esbuild/netbsd-arm64": "0.28.0", - "@esbuild/netbsd-x64": "0.28.0", - "@esbuild/openbsd-arm64": "0.28.0", - "@esbuild/openbsd-x64": "0.28.0", - "@esbuild/openharmony-arm64": "0.28.0", - "@esbuild/sunos-x64": "0.28.0", - "@esbuild/win32-arm64": "0.28.0", - "@esbuild/win32-ia32": "0.28.0", - "@esbuild/win32-x64": "0.28.0" + "@esbuild/aix-ppc64": "0.28.1", + "@esbuild/android-arm": "0.28.1", + "@esbuild/android-arm64": "0.28.1", + "@esbuild/android-x64": "0.28.1", + "@esbuild/darwin-arm64": "0.28.1", + "@esbuild/darwin-x64": "0.28.1", + "@esbuild/freebsd-arm64": "0.28.1", + "@esbuild/freebsd-x64": "0.28.1", + "@esbuild/linux-arm": "0.28.1", + "@esbuild/linux-arm64": "0.28.1", + "@esbuild/linux-ia32": "0.28.1", + "@esbuild/linux-loong64": "0.28.1", + "@esbuild/linux-mips64el": "0.28.1", + "@esbuild/linux-ppc64": "0.28.1", + "@esbuild/linux-riscv64": "0.28.1", + "@esbuild/linux-s390x": "0.28.1", + "@esbuild/linux-x64": "0.28.1", + "@esbuild/netbsd-arm64": "0.28.1", + "@esbuild/netbsd-x64": "0.28.1", + "@esbuild/openbsd-arm64": "0.28.1", + "@esbuild/openbsd-x64": "0.28.1", + "@esbuild/openharmony-arm64": "0.28.1", + "@esbuild/sunos-x64": "0.28.1", + "@esbuild/win32-arm64": "0.28.1", + "@esbuild/win32-ia32": "0.28.1", + "@esbuild/win32-x64": "0.28.1" } }, "node_modules/xterm": { diff --git a/frontend/package.json b/frontend/package.json index 04d58de..9dafde6 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -19,6 +19,6 @@ "xterm-addon-web-links": "0.9.0" }, "devDependencies": { - "esbuild": "^0.28.0" + "esbuild": "^0.28.1" } } diff --git a/frontend/package.json.md5 b/frontend/package.json.md5 index 58a75ed..b7744fd 100755 --- a/frontend/package.json.md5 +++ b/frontend/package.json.md5 @@ -1 +1 @@ -0eb34f66d9120fafc023eb90e9144592 \ No newline at end of file +98d10e21267ecd49ba1108b344949fbf diff --git a/frontend/src/js/terminal.js b/frontend/src/js/terminal.js index 0b411bc..9ad08be 100644 --- a/frontend/src/js/terminal.js +++ b/frontend/src/js/terminal.js @@ -7,6 +7,8 @@ /* global Terminal, FitAddon, SearchAddon, WebLinksAddon, Unicode11Addon */ + const MAX_INLINE_UPLOAD_BYTES = 25 * 1024 * 1024; + /** * Encode a string as UTF-8 bytes then base64-encode them. * Unlike bare btoa(), this handles characters above U+007F correctly @@ -716,7 +718,7 @@ } _promptFileDropAction(files, canUpload) { - const { createElement, formatBytes } = window.NexusTerminal; + const { createElement, escapeHtml, formatBytes } = window.NexusTerminal; return new Promise((resolve) => { const backdrop = createElement("div", "modal-backdrop"); const modal = createElement("div", "modal modal-sm"); @@ -736,7 +738,7 @@