{"metadata": {"vulnerability": "GHSA-F3FJ-9625-RV3M", "count": 3, "kinds": {"milestone": 1, "sighting": 1, "kev": 0, "other": 1}}, "data": [{"timestamp": "2026-10-30T14:53:57Z", "date_only": false, "value": "2026-10-30T14:53:57Z", "kind": "milestone", "label": "Published", "source": "github", "record": "GHSA-F3FJ-9625-RV3M", "field": "published", "metric_role": "disclosure", "metric_basis": "recorded_event"}, {"timestamp": "2026-10-30T14:53:57Z", "date_only": false, "value": "2026-10-30T14:53:57Z", "kind": "other", "label": "Updated", "source": "github", "record": "GHSA-F3FJ-9625-RV3M", "field": "modified"}, {"timestamp": "2026-10-30T17:30:51Z", "date_only": false, "value": "2026-10-30T17:30:51.000000Z", "kind": "sighting", "label": "Seen", "source": "https://gist.github.com/alon710/e546477f9047750ab52bd87b8a3f2051", "record": "GHSA-F3FJ-9625-RV3M", "field": "creation_timestamp", "uuid": "fdcfa35c-5d9c-4d0f-9d7a-ee77fec94686", "content": "# GHSA-F3FJ-9625-RV3M: GHSA-f3fj-9625-rv3m: Race Condition in Soft Serve Repository Cache Invalidation\n\n&gt; **CVSS Score:** 5.9\n&gt; **Published:** 2026-10-30\n&gt; **Full Report:** https://cvereports.com/reports/GHSA-F3FJ-9625-RV3M\n\n## Summary\nA Time-of-Check to Time-of-Use (TOCTOU) race condition in Charmbracelet Soft Serve versions 0.6.0 through 0.12.2 allows unauthenticated users to retain read access to repositories after their visibility is changed from public to private. The flaw stems from premature cache invalidation in the SetPrivate method prior to committing the visibility update to the underlying database. Concurrent read requests arriving during the database transaction window repopulate the non-expiring in-memory LRU cache with stale public metadata, bypassing access controls across HTTP, SSH, and Git protocols until the server process is restarted.\n\n## TL;DR\nSoft Serve versions &gt;= 0.6.0 and &lt; 0.12.3 contain a cache invalidation race condition in the SetPrivate repository method. Evicting the in-memory LRU cache before committing the database transaction allows concurrent unauthenticated requests to re-cache the stale public state, leaving private repositories perpetually readable by anonymous users. Upgrade to version 0.12.3, which removes the in-memory repository cache entirely.\n\n## Exploit Status: POC\n\n## Technical Details\n\n- **Advisory ID**: GHSA-f3fj-9625-rv3m\n- **Vulnerability Class**: CWE-362 / CWE-367 (TOCTOU Race Condition)\n- **CVSS v3.1 Score**: 5.9 Medium (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N)\n- **Affected Versions**: github.com/charmbracelet/soft-serve &gt;= 0.6.0, &lt; 0.12.3\n- **Patched Version**: 0.12.3\n- **Attack Vector**: Network (HTTP, SSH, and git:// protocols)\n- **Security Impact**: Unauthenticated read access to private Git repositories\n- **Exploit Status**: Proof-of-Concept in unit tests (No KEV listing)\n\n## Affected Systems\n\n- github.com/charmbracelet/soft-serve\n- **soft-serve**: &gt;= 0.6.0, &lt; 0.12.3 (Fixed in: `0.12.3`)\n\n## Mitigation\n\n- Upgrade Soft Serve to version 0.12.3 or later to eliminate the vulnerable in-memory repository cache.\n- Restart the Soft Serve server process immediately after changing any repository's visibility from public to private to flush stale in-memory cache entries.\n- Create confidential repositories with the private flag (-p) enabled at initialization rather than toggling visibility after creation.\n- Disable anonymous read access globally by setting anon_access to no-access if unauthenticated public access is not required.\n\n**Remediation Steps:**\n1. Update the Soft Serve binary or Go module to v0.12.3 using 'go get -u github.com/charmbracelet/soft-serve@v0.12.3' or via system package managers.\n2. Restart all running Soft Serve service instances ('systemctl restart soft-serve') to ensure the updated binary is active and any previously cached in-memory state is cleared.\n3. Audit server access logs for any unauthenticated Git read operations (such as GET requests to /.git/info/refs) that occurred after a repository was marked private.\n\n## References\n\n- [Soft Serve Security Advisory GHSA-f3fj-9625-rv3m](https://github.com/charmbracelet/soft-serve/security/advisories/GHSA-f3fj-9625-rv3m)\n- [GitHub Advisory Database: GHSA-f3fj-9625-rv3m](https://github.com/advisories/GHSA-f3fj-9625-rv3m)\n- [Fix Commit: Remove in-memory repository cache (5b307b4da4db285f797cc028b381ba4d3d853019)](https://github.com/charmbracelet/soft-serve/commit/5b307b4da4db285f797cc028b381ba4d3d853019)\n- [Fix Commit: Send visibility webhook only when visibility changes (0a4e6f0b7e063927c7128756e1c1b3db871edabf)](https://github.com/charmbracelet/soft-serve/commit/0a4e6f0b7e063927c7128756e1c1b3db871edabf)\n- [Prior Commit: Implement database module and abstract backend (e398b4dde723437f637b06710e0938d349b360e8)](https://github.com/charmbracelet/soft-serve/commit/e398b4dde723437f637b06710e0938d349b360e8)\n- [Soft Serve Release v0.12.3](https://github.com/charmbracelet/soft-serve/releases/tag/v0.12.3)\n- [Reporter Profile: sondt99](https://github.com/sondt99)\n\n\n---\n*Generated by [CVEReports](https://cvereports.com/reports/GHSA-F3FJ-9625-RV3M) - Automated Vulnerability Intelligence*", "url": "https://gist.github.com/alon710/e546477f9047750ab52bd87b8a3f2051"}], "metrics": {"as_of": "2026-11-05T03:54:41.757Z", "anchors": {"origin": {"timestamp": "2026-10-30T14:53:57Z", "date_only": false, "value": "2026-10-30T14:53:57Z", "kind": "milestone", "label": "Published", "source": "github", "record": "GHSA-F3FJ-9625-RV3M", "field": "published", "metric_role": "disclosure", "metric_basis": "recorded_event"}, "discovery": null, "report": null, "acknowledgement": null, "disclosure": {"timestamp": "2026-10-30T14:53:57Z", "date_only": false, "value": "2026-10-30T14:53:57Z", "kind": "milestone", "label": "Published", "source": "github", "record": "GHSA-F3FJ-9625-RV3M", "field": "published", "metric_role": "disclosure", "metric_basis": "recorded_event"}, "exploit_publication": null, "exploitation": null, "patch": null}, "vendor_response_time": {"available": false, "missing": ["start", "end"]}, "time_to_exploit": {"available": false, "missing": ["end"]}, "disclosure_to_exploit": {"available": false, "missing": ["end"]}, "disclosure_to_exploit_publication": {"available": false, "missing": ["end"]}, "time_to_patch": {"available": false, "missing": ["start", "end"]}, "total_time_to_patch": {"available": false, "missing": ["start", "end"]}, "disclosure_to_patch": {"available": false, "missing": ["end"]}, "time_unpatched": {"available": true, "seconds": 478844.757871, "hours": 133.01243274194445, "days": 5.5421846975810185, "min_seconds": 478844.757871, "max_seconds": 478844.757871, "approximate": false, "ongoing": true, "order_known": true, "batch_listing": false, "end_before_start": false, "start": {"timestamp": "2026-10-30T14:53:57Z", "date_only": false, "value": "2026-10-30T14:53:57Z", "kind": "milestone", "label": "Published", "source": "github", "record": "GHSA-F3FJ-9625-RV3M", "field": "published", "metric_role": "disclosure", "metric_basis": "recorded_event"}, "end": {"timestamp": "2026-11-05T03:54:41.757Z", "date_only": false, "label": "As of", "source": "Calculation clock"}}, "exploitation_to_patch": {"available": false, "missing": ["start"]}, "exploit_publication_to_patch": {"available": false, "missing": ["start"]}}}
