Skip to content
Draft
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
13 changes: 13 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>

#include <wolfssl/ssl.h>

#include <wolfclu/clu_header_main.h>
Expand Down Expand Up @@ -147,6 +149,17 @@ 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(). */
for (cp = peer; *cp != '\0'; cp++) {
if (!isalnum((unsigned char)*cp) &&
*cp != '.' && *cp != '-') {
err_sys("invalid character in hostname");
return;
}
}

XSTRNCPY(cmd, "host ", 6);
XSTRNCAT(cmd, peer, 99 - XSTRLEN(cmd));
Expand Down
24 changes: 15 additions & 9 deletions src/x509/clu_x509_sign.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ int wolfCLU_GenChimeraCertSign(WOLFSSL_BIO *bioCaKey, WOLFSSL_BIO *bioAltCaKey,
const char *altSigAlgOid = "2.5.29.73";
const char *altSigValOid = "2.5.29.74";

/*
/*
* LARGE_TEMO_SZ defines the size of temporary buffers used for signature key,
* verification key and signature value buffers.
* The value 11264 is enough for P-521 and ML-DSA-87 PEM certs.
Expand Down Expand Up @@ -397,7 +397,7 @@ int wolfCLU_GenChimeraCertSign(WOLFSSL_BIO *bioCaKey, WOLFSSL_BIO *bioAltCaKey,
ret = WOLFCLU_FATAL_ERROR;
}
}

if (ret == 0) {
XMEMSET(caKeyBuf, 0, caKeySz); /* clear original buffer */
caKeySz = derObj->length;
Expand Down Expand Up @@ -667,13 +667,13 @@ int wolfCLU_GenChimeraCertSign(WOLFSSL_BIO *bioCaKey, WOLFSSL_BIO *bioAltCaKey,

if (ret == WOLFCLU_SUCCESS) {
switch (level) {
case 2:
case 2:
newCert.sigType = CTC_SHA256wECDSA;
break;
case 3:
case 3:
newCert.sigType = CTC_SHA384wECDSA;
break;
case 5:
case 5:
newCert.sigType = CTC_SHA512wECDSA;
break;
}
Expand All @@ -691,7 +691,7 @@ int wolfCLU_GenChimeraCertSign(WOLFSSL_BIO *bioCaKey, WOLFSSL_BIO *bioAltCaKey,
else {
ret = WOLFCLU_SUCCESS;
}
}
}
}

if (ret == WOLFCLU_SUCCESS) {
Expand All @@ -715,7 +715,7 @@ int wolfCLU_GenChimeraCertSign(WOLFSSL_BIO *bioCaKey, WOLFSSL_BIO *bioAltCaKey,
}

if (ret == WOLFCLU_SUCCESS && isCA) {
ret = wc_MakeCert(&newCert, scratchBuf,
ret = wc_MakeCert(&newCert, scratchBuf,
scratchSz, NULL, &caKey, &rng);
if (ret <= 0) {
wolfCLU_LogError("Error making certificate");
Expand All @@ -732,7 +732,7 @@ int wolfCLU_GenChimeraCertSign(WOLFSSL_BIO *bioCaKey, WOLFSSL_BIO *bioAltCaKey,
scratchSz = ret;
ret = WOLFCLU_SUCCESS;
}
}
}
}
else if (ret == WOLFCLU_SUCCESS && !isCA) {
ret = wc_MakeCert(&newCert, scratchBuf, scratchSz,
Expand Down Expand Up @@ -1274,7 +1274,13 @@ int wolfCLU_CertSign(WOLFCLU_CERT_SIGN* csign, WOLFSSL_X509* x509)
case WC_HASH_TYPE_BLAKE2B:
case WC_HASH_TYPE_BLAKE2S:

#if LIBWOLFSSL_VERSION_HEX > 0x05001000
#if LIBWOLFSSL_VERSION_HEX >= 0x05009000
case WC_HASH_TYPE_SHA512_224:
case WC_HASH_TYPE_SHA512_256:
case WC_HASH_TYPE_SHAKE128:
case WC_HASH_TYPE_SHAKE256:
case WC_HASH_TYPE_SM3:
#elif LIBWOLFSSL_VERSION_HEX > 0x05001000
#ifndef WOLFSSL_NOSHA512_224
case WC_HASH_TYPE_SHA512_224:
#endif
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.
# 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
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
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
if [ -f "$INJFILE" ]; then
echo "SECURITY FAILURE: command injection via hostname (pipe)"
rm -f "$INJFILE"
exit 99
fi

echo "Done"
exit 0
2 changes: 1 addition & 1 deletion tests/ocsp/ocsp-interop-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ if [ $RESULT = 0 ]; then
fi

# Check for error message
grep -qi "fail\|error\|not found\|unable" "$TEST_DIR/test6.log"
grep -qi "fail\|error\|not found\|unable\|no such\|could not" "$TEST_DIR/test6.log"
if [ $? != 0 ]; then
echo "Test 6 failed: expected error message about invalid file"
exit 99
Expand Down
Loading