Skip to content

Releases: RobinMJD/kutt

Kutt v3.2.6-sr94.66 security maintenance

Choose a tag to compare

@RobinMJD RobinMJD released this 02 Oct 11:25

Security maintenance

  • Update nodemailer to 10.0.13, pin transitive ip-address to 10.7.1, and refresh vulnerable development dependencies. Both production and full npm audits report zero known advisories for the tested lockfile.
  • Serialize first-administrator creation on an empty database. The concurrent regression reproduces the original two-admin race and verifies one winner on SQLite, MySQL, and PostgreSQL.
  • Reject unsafe redirect URI schemes and web URLs containing embedded credentials, even when the optional destination host allowlist is unset. Existing unsafe rows are retained but return 410 without a Location header until repaired. Supported web and common external-app destinations remain available; inventory custom-scheme links before upgrading.
  • Show any legacy unsafe target or domain homepage as plain text in management tables, not a clickable URL. The original value remains visible so an authorized owner can repair it; safe HTTPS destinations remain clickable.
  • Default TRUST_PROXY to false and ENABLE_RATE_LIMIT to true. Deployments behind a trusted reverse proxy must explicitly opt in to proxy trust and sanitize forwarded headers at the edge.
  • Run the published source image as UID/GID 1000. Existing root-owned SQLite volumes require a backup-first, one-time ownership change before upgrading; see deployment guidance. Fresh named volumes inherit the writable ownership automatically.

The source and homelab-wrapper candidate scans have no Critical or High package matches. They retain three Medium package matches for one unfixed BusyBox wget advisory, CVE-2025-60876; Kutt does not use that applet. See the dated audit ledger for evidence, scope, and residual risks.

Publishing this tag does not deploy it. The homelab cutover is separately gated on a fresh local and NAS backup, writable restore, WAF/SSO and public-redirect checks, and monitored health.

v3.2.6-sr94.65: upstream issue fixes

Choose a tag to compare

@RobinMJD RobinMJD released this 25 Sep 01:00

Applicable upstream issues

  • Fix numeric-leading email searches in the admin Users list and count (thedevs-network#1033).
  • Update ioredis within major 5 for DNS-family handling (thedevs-network#1020); AAAA-only DNS is not emulated in the smoke test.
  • Preserve published links, visits and domains when an account is deleted, and show the retained-link count before confirmation (thedevs-network#1008).
  • Correct annual statistics to twelve calendar months (thedevs-network#1000).
  • Return HTTP 409 for duplicate custom aliases without mutating the existing link (thedevs-network#975).
  • Emit UTC ISO 8601 API expiry output while retaining relative-expiry input (thedevs-network#930).
  • Accept one-digit URL ports (thedevs-network#926).
  • Generate verification token and expiry for admin-created unverified users (thedevs-network#825).

All 69 open upstream issues were reviewed: eight fixed here, 31 already covered, ten hosted/unreproduced, and 20 separate feature or policy requests. Issue-by-issue disposition.

Verification

Source tag at 406fc810d6780a9b5343df89f6c171a6db5d6379; main CI, tag/image CI, and Shortcut CI passed. Source image ghcr.io/robinmjd/kutt@sha256:054a624d1ad162f3551d9c8f2b5015f8489e7354820c812bf9c24ce8360444d5 matched the tagged source. The hardened homelab image passed full isolated tests and an image scan with zero Critical/High and three Medium findings.

Live public WAF/SSO smoke, signed Authentik logout, original-record checks, two healthy samples and full lab validation passed. Pre- and post-change backups were copied off-host; the post-change local and NAS restores matched byte-for-byte across 75 files and passed writable candidate-image database recovery. Existing records and secrets were retained.

Compatibility and recovery

No schema, WAF, SSO, CSP, TLS or public-redirect policy change. API expire_in output is now UTC ISO 8601; relative input still works. Image-only rollback to .64 preserves the current database and secrets but restores the old defects. Do not overwrite newer data with a stale snapshot. Reload open admin pages after upgrading.

v3.2.6-sr94.64: responsive interface polish

Choose a tag to compare

@RobinMJD RobinMJD released this 23 Sep 13:23

Management interface polish

  • Align labelled search, sorting and pagination controls; paste/native clear also reset pagination.
  • Restore visible dark-mode action icons with semantic foreground/background colours and measured SVG paint contrast.
  • Remove the large gap between link creation and recent links. Compact Library actions, Settings navigation and Admin filters.
  • Use consistent controls, stable targets and visible keyboard focus; keep translated selections readable at narrow widths.
  • Replace blank zero-visit analytics visualizations with a compact empty state while retaining totals, filters and exports.

Verification

Source 418a37f5ab4fcbc96c991b106a5499056dd931cc passed main CI and immutable tag CI. The byte-reconciled contribution passed CI and is included in upstream PR #1046.

The interface matrix covers 22 management pages plus creation/list/empty/edit/confirmation states at 1440/1024/768/390/320 pixels, in both themes and all three languages: 780 captures and 720 actual SVG paint checks. The 198-page localization suite also passes on macOS and isolated Ubuntu Chromium. Full application, authorization, database, OIDC, TLS and existing browser regression passed in CI.

The exact hardened deployment passed fresh scanning (zero Critical/High; three existing Medium BusyBox-package findings), full regression, pre/post off-host byte-verified and writable recovery, public API/SSO/logout checks and repeated health checks. Public browser acceptance covered 72 pages across 18 locale/theme/viewport combinations, plus three native date/time creation workflows. No JavaScript, CSP or network failures were recorded; disposable fixtures were removed and original records retained.

Source image: ghcr.io/robinmjd/kutt@sha256:39e919ce8bb1bf7aa6591fa06b81e3ba9e835a114dc7ab49adae6a35fa5142a1.

Compatibility and recovery

No schema migration, API format, permission, redirect, secret or WAF/SSO/CSP/TLS policy change. Public short links remain public. Existing UTC start/end pickers and legacy expiry edits remain compatible. Operator custom CSS still loads last.

Reload open management pages after upgrading. A rollback to the verified .59 image/configuration retains current data and schedules; never restore an old database as a styling rollback.

Candidates .60–.63 were not deployed. Their immutable tags and failed checks remain traceable; .64 includes the resulting screenshot-helper, mobile text-fit and Linux Admin sizing corrections. Native Safari/Firefox and physical-device acceptance are not claimed.

3.2.6-sr94.59: Start and end date/time pickers

Choose a tag to compare

@RobinMJD RobinMJD released this 23 Sep 10:27

Start and end date/time pickers

The homepage creation form now uses optional calendar/time pickers instead of
the free-text "Expire in" field. Selected values display exactly as
yyyy-MM-dd HH:mm:ss, including seconds, with explicitly labeled UTC times.
English, French and Spanish are supported.

  • Blank start: available immediately. Blank end: no scheduled expiration.
  • Apply, Cancel, Escape and Clear preserve predictable draft behavior.
  • Validation focuses the visible field and preserves the submitted dates.
  • Pending requests lock picker changes without dropping submitted timestamps.
  • Responsive keyboard-accessible controls fit desktop and narrow mobile views.

Existing links, users and secrets are preserved. The legacy expire_in API and
existing edit-expiry flows remain compatible. There is no schema migration;
the previous .58 image already enforces the stored start/end fields.
See the lifecycle guide
and deployment/recovery guide.

Verification

  • Exact release CI,
    main CI and
    curated upstream contribution CI passed.
  • Full isolated source and hardened-image regression, authorization boundaries,
    legacy expiry, migration compatibility and writable recovery passed.
  • All 18 EN/FR/ES, light/dark, desktop/mobile creation-picker combinations passed
    locally under enforced CSP. Live picker checks passed EN/1440, FR/390 and
    ES/320, with exact UTC seconds and active/scheduled/expired public redirects.
  • The deployed public community matrix passed 18 layouts and 1,602 browser
    requests, including QR decoding, contrast and downloads, with no recorded
    JavaScript, CSP or network failures. Disposable fixtures were removed.
  • Full public API and real Authentik-signed logout/replay passed. WAF, SSO,
    CSP, TLS and public short-link behavior were not weakened.
  • Pre/post local and NAS backups were byte-verified and write-restored. Original
    records, database integrity, monitored routes and repeated health checks passed.
  • Fresh scan: zero Critical/High findings; three Medium BusyBox-package matches
    for CVE-2025-60876 have no fixed version listed. Findings are not suppressed.

Source: 7f136a23ef4b4010566863d240d20345b9aee04c.
Published image: ghcr.io/robinmjd/kutt:v3.2.6-sr94.59 at
sha256:34481aeca5f7a26074f65fabcec77b34440d0bc331e2aa8ce019e9884dd149a2.
Chromium mobile-width tests are not physical Safari/iOS acceptance. These are
bounded test and scan results, not an exhaustive security certification.

3.2.6-sr94.58: community features and English/French/Spanish localization

Choose a tag to compare

@RobinMJD RobinMJD released this 22 Sep 15:26

Community Features And Translations

This release completes the approved 21-item community implementation:

  • English (default), French and Spanish with 1,519 messages per validated catalog, request-local translation, safe interpolation and an extensible language registry.
  • System/light/dark appearance, stable table sorting, Safari analytics and hostname/proxy/custom-domain routing corrections.
  • Verified database/Redis TLS, asymmetric OIDC support, transactional moderation and safe dotted aliases.
  • Staged/enforced CSP with fresh nonces and proxy-safe rendered HTML, including HTMX fragments, without expanding script permissions.
  • Branded QR PNG/SVG exports with bounded PNG validation, sanitized ephemeral logos and independently decoded output.
  • Optional signed OIDC administrator mapping, protected recovery and transactional checks against stale authority.
  • Optional separate management origin and explicit shared-domain grants, creator-isolated analytics and permanent scoped-token revocation.
  • Optional destination-host policy with consistent enforcement and authorized unchanged-target metadata repair.
  • Private authenticated metrics, accessible local country analytics and profile-led SQLite visit indexing.

Native analytics filters show long selected values fully at compact widths. CSV/JSON export controls now use the existing theme-button style and current-color icons. The regression reproduces the old dark contrast failure and checks normal, hover and focus contrast plus actual keyboard downloads in all three languages, both themes and three widths. French/Spanish copy clarifies geography percentages and uses consistent management wording.

These are independently adapted implementations, not blind merges of older proposals. The community guide credits upstream proposals and records each feature's boundaries and tests.

Compatibility And Recovery

Existing links, users and secrets are preserved. Public redirects remain public; management remains authenticated and WAF-protected. Optional role mapping, destination restrictions and management-host splitting are disabled by default. No domain is automatically shared or exposed.

Back up the database and original signing/encryption secrets together and verify a writable restore with the candidate image. Prefer fix-forward after authorization features are used: older images may ignore new state. Never downgrade populated authorization history or revive revoked credentials.

Candidates .50, .53 and .55 were rejected by live acceptance and rolled back; .51, .52 and .54 were superseded before deployment. Their immutable tags and evidence remain. .56 and .57 provide preceding functional evidence, not separate accepted releases. This release includes WAF-compatible QR transport, proxy HTML transformation protection, fresh mapped-administrator write authority, readable analytics filters, reviewed copy and accessible exports. No WAF/SSO/CSP exception was added.

Verification

  • Immutable release CI 35740453869, main CI 35740453470, and curated contribution CI 35741346684 passed, including real databases, Redis restart, OIDC, TLS and translated/themed browser suites.
  • Exact hardened-image full regression and fresh image scan passed: zero Critical/High findings. Three Medium BusyBox-package findings remain, with no fixed version listed in the scan database.
  • The deployed .58 public enforced-CSP matrix passed all 18 layouts, 108 export-contrast states, 36 verified keyboard downloads and independent QR decoding. Compact French/Spanish screenshots were reviewed. No network, JavaScript or CSP failures were recorded; the synthetic fixture was removed.
  • Original records, integrity and foreign keys remain unchanged. Two post-change samples 65 seconds apart passed with three required probes and zero restarts, scoped alerts, failed units or unhealthy containers; lab configuration validation passed.
  • Fresh pre/post backups were copied off-host to the NAS. Both 75-file byte checks and exact-image writable restores passed. This is Kutt recovery evidence, not USB SSD or whole-lab restore certification.
  • Source commit: 9360e913bbc2e9ace4f39688569dc5dab7a799e1. Published image: ghcr.io/robinmjd/kutt@sha256:5a3c2efa558b2d915e41210060612971ead7463d65428869102e7656974d356b.

The final .58 public matrix covers 18 translated/theme/width layouts with QR decoding, destination-policy views, geography, measured export contrast and actual CSV/JSON downloads. Full public shared-domain matrices belong to .56; .57 supplies the three-layout follow-up and full public API/real Authentik-signed logout/replay. The only subsequent runtime change is export HTML/CSS; those earlier results are not relabeled as .58 reruns.

SQLite receives the full regression suite; PostgreSQL 17 and MySQL 8.4 receive focused real-engine checks. MariaDB remains configuration-only. Chromium desktop/mobile-width testing is not physical Safari/Firefox/device certification. Physical printing, operator-specific IdP claims/custom templates and SMTP delivery remain separate deployment-specific checks. Scans and passing tests are bounded evidence, not certification that the software is vulnerability-free.

v3.2.6-sr94.49: English, French and Spanish

Choose a tag to compare

@RobinMJD RobinMJD released this 22 Sep 04:04

English, French and Spanish

  • English remains the default; choose French or Spanish from the native language selector.
  • UI, validation, browser feedback, email templates, dates and numbers use separate extensible translation catalogs. Documented stable keys, placeholder parity and request-local translation make additional languages straightforward.
  • User data, API identifiers, URLs, token scopes and cryptographic inputs are never translated. Locale selection retains strict same-origin checks and does not reset appearance preferences.
  • Includes mobile sorting-label and dark Library-icon readability corrections discovered in rendered review.

Validation and compatibility

The combined source regression and localization/security tests passed, together with 198 multilingual page layouts and 270 theme layouts. Final screenshot corrections have their own rendered assertions. CI verifies the versioned source again before publication. No database migration is required.

Physical-device, Safari/Firefox, custom operator-template and SMTP delivery acceptance are separate from these checks. The signed iOS Shortcut's embedded prompts remain English; its setup guides are translated. Homelab rollout and verified recovery are tracked in docs/COMMUNITY-FEATURE-ROADMAP.md; publication alone is not deployment acceptance.

See docs/LOCALIZATION.md for adding languages, custom templates, fallback, escaping and compatibility boundaries.

v3.2.6-sr94.48

Choose a tag to compare

@RobinMJD RobinMJD released this 22 Sep 03:35

Private performance metrics

  • Add an opt-in, independently authenticated metrics listener, separate from the public app and short-link aliases.
  • Report bounded request counters/duration histograms and worker process/event-loop gauges. Never label data with URLs, aliases, users, domains, IPs or credentials.
  • Fail startup on invalid credentials, bind addresses, worker ports or listener conflicts; support protected credential files and restart-based rotation.
  • Document private-network Prometheus setup, worker coverage, rotation and rollback. Off by default; no migration or existing account/link changes.

Validation

Focused and full isolated container regression passed, including token-file precedence, revocation after rotation, disabled mode, private/public listener separation, preserved /metrics aliases, bounded cardinality and cumulative histograms.

The test client now drains ordinary bodies on fresh connections (preserving streaming tests), avoiding Node's unread-response close assertion without retrying counted redirects. An offline response-schema fixture no longer relies on public DNS. Application assertions remain unchanged.

Publication is not deployment acceptance: exact-wrapper scans, recoverable backups and live checks are tracked separately in docs/COMMUNITY-FEATURE-ROADMAP.md.

v3.2.6-sr94.47: System, light and dark appearance

Choose a tag to compare

@RobinMJD RobinMJD released this 22 Sep 03:07

Accessible appearance modes

  • Add System, Light and Dark preferences with early initialization, native keyboard controls, cross-tab synchronization and graceful handling of unavailable browser storage.
  • Adjust management surfaces, chart labels, grid lines, tooltips, semantic colors and icons. Preserve white QR quiet zones and print sheets.
  • Keep the existing light palette, custom-style precedence, APIs, authorization and public redirects unchanged. No migration or new dependency.
  • Resolve static assets relative to the application directory so isolated or custom working-directory launches remain functional.

Validation: full source regression; rendered desktop/mobile workflows at 1440/390/320px across 15 routes in both themes; contrast, storage denial, keyboard, system changes, chart pixels and QR/print checks. Screenshot review prompted additional select-arrow and legacy-icon fixes.

Documentation: docs/THEMES.md. Release publication is separate from recoverable homelab deployment; the community ledger records deployment only after its live gates pass. Native Safari/Firefox and physical assistive-technology acceptance are not claimed by Chromium tests.

3.2.6-sr94.46: Safe dotted aliases

Choose a tag to compare

@RobinMJD RobinMJD released this 22 Sep 02:38

Safe Dotted Aliases

  • Use literal dotted aliases such as guide.pdf and docs/v2.release in personal, administrative, workspace and import workflows.
  • Reject reserved routes, traversal, ambiguous encoding, empty dot components and excessive length/depth consistently.
  • Preserve existing forwarding suffixes, alias retirement, domain scoping and legacy custom-alphabet compatibility. No migration or historical alias rewrite.
  • Fix MySQL stale-snapshot reservation races: ordinary and dotted aliases return controlled conflicts while preserving the winner and rolling back the loser.
  • Add real MySQL/PostgreSQL race and authorization tests, and 1440/390/320px browser checks for creation, editing, retained validation drafts and public redirects.

The full combined-source isolated regression passed. Release CI, exact homelab wrapper/security scan, recoverable backup and live acceptance remain separate deployment gates recorded in the community roadmap. No WAF/SSO changes; redirects remain public.

3.2.6-sr94.45: Transactional moderation

Choose a tag to compare

@RobinMJD RobinMJD released this 22 Sep 02:15

Transactional administrative moderation

  • Commit a selected user/link/domain/destination-IP ban and all selected related changes atomically. Invalid DNS or a protected administrator leaves no partial bans or audit entries.
  • Add administrator-only moderation/recovery pages, explicit per-record unban and a bounded private audit. Independent related bans are never silently restored.
  • Permanently revoke sessions/recovery tokens/API credentials on user ban/unban, with fresh locked authorization and token-race protection.
  • Preserve claimed-domain ownership/homepage; protect self-administrative deletion/ban and the final active administrator under concurrency.
  • Use SQL-authoritative ban reads and awaited, retryable cache invalidation. Preserve legacy full-key and JSON/form compatibility while rejecting malformed cascade values.
  • Add documented UI/API/recovery behavior, native keyboard/mobile workflows and real SQLite/MySQL/PostgreSQL concurrency coverage.

Migration adds mutation-lock and audit tables without changing existing bans or credentials. Do not downgrade populated audit tables; prefer explicit unban and fresh sign-in instead of restoring old credentials. No WAF/SSO/public-redirect relaxation.

Source validation and publication/deployment are separate gates, tracked in docs/COMMUNITY-FEATURE-ROADMAP.md. This release does not claim completion of the remaining community roadmap or localization work.