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