Skip to content

Commit 42f48d3

Browse files
committed
Reject traversal filenames in SCP receive path
Disallow '.' components and path separators in GetScpFileName so malicious SCP clients cannot escape the configured base directory.
1 parent c10896c commit 42f48d3

File tree

1 file changed

+26
-1
lines changed

1 file changed

+26
-1
lines changed

src/wolfscp.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -966,6 +966,7 @@ static int GetScpFileName(WOLFSSH* ssh, byte* buf, word32 bufSz,
966966
{
967967
int ret = WS_SUCCESS;
968968
word32 idx, len;
969+
const char* fileName;
969970

970971
if (ssh == NULL || buf == NULL || inOutIdx == NULL)
971972
return WS_BAD_ARGUMENT;
@@ -977,6 +978,31 @@ static int GetScpFileName(WOLFSSH* ssh, byte* buf, word32 bufSz,
977978
ret = WS_SCP_CMD_E;
978979

979980
if (ret == WS_SUCCESS) {
981+
word32 i;
982+
983+
fileName = (const char*)(buf + idx);
984+
985+
if (len == 0 ||
986+
(len == 1 && fileName[0] == '.') ||
987+
(len == 2 && fileName[0] == '.' && fileName[1] == '.')) {
988+
WLOG(WS_LOG_ERROR, "scp: invalid file name component received");
989+
wolfSSH_SetScpErrorMsg(ssh, "invalid file name");
990+
return WS_SCP_BAD_MSG_E;
991+
}
992+
993+
for (i = 0; i < len; i++) {
994+
char c = fileName[i];
995+
996+
if (c == '/' || c == '\\'
997+
#if defined(USE_WINDOWS_API) || defined(WOLFSSL_NUCLEUS)
998+
|| c == ':'
999+
#endif
1000+
) {
1001+
WLOG(WS_LOG_ERROR, "scp: invalid file name component received");
1002+
wolfSSH_SetScpErrorMsg(ssh, "invalid file name");
1003+
return WS_SCP_BAD_MSG_E;
1004+
}
1005+
}
9801006

9811007
if (ssh->scpFileName != NULL) {
9821008
WFREE(ssh->scpFileName, ssh->ctx->heap, DYNTYPE_STRING);
@@ -3090,4 +3116,3 @@ int wsScpSendCallback(WOLFSSH* ssh, int state, const char* peerRequest,
30903116
#endif /* WOLFSSH_SCP_USER_CALLBACKS */
30913117

30923118
#endif /* WOLFSSH_SCP */
3093-

0 commit comments

Comments
 (0)