Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/client/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
#endif
#include <wolfssl/wolfcrypt/settings.h>

#include <ctype.h>
Comment thread
JacobBarthelmeh marked this conversation as resolved.

#include <wolfssl/ssl.h>

#include <wolfclu/clu_header_main.h>
Expand Down Expand Up @@ -147,6 +149,21 @@ static WC_INLINE void clu_build_addr(SOCKADDR_IN4_T* addr, SOCKADDR_IN6_T* ipv6,
FILE* fp;
char host_out[100];
char cmd[100];
const char* cp;

/* Validate hostname: only allow characters valid in DNS names
* (RFC 1123) to prevent shell injection via popen().
* Use explicit ASCII ranges instead of isalnum() to avoid
* locale-dependent behavior. */
for (cp = peer; *cp != '\0'; cp++) {
Comment thread
miyazakh marked this conversation as resolved.
if (!((*cp >= 'A' && *cp <= 'Z') ||
(*cp >= 'a' && *cp <= 'z') ||
(*cp >= '0' && *cp <= '9') ||
*cp == '.' || *cp == '-')) {
err_sys("invalid character in hostname");
return;
}
}
Comment thread
miyazakh marked this conversation as resolved.

XSTRNCPY(cmd, "host ", 6);
XSTRNCAT(cmd, peer, 99 - XSTRLEN(cmd));
Expand Down
34 changes: 34 additions & 0 deletions tests/client/client-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,39 @@ fi

rm tmp.crt

# Regression tests: shell injection via hostname must not execute injected command.
Comment thread
JacobBarthelmeh marked this conversation as resolved.
# Applies to the WOLFSSL_USE_POPEN_HOST path where peer is concatenated into a
# popen() shell command. On other builds, getaddrinfo/gethostbyname reject
# these hostnames before any shell is involved, so the tests pass either way.
INJFILE="clu_injection_probe.txt"
rm -f "$INJFILE"

# Semicolon: "evil.com;touch clu_injection_probe.txt" passed as peer
./wolfssl s_client -connect 'evil.com;touch clu_injection_probe.txt:443' \
2>/dev/null
Comment thread
miyazakh marked this conversation as resolved.
if [ -f "$INJFILE" ]; then
echo "SECURITY FAILURE: command injection via hostname (semicolon)"
rm -f "$INJFILE"
exit 99
fi

# Command substitution: "$(touch clu_injection_probe.txt)" passed as peer
./wolfssl s_client -connect 'evil$(touch clu_injection_probe.txt).com:443' \
2>/dev/null
Comment thread
miyazakh marked this conversation as resolved.
if [ -f "$INJFILE" ]; then
echo "SECURITY FAILURE: command injection via hostname (command substitution)"
rm -f "$INJFILE"
exit 99
fi

# Pipe: "evil.com|touch clu_injection_probe.txt" passed as peer
./wolfssl s_client -connect 'evil.com|touch clu_injection_probe.txt:443' \
2>/dev/null
Comment thread
miyazakh marked this conversation as resolved.
if [ -f "$INJFILE" ]; then
echo "SECURITY FAILURE: command injection via hostname (pipe)"
rm -f "$INJFILE"
exit 99
fi

echo "Done"
exit 0
Loading