Gin-vue-admin is a popular open-source management system built with the Gin web framework (Go) for the backend and Vue.js for the frontend. It offers a modern, flexible backend panel used by individual developers and small businesses around the world. However, up to version 2.5.3, a critical security flaw existed—CVE-2022-39345—that made file uploads dangerous and potentially let attackers access sensitive files on your server.
This post will break down what CVE-2022-39345 is, how the vulnerability works, and how to protect yourself, using simple language and code examples. If you have a Gin-vue-admin installation, update to 2.5.4 or later immediately!
What is CVE-2022-39345?
CVE-2022-39345 is a path traversal vulnerability in Gin-vue-admin below version 2.5.4. This type of bug lets an attacker manipulate file paths in uploads—so instead of uploading a file to the safe, expected folder, they "traverse" up the directory tree and upload files anywhere on the server.
Impact:
How Path Traversal Happened
When an application lets users upload files, it should strictly control the filepath—never trusting user-provided names or directories. If the upload handler takes a filename directly from what the user submits, like:
dst := fmt.Sprintf("./uploads/%s", filename) // ⚠️ Danger!
c.SaveUploadedFile(file, dst)
And if the attacker sends a filename like ../../../../etc/passwd, the uploaded file gets saved far outside ./uploads/, possibly overwriting critical data.
Even worse, the attacker can use this to place a web shell (a script the attacker can execute remotely) anywhere the server has write permissions, like the static web directory.
Imagine the upload API works like this
func UploadFile(c *gin.Context) {
file, _ := c.FormFile("file")
filename := file.Filename
dst := fmt.Sprintf("./uploads/%s", filename)
c.SaveUploadedFile(file, dst)
c.JSON(http.StatusOK, gin.H{"msg": "upload success"})
}
Let’s say the attacker uploads a PHP shell (or any script) and crafts the filename like
filename=../../../public/webshell.php
Malicious HTTP request
POST /api/upload
Content-Type: multipart/form-data; boundary=-------------boundary
-------------boundary
Content-Disposition: form-data; name="file"; filename="../../../public/webshell.php"
<PHPSHELLCODE>
-------------boundary--
Result:
Their PHP shell is now accessible at https://yourdomain.com/webshell.php (or anywhere else on the server that the app can write).
The Patch
Gin-vue-admin 2.5.4 fixed this by sanitizing filenames and paths. Here's what secure code looks like:
import "path/filepath"
import "strings"
func sanitizeFileName(filename string) string {
// Only keep base name, remove path elements.
filename = filepath.Base(filename)
// Optionally, whitelist extensions or characters.
return filename
}
func UploadFile(c *gin.Context) {
file, _ := c.FormFile("file")
filename := sanitizeFileName(file.Filename)
dst := filepath.Join("./uploads", filename)
c.SaveUploadedFile(file, dst)
c.JSON(http.StatusOK, gin.H{"msg": "upload success"})
}
Notice how filepath.Base() ensures attackers can’t use paths like ../../… to escape the uploads folder anymore.
No Workarounds — Upgrade Now
There are NO effective workarounds.
If you use Gin-vue-admin, upgrade to v2.5.4 or later instantly. This is the only way to stay safe.
More References
- Original advisory
- CVE Record
- Gin-vue-admin repository
- Path Traversal Explanation (OWASP)
If you run Gin-vue-admin below 2.5.4, your system is at severe risk. PATCH IT NOW.
*For demonstrations, source links, and official patch information, see the references above. Stay secure!*
Timeline
Published on: 10/25/2022 17:15:00 UTC
Last modified on: 10/26/2022 00:54:00 UTC