From b5427e3006d0bdb39e3c25e681a90736241710d2 Mon Sep 17 00:00:00 2001
From: Dirk
Date: Sun, 8 Sep 2024 16:32:19 +0200
Subject: [PATCH 01/28] Bump version to 3.2rc4
---
testssl.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/testssl.sh b/testssl.sh
index 4068440..cf02a8f 100755
--- a/testssl.sh
+++ b/testssl.sh
@@ -122,7 +122,7 @@ trap "child_error" USR1
########### Internal definitions
#
-declare -r VERSION="3.2rc3"
+declare -r VERSION="3.2rc4"
declare -r SWCONTACT="dirk aet testssl dot sh"
[[ "$VERSION" =~ dev|rc|beta ]] && \
SWURL="https://testssl.sh/dev/" ||
From dab177fda96dce0d5bb21f3ae8fcde86c9b6f4fb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emmanuel=20Fust=C3=A9?=
Date: Mon, 4 Nov 2024 17:27:18 +0100
Subject: [PATCH 02/28] Big client renego cleanup / refactoring
All cases could be handled by the single openssl s_client invocation
loop:
- dispatch and adjust comments to not loose them
- remove the first s_client invocation: stuck connections are allready
handled by the main loop
- remove the second s_client invocation: normal case and server closed
connections are allready handled by the main loop. The loop take care
of the race between server connection close and s_client terminating
too by doing another loop run, not closing STDIN.
- special non HTTP case equivalent to ssl_reneg_attempts=2
- specialcase only the HTTP result printing to not change the output
- openssl-timeout option clashe badly with the main loop logic:
Introduce $OPENSSL_NOTIMEOUT
---
testssl.sh | 181 +++++++++++++++++++++++++----------------------------
1 file changed, 87 insertions(+), 94 deletions(-)
diff --git a/testssl.sh b/testssl.sh
index c2e43e3..c90581c 100755
--- a/testssl.sh
+++ b/testssl.sh
@@ -17076,7 +17076,7 @@ run_ticketbleed() {
#
run_renego() {
local legacycmd="" proto="$OPTIMAL_PROTO"
- local sec_renego sec_client_renego
+ local sec_renego
local -i ret=0
local cve=""
local cwe="CWE-310"
@@ -17168,7 +17168,6 @@ run_renego() {
elif [[ "$CLIENT_AUTH" == required ]] && [[ -z "$MTLS" ]]; then
prln_warning "not having provided client certificate and private key file, the client x509-based authentication prevents this from being tested"
fileout "$jsonID" "WARN" "not having provided client certificate and private key file, the client x509-based authentication prevents this from being tested"
- sec_client_renego=1
else
# We will need $ERRFILE for mitigation detection
if [[ $ERRFILE =~ dev.null ]]; then
@@ -17179,99 +17178,91 @@ run_renego() {
else
restore_errfile=0
fi
- # We need up to two tries here, as some LiteSpeed servers don't answer on "R" and block. Thus first try in the background
- # msg enables us to look deeper into it while debugging
- echo R | $OPENSSL s_client $(s_client_options "$proto $BUGS $legacycmd $STARTTLS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>>$ERRFILE &
- wait_kill $! $HEADER_MAXSLEEP
- if [[ $? -eq 3 ]]; then
- pr_svrty_good "likely not vulnerable (OK)"; outln ", timed out" # it hung
- fileout "$jsonID" "OK" "likely not vulnerable (timed out)" "$cve" "$cwe"
- sec_client_renego=1
+ if [[ $SERVICE != HTTP ]]; then
+ # Connection could be closed by the server after one try so we will try two iteration
+ # to not close the openssl s_client STDIN too early like on the HTTP case.
+ # See https://github.com/drwetter/testssl.sh/issues/2590
+ ssl_reneg_attempts=2
+ fi
+ # We try again if server is HTTP. This could be either a node.js server or something else.
+ # Mitigations (default values) for:
+ # - node.js allows 3x R and then blocks. So then 4x should be tested.
+ # - F5 BIG-IP ADS allows 5x R and then blocks. So then 6x should be tested.
+ # - Stormshield allows 9x and then blocks. So then 10x should be tested.
+ # This way we save a couple seconds as we weeded out the ones which are more robust
+ # Amount of times tested before breaking is set in SSL_RENEG_ATTEMPTS.
+
+ # Clear the log to not get the content of previous run before the execution of the new one.
+ echo -n > $TMPFILE
+ # RENEGOTIATING wait loop watchdog file
+ touch $TEMPDIR/allowed_to_loop
+ # If we dont wait for the session to be established on slow server, we will try to re-negotiate
+ # too early losing all the attempts before the session establishment as OpenSSL will not buffer them
+ # (only the first will be till the establishement of the session).
+ (j=0; while [[ $(grep -ac '^SSL-Session:' $TMPFILE) -ne 1 ]] && [[ $j -lt 30 ]]; do sleep $ssl_reneg_wait; ((j++)); done; \
+ for ((i=0; i < ssl_reneg_attempts; i++ )); do sleep $ssl_reneg_wait; echo R; k=0; \
+ # 0 means client is renegotiating & doesn't return an error --> vuln!
+ # 1 means client tried to renegotiating but the server side errored then. You still see RENEGOTIATING in the output
+ # Exemption from above: server closed the connection but return value was zero
+ # See https://github.com/drwetter/testssl.sh/issues/1725 and referenced issue @haproxy
+ while [[ $(grep -ac '^RENEGOTIATING' $ERRFILE) -ne $((i+1)) ]] && [[ -f $TEMPDIR/allowed_to_loop ]] \
+ && [[ $(tail -n1 $ERRFILE |grep -acE '^(RENEGOTIATING|depth|verify|notAfter)') -eq 1 ]] \
+ && [[ $k -lt 120 ]]; \
+ do sleep $ssl_reneg_wait; ((k++)); if (tail -5 $TMPFILE| grep -qa '^closed'); then sleep 1; break; fi; done; \
+ done) | \
+ $OPENSSL_NOTIMEOUT s_client $(s_client_options "$proto $legacycmd $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>>$ERRFILE &
+ pid=$!
+ ( sleep $((ssl_reneg_attempts*3)) && kill $pid && touch $TEMPDIR/was_killed ) >&2 2>/dev/null &
+ watcher=$!
+ # Trick to get the return value of the openssl command, output redirection and a timeout.
+ # Yes, some target hang/block after some tries (some LiteSpeed servers don't answer at all on "R" and block).
+ wait $pid
+ tmp_result=$?
+ pkill -HUP -P $watcher
+ wait $watcher
+ rm -f $TEMPDIR/allowed_to_loop
+ # If we are here, we have done the loop
+ loop_reneg=$(grep -ac '^RENEGOTIATING' $ERRFILE)
+ # As above, some servers close the connection and return value is zero
+ if (tail -5 $TMPFILE| grep -qa '^closed'); then
+ tmp_result=1
+ fi
+ if [[ -f $TEMPDIR/was_killed ]]; then
+ tmp_result=2
+ rm -f $TEMPDIR/was_killed
+ fi
+ if [[ $SERVICE != HTTP ]]; then
+ case $tmp_result in
+ 0) pr_svrty_medium "VULNERABLE (NOT ok)"; outln ", potential DoS threat"
+ fileout "$jsonID" "MEDIUM" "VULNERABLE, potential DoS threat" "$cve" "$cwe" "$hint"
+ ;;
+ 1) prln_svrty_good "not vulnerable (OK)"
+ fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe"
+ ;;
+ 2) pr_svrty_good "likely not vulnerable (OK)"; outln ", timed out ($((${ssl_reneg_attempts}*3))s)" # it hung
+ fileout "$jsonID" "OK" "likely not vulnerable (timed out)" "$cve" "$cwe"
+ ;;
+ *) prln_warning "FIXME (bug): $sec_client_renego"
+ fileout "$jsonID" "DEBUG" "FIXME (bug) $sec_client_renego - Please report" "$cve" "$cwe"
+ ret=1
+ ;;
+ esac
else
- # second try in the foreground as we are sure now it won't hang
- echo R | $OPENSSL s_client $(s_client_options "$proto $legacycmd $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>>$ERRFILE
- sec_client_renego=$?
- # 0 means client is renegotiating & doesn't return an error --> vuln!
- # 1 means client tried to renegotiating but the server side errored then. You still see RENEGOTIATING in the output
- if tail -5 $TMPFILE| grep -qa '^closed'; then
- # Exemption from above: server closed the connection but return value was zero
- # See https://github.com/drwetter/testssl.sh/issues/1725 and referenced issue @haproxy
- sec_client_renego=1
- fi
- case "$sec_client_renego" in
- 0) # We try again if server is HTTP. This could be either a node.js server or something else.
- # Mitigations (default values) for:
- # - node.js allows 3x R and then blocks. So then 4x should be tested.
- # - F5 BIG-IP ADS allows 5x R and then blocks. So then 6x should be tested.
- # - Stormshield allows 9x and then blocks. So then 10x should be tested.
- # This way we save a couple seconds as we weeded out the ones which are more robust
- # Amount of times tested before breaking is set in SSL_RENEG_ATTEMPTS.
- if [[ $SERVICE != HTTP ]]; then
- pr_svrty_medium "VULNERABLE (NOT ok)"; outln ", potential DoS threat"
- fileout "$jsonID" "MEDIUM" "VULNERABLE, potential DoS threat" "$cve" "$cwe" "$hint"
- else
- # Clear the log to not get the content of previous run before the execution of the new one.
- echo -n > $TMPFILE
- #RENEGOTIATING wait loop watchdog file
- touch $TEMPDIR/allowed_to_loop
- # If we dont wait for the session to be established on slow server, we will try to re-negotiate
- # too early losing all the attempts before the session establishment as OpenSSL will not buffer them
- # (only the first will be till the establishement of the session).
- (j=0; while [[ $(grep -ac '^SSL-Session:' $TMPFILE) -ne 1 ]] && [[ $j -lt 30 ]]; do sleep $ssl_reneg_wait; ((j++)); done; \
- for ((i=0; i < ssl_reneg_attempts; i++ )); do sleep $ssl_reneg_wait; echo R; k=0; \
- while [[ $(grep -ac '^RENEGOTIATING' $ERRFILE) -ne $((i+3)) ]] && [[ -f $TEMPDIR/allowed_to_loop ]] \
- && [[ $(tail -n1 $ERRFILE |grep -acE '^(RENEGOTIATING|depth|verify|notAfter)') -eq 1 ]] \
- && [[ $k -lt 120 ]]; \
- do sleep $ssl_reneg_wait; ((k++)); if (tail -5 $TMPFILE| grep -qa '^closed'); then sleep 1; break; fi; done; \
- done) | \
- $OPENSSL s_client $(s_client_options "$proto $legacycmd $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>>$ERRFILE &
- pid=$!
- ( sleep $((ssl_reneg_attempts*3)) && kill $pid && touch $TEMPDIR/was_killed ) >&2 2>/dev/null &
- watcher=$!
- # Trick to get the return value of the openssl command, output redirection and a timeout.
- # Yes, some target hang/block after some tries.
- wait $pid
- tmp_result=$?
- pkill -HUP -P $watcher
- wait $watcher
- rm -f $TEMPDIR/allowed_to_loop
- # If we are here, we have done two successful renegotiation (-2) and do the loop
- loop_reneg=$(($(grep -ac '^RENEGOTIATING' $ERRFILE)-2))
- # As above, some servers close the connection and return value is zero
- if (tail -5 $TMPFILE| grep -qa '^closed'); then
- tmp_result=1
- fi
- if [[ -f $TEMPDIR/was_killed ]]; then
- tmp_result=2
- rm -f $TEMPDIR/was_killed
- fi
- case $tmp_result in
- 0) pr_svrty_high "VULNERABLE (NOT ok)"; outln ", DoS threat ($ssl_reneg_attempts attempts)"
- fileout "$jsonID" "HIGH" "VULNERABLE, DoS threat" "$cve" "$cwe" "$hint"
- ;;
- 1) pr_svrty_good "not vulnerable (OK)"; outln " -- mitigated (disconnect after $loop_reneg/$ssl_reneg_attempts attempts)"
- fileout "$jsonID" "OK" "not vulnerable, mitigated" "$cve" "$cwe"
- ;;
- 2) pr_svrty_good "not vulnerable (OK)"; \
- outln " -- mitigated ($loop_reneg successful reneg within ${ssl_reneg_attempts} in $((${ssl_reneg_attempts}*3))s(timeout))"
- fileout "$jsonID" "OK" "not vulnerable, mitigated" "$cve" "$cwe"
- ;;
- *) prln_warning "FIXME (bug): $sec_client_renego ($ssl_reneg_attempts tries)"
- fileout "$jsonID" "DEBUG" "FIXME (bug $ssl_reneg_attempts tries) $sec_client_renego" "$cve" "$cwe"
- ret=1
- ;;
- esac
- fi
- ;;
- 1)
- prln_svrty_good "not vulnerable (OK)"
- fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe"
- ;;
- *)
- prln_warning "FIXME (bug): $sec_client_renego"
- fileout "$jsonID" "DEBUG" "FIXME (bug) $sec_client_renego - Please report" "$cve" "$cwe"
- ret=1
- ;;
+ case $tmp_result in
+ 0) pr_svrty_high "VULNERABLE (NOT ok)"; outln ", DoS threat ($ssl_reneg_attempts attempts)"
+ fileout "$jsonID" "HIGH" "VULNERABLE, DoS threat" "$cve" "$cwe" "$hint"
+ ;;
+ 1) pr_svrty_good "not vulnerable (OK)"; outln " -- mitigated (disconnect after $loop_reneg/$ssl_reneg_attempts attempts)"
+ fileout "$jsonID" "OK" "not vulnerable, mitigated" "$cve" "$cwe"
+ ;;
+ 2) pr_svrty_good "not vulnerable (OK)"; \
+ outln " -- mitigated ($loop_reneg successful reneg within ${ssl_reneg_attempts} in $((${ssl_reneg_attempts}*3))s(timeout))"
+ fileout "$jsonID" "OK" "not vulnerable, mitigated" "$cve" "$cwe"
+ ;;
+ *) prln_warning "FIXME (bug): $sec_client_renego ($ssl_reneg_attempts tries)"
+ fileout "$jsonID" "DEBUG" "FIXME (bug $ssl_reneg_attempts tries) $sec_client_renego" "$cve" "$cwe"
+ ret=1
+ ;;
esac
fi
fi
@@ -20447,6 +20438,8 @@ find_openssl_binary() {
fi
fi
+ OPENSSL_NOTIMEOUT=$OPENSSL
+
if ! "$do_mass_testing"; then
if [[ -n $OPENSSL_TIMEOUT ]]; then
OPENSSL="$TIMEOUT_CMD $OPENSSL_TIMEOUT $OPENSSL"
From 09719a322bc2ae7006a243a2fc01bc19b0485af4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emmanuel=20Fust=C3=A9?=
Date: Mon, 4 Nov 2024 20:25:31 +0100
Subject: [PATCH 03/28] Remove the last 1s euristic
In the wait loop, I was relying on a 1s sleep to eliminate a possible
late zero return value server close on the last attempt.
- do globaly one more harmless "for" iteration
and remove the sleep 1 for faster and more robust result
- correct the non HTTP case iteration value
- adjust the timeout to the conservative 6s in the non HTTP case,
for HTTP case it become 33s
- improve comments
---
testssl.sh | 23 +++++++++++++----------
1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/testssl.sh b/testssl.sh
index c90581c..1391175 100755
--- a/testssl.sh
+++ b/testssl.sh
@@ -17179,10 +17179,7 @@ run_renego() {
restore_errfile=0
fi
if [[ $SERVICE != HTTP ]]; then
- # Connection could be closed by the server after one try so we will try two iteration
- # to not close the openssl s_client STDIN too early like on the HTTP case.
- # See https://github.com/drwetter/testssl.sh/issues/2590
- ssl_reneg_attempts=2
+ ssl_reneg_attempts=1
fi
# We try again if server is HTTP. This could be either a node.js server or something else.
# Mitigations (default values) for:
@@ -17200,7 +17197,11 @@ run_renego() {
# too early losing all the attempts before the session establishment as OpenSSL will not buffer them
# (only the first will be till the establishement of the session).
(j=0; while [[ $(grep -ac '^SSL-Session:' $TMPFILE) -ne 1 ]] && [[ $j -lt 30 ]]; do sleep $ssl_reneg_wait; ((j++)); done; \
- for ((i=0; i < ssl_reneg_attempts; i++ )); do sleep $ssl_reneg_wait; echo R; k=0; \
+ # Connection could be closed by the server with 0 return value. We do one more iteration to not close
+ # s_client STDIN too early as the close could come at any time and race with the tear down of s_client.
+ # See https://github.com/drwetter/testssl.sh/issues/2590
+ # In this case the added iteration is harmfull as it will just spin in backgroup
+ for ((i=0; i <= ssl_reneg_attempts; i++ )); do sleep $ssl_reneg_wait; echo R; k=0; \
# 0 means client is renegotiating & doesn't return an error --> vuln!
# 1 means client tried to renegotiating but the server side errored then. You still see RENEGOTIATING in the output
# Exemption from above: server closed the connection but return value was zero
@@ -17208,11 +17209,11 @@ run_renego() {
while [[ $(grep -ac '^RENEGOTIATING' $ERRFILE) -ne $((i+1)) ]] && [[ -f $TEMPDIR/allowed_to_loop ]] \
&& [[ $(tail -n1 $ERRFILE |grep -acE '^(RENEGOTIATING|depth|verify|notAfter)') -eq 1 ]] \
&& [[ $k -lt 120 ]]; \
- do sleep $ssl_reneg_wait; ((k++)); if (tail -5 $TMPFILE| grep -qa '^closed'); then sleep 1; break; fi; done; \
+ do sleep $ssl_reneg_wait; ((k++)); if (tail -5 $TMPFILE| grep -qa '^closed'); then break; fi; done; \
done) | \
$OPENSSL_NOTIMEOUT s_client $(s_client_options "$proto $legacycmd $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>>$ERRFILE &
pid=$!
- ( sleep $((ssl_reneg_attempts*3)) && kill $pid && touch $TEMPDIR/was_killed ) >&2 2>/dev/null &
+ ( sleep $((ssl_reneg_attempts*3+3)) && kill $pid && touch $TEMPDIR/was_killed ) >&2 2>/dev/null &
watcher=$!
# Trick to get the return value of the openssl command, output redirection and a timeout.
# Yes, some target hang/block after some tries (some LiteSpeed servers don't answer at all on "R" and block).
@@ -17220,8 +17221,10 @@ run_renego() {
tmp_result=$?
pkill -HUP -P $watcher
wait $watcher
+ # Stop any backgroud wait loop
rm -f $TEMPDIR/allowed_to_loop
- # If we are here, we have done the loop
+ # If we are here, we have done the loop. Count the effective renego attempts.
+ # It could be less than the numbers of "for" itterations (minus one) in case of late server close.
loop_reneg=$(grep -ac '^RENEGOTIATING' $ERRFILE)
# As above, some servers close the connection and return value is zero
if (tail -5 $TMPFILE| grep -qa '^closed'); then
@@ -17239,7 +17242,7 @@ run_renego() {
1) prln_svrty_good "not vulnerable (OK)"
fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe"
;;
- 2) pr_svrty_good "likely not vulnerable (OK)"; outln ", timed out ($((${ssl_reneg_attempts}*3))s)" # it hung
+ 2) pr_svrty_good "likely not vulnerable (OK)"; outln ", timed out ($((${ssl_reneg_attempts}*3+3))s)" # it hung
fileout "$jsonID" "OK" "likely not vulnerable (timed out)" "$cve" "$cwe"
;;
*) prln_warning "FIXME (bug): $sec_client_renego"
@@ -17256,7 +17259,7 @@ run_renego() {
fileout "$jsonID" "OK" "not vulnerable, mitigated" "$cve" "$cwe"
;;
2) pr_svrty_good "not vulnerable (OK)"; \
- outln " -- mitigated ($loop_reneg successful reneg within ${ssl_reneg_attempts} in $((${ssl_reneg_attempts}*3))s(timeout))"
+ outln " -- mitigated ($loop_reneg successful reneg within ${ssl_reneg_attempts} in $((${ssl_reneg_attempts}*3+3))s(timeout))"
fileout "$jsonID" "OK" "not vulnerable, mitigated" "$cve" "$cwe"
;;
*) prln_warning "FIXME (bug): $sec_client_renego ($ssl_reneg_attempts tries)"
From d8b439e48c24b60855a92cb9dae5ea5455cccd74 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emmanuel=20Fust=C3=A9?=
Date: Mon, 4 Nov 2024 20:53:07 +0100
Subject: [PATCH 04/28] Address a theorically still possible non HTTP case
---
testssl.sh | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/testssl.sh b/testssl.sh
index 1391175..6fc1069 100755
--- a/testssl.sh
+++ b/testssl.sh
@@ -17200,7 +17200,7 @@ run_renego() {
# Connection could be closed by the server with 0 return value. We do one more iteration to not close
# s_client STDIN too early as the close could come at any time and race with the tear down of s_client.
# See https://github.com/drwetter/testssl.sh/issues/2590
- # In this case the added iteration is harmfull as it will just spin in backgroup
+ # In this case the added iteration is harmless as it will just spin in backgroup
for ((i=0; i <= ssl_reneg_attempts; i++ )); do sleep $ssl_reneg_wait; echo R; k=0; \
# 0 means client is renegotiating & doesn't return an error --> vuln!
# 1 means client tried to renegotiating but the server side errored then. You still see RENEGOTIATING in the output
@@ -17230,11 +17230,16 @@ run_renego() {
if (tail -5 $TMPFILE| grep -qa '^closed'); then
tmp_result=1
fi
+ # timeout reached ?
if [[ -f $TEMPDIR/was_killed ]]; then
tmp_result=2
rm -f $TEMPDIR/was_killed
fi
if [[ $SERVICE != HTTP ]]; then
+ # theoric possible case
+ if [[ $loop_reneg -eq 2 ]];
+ $tmp_result=0
+ fi
case $tmp_result in
0) pr_svrty_medium "VULNERABLE (NOT ok)"; outln ", potential DoS threat"
fileout "$jsonID" "MEDIUM" "VULNERABLE, potential DoS threat" "$cve" "$cwe" "$hint"
From 5773303f239e3e7be412b61582bd81029ee58fe0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emmanuel=20Fust=C3=A9?=
Date: Mon, 4 Nov 2024 20:59:45 +0100
Subject: [PATCH 05/28] Correct incomplete commit
---
testssl.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/testssl.sh b/testssl.sh
index 6fc1069..986f4b8 100755
--- a/testssl.sh
+++ b/testssl.sh
@@ -17237,8 +17237,8 @@ run_renego() {
fi
if [[ $SERVICE != HTTP ]]; then
# theoric possible case
- if [[ $loop_reneg -eq 2 ]];
- $tmp_result=0
+ if [[ $loop_reneg -eq 2 ]]; then
+ tmp_result=0
fi
case $tmp_result in
0) pr_svrty_medium "VULNERABLE (NOT ok)"; outln ", potential DoS threat"
From 76254229761e9f224643ef58a7b719679903a62d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emmanuel=20Fust=C3=A9?=
Date: Mon, 4 Nov 2024 21:02:03 +0100
Subject: [PATCH 06/28] Spell fix
---
testssl.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/testssl.sh b/testssl.sh
index 986f4b8..775b7a3 100755
--- a/testssl.sh
+++ b/testssl.sh
@@ -17221,10 +17221,10 @@ run_renego() {
tmp_result=$?
pkill -HUP -P $watcher
wait $watcher
- # Stop any backgroud wait loop
+ # Stop any background wait loop
rm -f $TEMPDIR/allowed_to_loop
# If we are here, we have done the loop. Count the effective renego attempts.
- # It could be less than the numbers of "for" itterations (minus one) in case of late server close.
+ # It could be less than the numbers of "for" iterations (minus one) in case of late server close.
loop_reneg=$(grep -ac '^RENEGOTIATING' $ERRFILE)
# As above, some servers close the connection and return value is zero
if (tail -5 $TMPFILE| grep -qa '^closed'); then
From 1aaab67e81569cfbf0bf770cbbb65d571f9d5342 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emmanuel=20Fust=C3=A9?=
Date: Tue, 5 Nov 2024 12:59:01 +0100
Subject: [PATCH 07/28] Multiple IP fix and simple not vulnerable printing case
recover
- Recover the "not vulnerable" case (no mitigation) printing, cosmetic
fix.
- With the removing of all s_client invocation other than the main loop
one, fix the init of the ERRFILE and TMPFILE: no need to append, no
need to remove, inconditionally zap the content before the loop.
---
testssl.sh | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/testssl.sh b/testssl.sh
index 775b7a3..e3c63c4 100755
--- a/testssl.sh
+++ b/testssl.sh
@@ -17172,8 +17172,6 @@ run_renego() {
# We will need $ERRFILE for mitigation detection
if [[ $ERRFILE =~ dev.null ]]; then
ERRFILE=$TEMPDIR/errorfile.txt || exit $ERR_FCREATE
- # cleanup previous run if any (multiple IP)
- rm -f $ERRFILE
restore_errfile=1
else
restore_errfile=0
@@ -17190,7 +17188,9 @@ run_renego() {
# Amount of times tested before breaking is set in SSL_RENEG_ATTEMPTS.
# Clear the log to not get the content of previous run before the execution of the new one.
+ # (Used in the loop tests before s_client invocation)
echo -n > $TMPFILE
+ echo -n > $ERRFILE
# RENEGOTIATING wait loop watchdog file
touch $TEMPDIR/allowed_to_loop
# If we dont wait for the session to be established on slow server, we will try to re-negotiate
@@ -17211,7 +17211,7 @@ run_renego() {
&& [[ $k -lt 120 ]]; \
do sleep $ssl_reneg_wait; ((k++)); if (tail -5 $TMPFILE| grep -qa '^closed'); then break; fi; done; \
done) | \
- $OPENSSL_NOTIMEOUT s_client $(s_client_options "$proto $legacycmd $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>>$ERRFILE &
+ $OPENSSL_NOTIMEOUT s_client $(s_client_options "$proto $legacycmd $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>$ERRFILE &
pid=$!
( sleep $((ssl_reneg_attempts*3+3)) && kill $pid && touch $TEMPDIR/was_killed ) >&2 2>/dev/null &
watcher=$!
@@ -17235,6 +17235,9 @@ run_renego() {
tmp_result=2
rm -f $TEMPDIR/was_killed
fi
+ if [[ $tmp_result -eq 1 ]] && [[ loop_reneg -eq 1 ]]; then
+ tmp_result=3
+ fi
if [[ $SERVICE != HTTP ]]; then
# theoric possible case
if [[ $loop_reneg -eq 2 ]]; then
@@ -17244,7 +17247,7 @@ run_renego() {
0) pr_svrty_medium "VULNERABLE (NOT ok)"; outln ", potential DoS threat"
fileout "$jsonID" "MEDIUM" "VULNERABLE, potential DoS threat" "$cve" "$cwe" "$hint"
;;
- 1) prln_svrty_good "not vulnerable (OK)"
+ 1|3) prln_svrty_good "not vulnerable (OK)"
fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe"
;;
2) pr_svrty_good "likely not vulnerable (OK)"; outln ", timed out ($((${ssl_reneg_attempts}*3+3))s)" # it hung
@@ -17263,6 +17266,9 @@ run_renego() {
1) pr_svrty_good "not vulnerable (OK)"; outln " -- mitigated (disconnect after $loop_reneg/$ssl_reneg_attempts attempts)"
fileout "$jsonID" "OK" "not vulnerable, mitigated" "$cve" "$cwe"
;;
+ 3) prln_svrty_good "not vulnerable (OK)"
+ fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe"
+ ;;
2) pr_svrty_good "not vulnerable (OK)"; \
outln " -- mitigated ($loop_reneg successful reneg within ${ssl_reneg_attempts} in $((${ssl_reneg_attempts}*3+3))s(timeout))"
fileout "$jsonID" "OK" "not vulnerable, mitigated" "$cve" "$cwe"
From 991c1fefb228f62f0506a0d9aef05307da6599df Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emmanuel=20Fust=C3=A9?=
Date: Thu, 7 Nov 2024 12:25:50 +0100
Subject: [PATCH 08/28] One tab fix
---
testssl.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/testssl.sh b/testssl.sh
index e3c63c4..fe0b2db 100755
--- a/testssl.sh
+++ b/testssl.sh
@@ -17188,7 +17188,7 @@ run_renego() {
# Amount of times tested before breaking is set in SSL_RENEG_ATTEMPTS.
# Clear the log to not get the content of previous run before the execution of the new one.
- # (Used in the loop tests before s_client invocation)
+ # (Used in the loop tests before s_client invocation)
echo -n > $TMPFILE
echo -n > $ERRFILE
# RENEGOTIATING wait loop watchdog file
From e4e3afbbe8ed721e28cb11037950d2990d1b7a01 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emmanuel=20Fust=C3=A9?=
Date: Mon, 9 Dec 2024 10:46:45 +0100
Subject: [PATCH 09/28] Tentative to fix CI tests
---
testssl.sh | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/testssl.sh b/testssl.sh
index fe0b2db..0c6c668 100755
--- a/testssl.sh
+++ b/testssl.sh
@@ -17169,6 +17169,10 @@ run_renego() {
prln_warning "not having provided client certificate and private key file, the client x509-based authentication prevents this from being tested"
fileout "$jsonID" "WARN" "not having provided client certificate and private key file, the client x509-based authentication prevents this from being tested"
else
+ # We will extensively use subshell and command pipe
+ # Do not let herited pipeline error control interfere
+ [[ $- == *e* ]] && restore_pipeerror=1
+ [[ $restore_pipeerror == 1 ]] && set +e
# We will need $ERRFILE for mitigation detection
if [[ $ERRFILE =~ dev.null ]]; then
ERRFILE=$TEMPDIR/errorfile.txt || exit $ERR_FCREATE
@@ -17279,6 +17283,7 @@ run_renego() {
;;
esac
fi
+ [[ $restore_pipeerror == 1 ]] && set -e
fi
#pr_bold " Insecure Client-Initiated Renegotiation " # pre-RFC 5746, CVE-2009-3555
From 88856ecad5f6e83e127cf82675dd47e22150ba36 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emmanuel=20Fust=C3=A9?=
Date: Mon, 9 Dec 2024 12:00:16 +0100
Subject: [PATCH 10/28] 2nd try
---
testssl.sh | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/testssl.sh b/testssl.sh
index 0616064..089abd1 100755
--- a/testssl.sh
+++ b/testssl.sh
@@ -17173,10 +17173,11 @@ run_renego() {
prln_warning "not having provided client certificate and private key file, the client x509-based authentication prevents this from being tested"
fileout "$jsonID" "WARN" "not having provided client certificate and private key file, the client x509-based authentication prevents this from being tested"
else
- # We will extensively use subshell and command pipe
- # Do not let herited pipeline error control interfere
- [[ $- == *e* ]] && restore_pipeerror=1
- [[ $restore_pipeerror == 1 ]] && set +e
+# # We will extensively use subshell and command pipe
+# # Do not let herited pipeline error control interfere
+# [[ $- == *e* ]] && restore_pipeerror=1
+# [[ $restore_pipeerror == 1 ]] && set +e
+# set +o pipefail
# We will need $ERRFILE for mitigation detection
if [[ $ERRFILE =~ dev.null ]]; then
ERRFILE=$TEMPDIR/errorfile.txt || exit $ERR_FCREATE
@@ -17209,7 +17210,7 @@ run_renego() {
# s_client STDIN too early as the close could come at any time and race with the tear down of s_client.
# See https://github.com/drwetter/testssl.sh/issues/2590
# In this case the added iteration is harmless as it will just spin in backgroup
- for ((i=0; i <= ssl_reneg_attempts; i++ )); do sleep $ssl_reneg_wait; echo R; k=0; \
+ for ((i=0; i <= ssl_reneg_attempts; i++ )); do sleep $ssl_reneg_wait; echo R 2>/dev/null; k=0; \
# 0 means client is renegotiating & doesn't return an error --> vuln!
# 1 means client tried to renegotiating but the server side errored then. You still see RENEGOTIATING in the output
# Exemption from above: server closed the connection but return value was zero
@@ -17287,7 +17288,7 @@ run_renego() {
;;
esac
fi
- [[ $restore_pipeerror == 1 ]] && set -e
+# [[ $restore_pipeerror == 1 ]] && set -e
fi
#pr_bold " Insecure Client-Initiated Renegotiation " # pre-RFC 5746, CVE-2009-3555
From 6c17b6641873636433ed15ab03b148b3307278e2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emmanuel=20Fust=C3=A9?=
Date: Mon, 9 Dec 2024 14:19:56 +0100
Subject: [PATCH 11/28] CI fix : Cleanup
testssl.sh worked as expected.
Under the hood, broken pipes are expected as part of the fast loop exit
strategy that relies as little as possible on timeout detection.
But under the CI, testssl.sh output is garbled by the subshells stderr
outputs, catched for some reason by 'prove -v'.
Simply redirecting the stderr output of the offending command to
/dev/null fixes the problem.
---
testssl.sh | 6 ------
1 file changed, 6 deletions(-)
diff --git a/testssl.sh b/testssl.sh
index 089abd1..7983aae 100755
--- a/testssl.sh
+++ b/testssl.sh
@@ -17173,11 +17173,6 @@ run_renego() {
prln_warning "not having provided client certificate and private key file, the client x509-based authentication prevents this from being tested"
fileout "$jsonID" "WARN" "not having provided client certificate and private key file, the client x509-based authentication prevents this from being tested"
else
-# # We will extensively use subshell and command pipe
-# # Do not let herited pipeline error control interfere
-# [[ $- == *e* ]] && restore_pipeerror=1
-# [[ $restore_pipeerror == 1 ]] && set +e
-# set +o pipefail
# We will need $ERRFILE for mitigation detection
if [[ $ERRFILE =~ dev.null ]]; then
ERRFILE=$TEMPDIR/errorfile.txt || exit $ERR_FCREATE
@@ -17288,7 +17283,6 @@ run_renego() {
;;
esac
fi
-# [[ $restore_pipeerror == 1 ]] && set -e
fi
#pr_bold " Insecure Client-Initiated Renegotiation " # pre-RFC 5746, CVE-2009-3555
From 2e8d4a112858fc739bbe00bf8c829f6fd4fe8823 Mon Sep 17 00:00:00 2001
From: Hyeonho Kang
Date: Fri, 17 Jan 2025 00:36:37 +0900
Subject: [PATCH 12/28] Edit CONTRIBUTING.md
---
CONTRIBUTING.md | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index bd8dfcb..eb9098e 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,21 +1,21 @@
-### Contributions / participation
+### Contribution
-is always welcome, here @ github or via e-mail.
+Contribution is always welcome, submit here (GitHub) or via e-mail.
-Note please the following
+Please note the following:
-* Please read at least the [coding convention](https://github.com/testssl/testssl.sh/Coding_Convention.md).
-* One PR per feature or bug fix or improvement. Please do not mix issues.
-* Document your PR, both in the PR and/or commit message and in the code.
+* Please read at least the [coding convention](https://github.com/testssl/testssl.sh/blob/3.2/Coding_Convention.md).
+* One Pull Request per feature or bug fix or improvement. Please do not mix issues.
+* Document your Pull Request, both in the Pull Request and/or commit message and in the code.
* Please test your changes thoroughly as reliability is important for this project. You may want to check different servers with different settings.
-* Travis runs automatically when anything is committed/PR'd. You should check any complains from Travis. Beforehand you can check with `prove -v`.
-* If it's a new feature please consider writing a unit test for it. You can use e.g. `t/20_baseline_ipv4_http.t` as a template. The general documentation for [Test::More](https://perldoc.perl.org/Test/More.html) is a good start.
-* If it's a new feature it would need to be documented in the appropriate section in `help()` and in `~/doc/testssl.1.md`
+* Travis runs automatically when anything is committed/pull requested. You should check any complains from Travis. Beforehand you can check with `prove -v`.
+* If it's a new feature, please consider writing a unit test for it. You can use e.g. `t/20_baseline_ipv4_http.t` as a template. The general documentation for [Test::More](https://perldoc.perl.org/Test/More.html) is a good start.
+* If it's a new feature, it would need to be documented in the appropriate section in `help()` and in `~/doc/testssl.1.md`
-For questions just open an issue or feel free to send me an e-mail.
+For the questions, just open an issue or feel free to send us an e-mail.
-#### Patches via e-mail
+#### Contribute via e-mail
-Of course it is fine when you want to send in patches to use e-mail. For the address please grep for SWCONTACT in testssl.sh .
+Of course it is fine when you want to send in patches to use e-mail. For the address, please grep for SWCONTACT in testssl.sh.
Let me know how you like them to be attributed.
From 80008853714b7f3ce52e888f33e5dbcb2fb5d3b3 Mon Sep 17 00:00:00 2001
From: Dirk Wetter
Date: Thu, 16 Jan 2025 21:18:47 +0100
Subject: [PATCH 13/28] Add more security headers
... and deprecate "X-Content-Security-Policy" and "X-WebKit-CSP"
---
testssl.sh | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/testssl.sh b/testssl.sh
index 1dd94c6..188de3b 100755
--- a/testssl.sh
+++ b/testssl.sh
@@ -3438,13 +3438,17 @@ run_security_headers() {
for header_and_svrty in "X-Frame-Options OK" \
"X-Content-Type-Options OK" \
"Content-Security-Policy OK" \
- "X-Content-Security-Policy OK" \
- "X-WebKit-CSP OK" \
+ "X-Content-Security-Policy INFO" \
+ "X-WebKit-CSP INFO" \
"Content-Security-Policy-Report-Only OK" \
"Expect-CT OK" \
"Permissions-Policy OK" \
+ "Cross-Origin-Opener-Policy INFO" \
+ "Cross-Origin-Resource-Policy INFO" \
+ "Cross-Origin-Embedder-Policy INFO" \
"X-XSS-Protection INFO" \
"Access-Control-Allow-Origin INFO" \
+ "Access-Control-Allow-Credentials INFO" \
"Upgrade INFO" \
"X-Served-By INFO" \
"Referrer-Policy INFO" \
From a1c2dc7c72e60ef58afc376fff063d10bde77596 Mon Sep 17 00:00:00 2001
From: Dirk
Date: Wed, 22 Jan 2025 19:19:16 +0100
Subject: [PATCH 14/28] Remove --nsa in help() and add --forward-secrecy
instead
Both are possible to use
---
testssl.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/testssl.sh b/testssl.sh
index a80d13a..5b398d5 100755
--- a/testssl.sh
+++ b/testssl.sh
@@ -20685,7 +20685,7 @@ single check as ("$PROG_NAME URI" does everything except -E and -g):
-e, --each-cipher checks each local cipher remotely
-E, --cipher-per-proto checks those per protocol
-s, --std, --categories tests standard cipher categories by strength
- -f, --fs, --nsa checks forward secrecy settings
+ -f, --fs, --forward-secrecy checks forward secrecy settings
-p, --protocols checks TLS/SSL protocols (including SPDY/HTTP2)
-g, --grease tests several server implementation bugs like GREASE and size limitations
-S, --server-defaults displays the server's default picks and certificate info
From 12036fb6c8b4aa38ac3472464bc3c673f41d6d0f Mon Sep 17 00:00:00 2001
From: Dirk
Date: Wed, 22 Jan 2025 19:54:34 +0100
Subject: [PATCH 15/28] Update baseline scan + add/deprecate security headers
---
t/baseline_data/default_testssl.csvfile | 6 ++++--
testssl.sh | 10 ++++++++--
2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/t/baseline_data/default_testssl.csvfile b/t/baseline_data/default_testssl.csvfile
index 28118ba..bb91a05 100644
--- a/t/baseline_data/default_testssl.csvfile
+++ b/t/baseline_data/default_testssl.csvfile
@@ -70,7 +70,7 @@
"FS_TLS13_sig_algs","testssl.sh/81.169.166.184","443","INFO","RSA-PSS-RSAE+SHA256 RSA-PSS-RSAE+SHA384 RSA-PSS-RSAE+SHA512","",""
"HTTP_status_code","testssl.sh/81.169.166.184","443","INFO","200 OK ('/')","",""
"HTTP_clock_skew","testssl.sh/81.169.166.184","443","INFO","0 seconds from localtime","",""
-"HTTP_headerTime","testssl.sh/81.169.166.184","443","INFO","1654006271","",""
+"HTTP_headerTime","testssl.sh/81.169.166.184","443","INFO","1737570310","",""
"HSTS_time","testssl.sh/81.169.166.184","443","OK","362 days (=31337000 seconds) > 15552000 seconds","",""
"HSTS_subdomains","testssl.sh/81.169.166.184","443","INFO","only for this domain","",""
"HSTS_preload","testssl.sh/81.169.166.184","443","INFO","domain is NOT marked for preloading","",""
@@ -81,6 +81,8 @@
"X-Frame-Options","testssl.sh/81.169.166.184","443","OK","DENY","",""
"X-Content-Type-Options","testssl.sh/81.169.166.184","443","OK","nosniff","",""
"Content-Security-Policy","testssl.sh/81.169.166.184","443","OK","script-src 'unsafe-inline'; style-src 'unsafe-inline' 'self'; object-src 'self'; base-uri 'none'; form-action 'none'; img-src 'self' ; default-src 'self'; frame-ancestors 'self'; upgrade-insecure-requests;","",""
+"Cross-Origin-Opener-Policy","testssl.sh/81.169.166.184","443","INFO","same-origin-allow-popups","",""
+"Cross-Origin-Resource-Policy","testssl.sh/81.169.166.184","443","INFO","same-site","",""
"banner_reverseproxy","testssl.sh/81.169.166.184","443","INFO","--","","CWE-200"
"heartbleed","testssl.sh/81.169.166.184","443","OK","not vulnerable, no heartbeat extension","CVE-2014-0160","CWE-119"
"CCS","testssl.sh/81.169.166.184","443","OK","not vulnerable","CVE-2014-0224","CWE-310"
@@ -95,7 +97,7 @@
"SWEET32","testssl.sh/81.169.166.184","443","OK","not vulnerable","CVE-2016-2183 CVE-2016-6329","CWE-327"
"FREAK","testssl.sh/81.169.166.184","443","OK","not vulnerable","CVE-2015-0204","CWE-310"
"DROWN","testssl.sh/81.169.166.184","443","OK","not vulnerable on this host and port","CVE-2016-0800 CVE-2016-0703","CWE-310"
-"DROWN_hint","testssl.sh/81.169.166.184","443","INFO","Make sure you don't use this certificate elsewhere with SSLv2 enabled services, see https://search.censys.io/search?resource=hosts&virtual_hosts=INCLUDE&q=31B44391529821C6A77F3C78B02D716A07F99B8FDB342BF5A78F263C25375968","CVE-2016-0800 CVE-2016-0703","CWE-310"
+"DROWN_hint","testssl.sh/81.169.166.184","443","INFO","Make sure you don't use this certificate elsewhere with SSLv2 enabled services, see https://search.censys.io/search?resource=hosts&virtual_hosts=INCLUDE&q=5B4BC205947AED96ECB1879F2668F7F69D696C143BA8D1C69DBB4DC873C92AE9","CVE-2016-0800 CVE-2016-0703","CWE-310"
"LOGJAM","testssl.sh/81.169.166.184","443","OK","not vulnerable, no DH EXPORT ciphers,","CVE-2015-4000","CWE-310"
"LOGJAM-common_primes","testssl.sh/81.169.166.184","443","OK","--","CVE-2015-4000","CWE-310"
"BEAST_CBC_TLS1","testssl.sh/81.169.166.184","443","MEDIUM","ECDHE-RSA-AES256-SHA ECDHE-RSA-AES128-SHA DHE-RSA-CAMELLIA256-SHA DHE-RSA-CAMELLIA128-SHA DHE-RSA-AES256-SHA DHE-RSA-AES128-SHA AES256-SHA","CVE-2011-3389","CWE-20"
diff --git a/testssl.sh b/testssl.sh
index 188de3b..6474414 100755
--- a/testssl.sh
+++ b/testssl.sh
@@ -3127,11 +3127,13 @@ emphasize_stuff_in_headers(){
-e "s/X-Powered-By/${yellow}X-Powered-By${off}/g" \
-e "s/X-UA-Compatible/${yellow}X-UA-Compatible${off}/g" \
-e "s/Link/${yellow}Link${off}/g" \
+ -e "s/X-DNS-Prefetch-Control/${html_yellow}X-DNS-Prefetch-Control${html_off}/g" \
-e "s/X-Rack-Cache/${yellow}X-Rack-Cache${off}/g" \
-e "s/X-Runtime/${yellow}X-Runtime${off}/g" \
-e "s/X-Pingback/${yellow}X-Pingback${off}/g" \
-e "s/X-Permitted-Cross-Domain-Policies/${yellow}X-Permitted-Cross-Domain-Policies${off}/g" \
-e "s/X-AspNet-Version/${yellow}X-AspNet-Version${off}/g" \
+ -e "s/X-AspNetMvc-Version/${yellow}X-AspNetMvc-Version${off}/g" \
-e "s/x-note/${yellow}x-note${off}/g" \
-e "s/x-global-transaction-id/${yellow}x-global-transaction-id${off}/g" \
-e "s/X-Global-Transaction-ID/${yellow}X-Global-Transaction-ID${off}/g" \
@@ -3177,9 +3179,11 @@ emphasize_stuff_in_headers(){
-e "s/Link/${html_yellow}Link${html_off}/g" \
-e "s/X-Runtime/${html_yellow}X-Runtime${html_off}/g" \
-e "s/X-Rack-Cache/${html_yellow}X-Rack-Cache${html_off}/g" \
+ -e "s/X-DNS-Prefetch-Control/${html_yellow}X-DNS-Prefetch-Control${html_off}/g" \
-e "s/X-Pingback/${html_yellow}X-Pingback${html_off}/g" \
-e "s/X-Permitted-Cross-Domain-Policies/${html_yellow}X-Permitted-Cross-Domain-Policies${html_off}/g" \
- -e "s/X-AspNet-Version/${html_yellow}X-AspNet-Version${html_off}/g")" \
+ -e "s/X-AspNet-Version/${html_yellow}X-AspNet-Version${html_off}/g" \
+ -e "s/X-AspNetMvc-Version/${yellow}X-AspNetMvc-Version${off}/g" \
-e "s/x-note/${html_yellow}x-note${html_off}/g" \
-e "s/X-Global-Transaction-ID/${html_yellow}X-Global-Transaction-ID${html_off}/g" \
-e "s/x-global-transaction-id/${html_yellow}x-global-transaction-id${html_off}/g" \
@@ -3435,13 +3439,14 @@ run_security_headers() {
pr_bold " Security headers "
# X-XSS-Protection is useless and at worst harmful, see https://news.ycombinator.com/item?id=20472947
+ # Expect-CT is depecated, see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expect-CT
for header_and_svrty in "X-Frame-Options OK" \
"X-Content-Type-Options OK" \
"Content-Security-Policy OK" \
"X-Content-Security-Policy INFO" \
"X-WebKit-CSP INFO" \
"Content-Security-Policy-Report-Only OK" \
- "Expect-CT OK" \
+ "Expect-CT INFO" \
"Permissions-Policy OK" \
"Cross-Origin-Opener-Policy INFO" \
"Cross-Origin-Resource-Policy INFO" \
@@ -3449,6 +3454,7 @@ run_security_headers() {
"X-XSS-Protection INFO" \
"Access-Control-Allow-Origin INFO" \
"Access-Control-Allow-Credentials INFO" \
+ "Permissions-Policy INFO" \
"Upgrade INFO" \
"X-Served-By INFO" \
"Referrer-Policy INFO" \
From ad912ea332943630bc8912382cc8afbe44010918 Mon Sep 17 00:00:00 2001
From: Dirk
Date: Wed, 22 Jan 2025 20:05:19 +0100
Subject: [PATCH 16/28] Fix typo + tags
---
testssl.sh | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/testssl.sh b/testssl.sh
index 6474414..02a2ac8 100755
--- a/testssl.sh
+++ b/testssl.sh
@@ -3127,7 +3127,7 @@ emphasize_stuff_in_headers(){
-e "s/X-Powered-By/${yellow}X-Powered-By${off}/g" \
-e "s/X-UA-Compatible/${yellow}X-UA-Compatible${off}/g" \
-e "s/Link/${yellow}Link${off}/g" \
- -e "s/X-DNS-Prefetch-Control/${html_yellow}X-DNS-Prefetch-Control${html_off}/g" \
+ -e "s/X-DNS-Prefetch-Control/${yellow}X-DNS-Prefetch-Control${off}/g" \
-e "s/X-Rack-Cache/${yellow}X-Rack-Cache${off}/g" \
-e "s/X-Runtime/${yellow}X-Runtime${off}/g" \
-e "s/X-Pingback/${yellow}X-Pingback${off}/g" \
@@ -3183,14 +3183,13 @@ emphasize_stuff_in_headers(){
-e "s/X-Pingback/${html_yellow}X-Pingback${html_off}/g" \
-e "s/X-Permitted-Cross-Domain-Policies/${html_yellow}X-Permitted-Cross-Domain-Policies${html_off}/g" \
-e "s/X-AspNet-Version/${html_yellow}X-AspNet-Version${html_off}/g" \
- -e "s/X-AspNetMvc-Version/${yellow}X-AspNetMvc-Version${off}/g" \
+ -e "s/X-AspNetMvc-Version/${html_yellow}X-AspNetMvc-Version${html_off}/g" \
-e "s/x-note/${html_yellow}x-note${html_off}/g" \
-e "s/X-Global-Transaction-ID/${html_yellow}X-Global-Transaction-ID${html_off}/g" \
-e "s/x-global-transaction-id/${html_yellow}x-global-transaction-id${html_off}/g" \
-e "s/Alt-Svc/${html_yellow}Alt-Svc${html_off}/g" \
-e "s/system-wsgw-management-loopback/${html_yellow}system-wsgw-management-loopback${html_off}/g"
-#FIXME: this is double code. The pattern to emphasize would fit better into
-# one function.
+#FIXME: this is double code. The pattern to emphasize would fit better into one function.
# Also we need another function like run_other_header as otherwise "Link" "Alt-Svc" will never be found.
# And: I matches case sensitive only which might not detect all banners. (sed ignorecase is not possible w/ BSD sed)
else
@@ -3439,7 +3438,7 @@ run_security_headers() {
pr_bold " Security headers "
# X-XSS-Protection is useless and at worst harmful, see https://news.ycombinator.com/item?id=20472947
- # Expect-CT is depecated, see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expect-CT
+ # Expect-CT is deprecated, see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expect-CT
for header_and_svrty in "X-Frame-Options OK" \
"X-Content-Type-Options OK" \
"Content-Security-Policy OK" \
From 4df0d9e4c343a673cce01d40f413fb92e1af1068 Mon Sep 17 00:00:00 2001
From: Dirk
Date: Wed, 22 Jan 2025 23:32:39 +0100
Subject: [PATCH 17/28] Re-added the ) to make the action word (why??)
---
testssl.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/testssl.sh b/testssl.sh
index 6bb8c26..0672297 100755
--- a/testssl.sh
+++ b/testssl.sh
@@ -3182,7 +3182,7 @@ emphasize_stuff_in_headers(){
-e "s/X-DNS-Prefetch-Control/${html_yellow}X-DNS-Prefetch-Control${html_off}/g" \
-e "s/X-Pingback/${html_yellow}X-Pingback${html_off}/g" \
-e "s/X-Permitted-Cross-Domain-Policies/${html_yellow}X-Permitted-Cross-Domain-Policies${html_off}/g" \
- -e "s/X-AspNet-Version/${html_yellow}X-AspNet-Version${html_off}/g" \
+ -e "s/X-AspNet-Version/${html_yellow}X-AspNet-Version${html_off}/g")" \
-e "s/X-AspNetMvc-Version/${html_yellow}X-AspNetMvc-Version${html_off}/g" \
-e "s/x-note/${html_yellow}x-note${html_off}/g" \
-e "s/X-Global-Transaction-ID/${html_yellow}X-Global-Transaction-ID${html_off}/g" \
From d7da22d598084b66546bf8ff32ff2471c94c8b1f Mon Sep 17 00:00:00 2001
From: Dirk
Date: Wed, 22 Jan 2025 23:33:35 +0100
Subject: [PATCH 18/28] Finalize check
* use system with @args so that we can query the return value
* code style improved for readability
* diff shows the filtered difference
* ok instead of cmp_ok to show not the whole content of vars
---
t/61_diff_testsslsh.t | 56 +++++++++++++++++++++----------------------
1 file changed, 27 insertions(+), 29 deletions(-)
diff --git a/t/61_diff_testsslsh.t b/t/61_diff_testsslsh.t
index f4070b1..18c3bfb 100755
--- a/t/61_diff_testsslsh.t
+++ b/t/61_diff_testsslsh.t
@@ -3,11 +3,10 @@
# Baseline diff test against testssl.sh (csv output)
#
# We don't use a full run yet and only the certificate section.
-# There we would need to blacklist at least:
+# There we would need to blacklist more, like:
# cert_serialNumber, cert_fingerprintSHA1, cert_fingerprintSHA256, cert
# cert_expirationStatus, cert_notBefore, cert_notAfter, cert_caIssuers, intermediate_cert
#
-# help is appreciated here
use strict;
use Test::More;
@@ -16,55 +15,54 @@ use Text::Diff;
my $tests = 0;
my $prg="./testssl.sh";
-my $master_socket_csv="./t/baseline_data/default_testssl.csvfile";
-my $socket_csv="tmp.csv";
-my $check2run="-p -s -P --fs -h -U -c -q --ip=one --color 0 --csvfile $socket_csv";
-#my $check2run="-p --color 0 --csvfile $socket_csv";
+my $baseline_csv="./t/baseline_data/default_testssl.csvfile";
+my $cat_csv="tmp.csv";
+my $check2run="-p -s -P --fs -h -U -c -q --ip=one --color 0 --csvfile $cat_csv";
my $uri="testssl.sh";
my $diff="";
die "Unable to open $prg" unless -f $prg;
-die "Unable to open $master_socket_csv" unless -f $master_socket_csv;
-
+die "Unable to open $baseline_csv" unless -f $baseline_csv;
# Provide proper start conditions
-unlink "tmp.csv";
+unlink $cat_csv;
-# Title
-printf "\n%s\n", "Diff unit test IPv4 against \"$uri\"";
+my @args=("$prg", "$check2run", "$uri", "2>&1");
#1 run
-`$prg $check2run $uri 2>&1`;
+printf "\n%s\n", "Diff unit test (IPv4) against \"$uri\"";
+printf "@args\n";
+system("@args") == 0
+ or die ("FAILED: \"@args\" ");
-$diff = diff $socket_csv, $master_socket_csv;
-
-$socket_csv=`cat tmp.csv`;
-$master_socket_csv=`cat $master_socket_csv`;
+$cat_csv=`cat $cat_csv`;
+$baseline_csv=`cat $baseline_csv`;
# Filter for changes that are allowed to occur
-$socket_csv=~ s/HTTP_clock_skew.*\n//g;
-$master_socket_csv=~ s/HTTP_clock_skew.*\n//g;
-
-# DROWN
-$socket_csv=~ s/censys.io.*\n//g;
-$master_socket_csv=~ s/censys.io.*\n//g;
+$cat_csv =~ s/HTTP_clock_skew.*\n//g;
+$baseline_csv =~ s/HTTP_clock_skew.*\n//g;
# HTTP time
-$socket_csv=~ s/HTTP_headerTime.*\n//g;
-$master_socket_csv=~ s/HTTP_headerTime.*\n//g;
+$cat_csv =~ s/HTTP_headerTime.*\n//g;
+$baseline_csv =~ s/HTTP_headerTime.*\n//g;
-# Compare the differences to the master file -- and print differences if there were detected.
+# DROWN
+$cat_csv =~ s/censys.io.*\n//g;
+$baseline_csv =~ s/censys.io.*\n//g;
+
+$diff = diff \$cat_csv, \$baseline_csv;
+
+# Compare the differences to the baseline file -- and print differences if there were detected.
#
-cmp_ok($socket_csv, "eq", $master_socket_csv, "Check whether CSV output matches master file from $uri") or
+ok($cat_csv eq $baseline_csv, "Check whether CSV output matches baseline file from $uri") or
diag ("\n%s\n", "$diff");
-$tests++;
-
unlink "tmp.csv";
+$tests++;
done_testing($tests);
printf "\n";
-# vim:ts=5:sw=5:expandtab
+# vim:ts=5:sw=5:expandtab
From fb3921cd1b2c9e392e9ff76ae349d05042624c04 Mon Sep 17 00:00:00 2001
From: Hyeonho Kang
Date: Thu, 23 Jan 2025 13:10:12 +0900
Subject: [PATCH 19/28] Edit CONTRIBUTING.md
---
CONTRIBUTING.md | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index eb9098e..5301665 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,21 +1,16 @@
-### Contribution
+### Contributing / participating
-Contribution is always welcome, submit here (GitHub) or via e-mail.
+Contributing / participating is always welcome!
Please note the following:
* Please read at least the [coding convention](https://github.com/testssl/testssl.sh/blob/3.2/Coding_Convention.md).
-* One Pull Request per feature or bug fix or improvement. Please do not mix issues.
-* Document your Pull Request, both in the Pull Request and/or commit message and in the code.
+* One pull request per feature or bug fix or improvement. Please do not mix issues.
+* Document your pull request, both in the pull request and/or commit message and in the code.
* Please test your changes thoroughly as reliability is important for this project. You may want to check different servers with different settings.
-* Travis runs automatically when anything is committed/pull requested. You should check any complains from Travis. Beforehand you can check with `prove -v`.
+* GitHub Actions runs automatically when anything is committed. You should check any complains from GitHub Actions. Beforehand you can check with `prove -v`.
* If it's a new feature, please consider writing a unit test for it. You can use e.g. `t/20_baseline_ipv4_http.t` as a template. The general documentation for [Test::More](https://perldoc.perl.org/Test/More.html) is a good start.
* If it's a new feature, it would need to be documented in the appropriate section in `help()` and in `~/doc/testssl.1.md`
-For the questions, just open an issue or feel free to send us an e-mail.
-
-#### Contribute via e-mail
-
-Of course it is fine when you want to send in patches to use e-mail. For the address, please grep for SWCONTACT in testssl.sh.
-Let me know how you like them to be attributed.
+For the questions, just open an issue.
From 4efe324ef7ac4b5d72e05035da4e95b385ec794e Mon Sep 17 00:00:00 2001
From: Dirk Wetter
Date: Thu, 23 Jan 2025 10:45:15 +0100
Subject: [PATCH 20/28] Fix round bracket and remove obsolete comment
---
testssl.sh | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/testssl.sh b/testssl.sh
index 0672297..5655670 100755
--- a/testssl.sh
+++ b/testssl.sh
@@ -582,8 +582,6 @@ tmln_out() { printf -- "%b" "$1\n"; }
out() { printf -- "%b" "$1"; html_out "$(html_reserved "$1")"; }
outln() { printf -- "%b" "$1\n"; html_out "$(html_reserved "$1")\n"; }
-#TODO: Still no shell injection safe but if just run it from the cmd line: that's fine
-
# Color print functions, see also https://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html
tm_liteblue() { [[ "$COLOR" -ge 2 ]] && { "$COLORBLIND" && tm_out "\033[0;32m$1" || tm_out "\033[0;34m$1"; } || tm_out "$1"; tm_off; } # not yet used
pr_liteblue() { tm_liteblue "$1"; [[ "$COLOR" -ge 2 ]] && { "$COLORBLIND" && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; } || html_out "$(html_reserved "$1")"; }
@@ -3143,7 +3141,7 @@ emphasize_stuff_in_headers(){
if "$do_html"; then
if [[ $COLOR -ge 2 ]]; then
html_out "$(tm_out "$1" | sed -e 's/\&/\&/g' \
- -e 's/\</g' -e 's/>/\>/g' -e 's/"/\"/g' -e "s/'/\'/g" \
+ -e 's/\</g' -e 's/>/\>/g' -e 's/\"/\"/g' -e "s/\'/\'/g" \
-e "s/\([0-9]\)/${html_brown}\1${html_off}/g" \
-e "s/Unix/${html_yellow}Unix${html_off}/g" \
-e "s/Debian/${html_yellow}Debian${html_off}/g" \
@@ -3182,16 +3180,16 @@ emphasize_stuff_in_headers(){
-e "s/X-DNS-Prefetch-Control/${html_yellow}X-DNS-Prefetch-Control${html_off}/g" \
-e "s/X-Pingback/${html_yellow}X-Pingback${html_off}/g" \
-e "s/X-Permitted-Cross-Domain-Policies/${html_yellow}X-Permitted-Cross-Domain-Policies${html_off}/g" \
- -e "s/X-AspNet-Version/${html_yellow}X-AspNet-Version${html_off}/g")" \
+ -e "s/X-AspNet-Version/${html_yellow}X-AspNet-Version${html_off}/g" \
-e "s/X-AspNetMvc-Version/${html_yellow}X-AspNetMvc-Version${html_off}/g" \
-e "s/x-note/${html_yellow}x-note${html_off}/g" \
-e "s/X-Global-Transaction-ID/${html_yellow}X-Global-Transaction-ID${html_off}/g" \
-e "s/x-global-transaction-id/${html_yellow}x-global-transaction-id${html_off}/g" \
-e "s/Alt-Svc/${html_yellow}Alt-Svc${html_off}/g" \
- -e "s/system-wsgw-management-loopback/${html_yellow}system-wsgw-management-loopback${html_off}/g"
-#FIXME: this is double code. The pattern to emphasize would fit better into one function.
-# Also we need another function like run_other_header as otherwise "Link" "Alt-Svc" will never be found.
-# And: I matches case sensitive only which might not detect all banners. (sed ignorecase is not possible w/ BSD sed)
+ -e "s/system-wsgw-management-loopback/${html_yellow}system-wsgw-management-loopback${html_off}/g" \
+ )"
+#FIXME: this is double code. The pattern to emphasize headers should be better in one single function
+# And: It matches case sensitive headers only which won't detect all banners. (sed ignorecase is not a/v for OpenBSD sed)
else
html_out "$(html_reserved "$1")"
fi
From 90f1e59e9f021b5bc687cb6cfb0ac2bbdff721f7 Mon Sep 17 00:00:00 2001
From: Dirk
Date: Thu, 23 Jan 2025 17:37:32 +0100
Subject: [PATCH 21/28] Merge #2618 and doing some overdue amendments
---
CONTRIBUTING.md | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 5301665..9fd3cbe 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -5,12 +5,21 @@ Contributing / participating is always welcome!
Please note the following:
-* Please read at least the [coding convention](https://github.com/testssl/testssl.sh/blob/3.2/Coding_Convention.md).
-* One pull request per feature or bug fix or improvement. Please do not mix issues.
-* Document your pull request, both in the pull request and/or commit message and in the code.
+* Please read the [coding convention](https://github.com/testssl/testssl.sh/blob/3.2/Coding_Convention.md).
+* If you have something new and/or bigger which you like to contribute, better open an issue first before you get frustrated.
+* Please one pull request per feature or bug fix or improvement. Please do not mix issues.
+* Documention pays off in the long run. So please your document your code and the pull request and/or commit message.
* Please test your changes thoroughly as reliability is important for this project. You may want to check different servers with different settings.
-* GitHub Actions runs automatically when anything is committed. You should check any complains from GitHub Actions. Beforehand you can check with `prove -v`.
-* If it's a new feature, please consider writing a unit test for it. You can use e.g. `t/20_baseline_ipv4_http.t` as a template. The general documentation for [Test::More](https://perldoc.perl.org/Test/More.html) is a good start.
+* GitHub actions are running automatically when anything is committed. You should see any complains. Beforehand you can check with `prove -v` from the "root dir"of tjhis project
+* If it's a new feature, please consider writing a unit test for it. You can use e.g. `t/10_baseline_ipv4_http.t` or `t/61_diff_testsslsh.t` as a template. The general documentation for [Test::More](https://perldoc.perl.org/Test/More.html) is a good start.
* If it's a new feature, it would need to be documented in the appropriate section in `help()` and in `~/doc/testssl.1.md`
-For the questions, just open an issue.
+If you're interested in contributing and wonder how you can help, you can search for different tags in the issues (somehwat increasing degree of difficulty):
+* [documentation](https://github.com/testssl/testssl.sh/issues?q=is:issue%20state:open%20label:documentation)
+* [good first issue](https://github.com/testssl/testssl.sh/issues?q=is:issue%20state:open%20label:%22good%20first%20issue%22)
+* [help wanted](https://github.com/testssl/testssl.sh/issues?q=is:issue%20state:open%20label:%22help%20wanted%22)
+* [for grabs](https://github.com/testssl/testssl.sh/issues?q=is:issue%20state:open%20label:%22good%20first%20issue%22)
+
+For questions just open an issue. Thanks for reading this!
+
+
From b185b1bea96aec23d922beff84cf00b0e352309d Mon Sep 17 00:00:00 2001
From: Dirk
Date: Thu, 23 Jan 2025 17:41:36 +0100
Subject: [PATCH 22/28] Fix typo
---
CONTRIBUTING.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 9fd3cbe..1029fbe 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -8,13 +8,13 @@ Please note the following:
* Please read the [coding convention](https://github.com/testssl/testssl.sh/blob/3.2/Coding_Convention.md).
* If you have something new and/or bigger which you like to contribute, better open an issue first before you get frustrated.
* Please one pull request per feature or bug fix or improvement. Please do not mix issues.
-* Documention pays off in the long run. So please your document your code and the pull request and/or commit message.
+* Documentation pays off in the long run. So please your document your code and the pull request and/or commit message.
* Please test your changes thoroughly as reliability is important for this project. You may want to check different servers with different settings.
-* GitHub actions are running automatically when anything is committed. You should see any complains. Beforehand you can check with `prove -v` from the "root dir"of tjhis project
+* GitHub actions are running automatically when anything is committed. You should see any complains. Beforehand you can check with `prove -v` from the "root dir" of this project.
* If it's a new feature, please consider writing a unit test for it. You can use e.g. `t/10_baseline_ipv4_http.t` or `t/61_diff_testsslsh.t` as a template. The general documentation for [Test::More](https://perldoc.perl.org/Test/More.html) is a good start.
* If it's a new feature, it would need to be documented in the appropriate section in `help()` and in `~/doc/testssl.1.md`
-If you're interested in contributing and wonder how you can help, you can search for different tags in the issues (somehwat increasing degree of difficulty):
+If you're interested in contributing and wonder how you can help, you can search for different tags in the issues (somewhat increasing degree of difficulty):
* [documentation](https://github.com/testssl/testssl.sh/issues?q=is:issue%20state:open%20label:documentation)
* [good first issue](https://github.com/testssl/testssl.sh/issues?q=is:issue%20state:open%20label:%22good%20first%20issue%22)
* [help wanted](https://github.com/testssl/testssl.sh/issues?q=is:issue%20state:open%20label:%22help%20wanted%22)
From 0042b6313efdeda7af9740a0994c2e9f70599dda Mon Sep 17 00:00:00 2001
From: Dirk Wetter
Date: Fri, 24 Jan 2025 11:15:55 +0100
Subject: [PATCH 23/28] s/drwetter/testssl
For the remaining occurences. Except dockerhub which needs to be solved.
---
bin/Readme.md | 6 +++---
doc/testssl.1 | 2 +-
doc/testssl.1.html | 2 +-
doc/testssl.1.md | 2 +-
etc/tls_data.txt | 2 +-
t/11_baseline_ipv6_http.t.DISABLED | 2 +-
utils/make-openssl.sh | 2 +-
7 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/bin/Readme.md b/bin/Readme.md
index 83d7094..2998804 100644
--- a/bin/Readme.md
+++ b/bin/Readme.md
@@ -10,7 +10,7 @@ for some new / advanced cipher suites and/or features which are not in the
official branch like (old version of the) CHACHA20+POLY1305 and CAMELLIA 256 bit ciphers.
The (stripped) binaries this directory are all compiled from my openssl snapshot
-(https://github.com/drwetter/openssl-1.0.2.bad) which adds a few bits to Peter
+(https://github.com/testssl/openssl-1.0.2.bad) which adds a few bits to Peter
Mosman's openssl fork (https://github.com/PeterMosmans/openssl). Thx a bunch, Peter!
The few bits are IPv6 support (except IPV6 proxy) and some STARTTLS backports.
@@ -71,11 +71,11 @@ Compilation instructions
If you want to compile OpenSSL yourself, here are the instructions:
1.)
- git git clone https://github.com/drwetter/openssl-1.0.2-bad
+ git git clone https://github.com/testssl/openssl-1.0.2-bad
cd openssl
-2.) configure the damned thing. Options I used (see https://github.com/drwetter/testssl.sh/blob/master/utils/make-openssl.sh)
+2.) configure the damned thing. Options I used (see https://github.com/testssl/testssl.sh/blob/master/utils/make-openssl.sh)
**for 64Bit including Kerberos ciphers:**
diff --git a/doc/testssl.1 b/doc/testssl.1
index e57bc0e..810d54a 100644
--- a/doc/testssl.1
+++ b/doc/testssl.1
@@ -607,4 +607,4 @@ All native Windows platforms emulating Linux are known to be slow\.
.SH "BUGS"
Probably\. Current known ones and interface for filing new ones: https://testssl\.sh/bugs/ \.
.SH "SEE ALSO"
-\fBciphers\fR(1), \fBopenssl\fR(1), \fBs_client\fR(1), \fBx509\fR(1), \fBverify\fR(1), \fBocsp\fR(1), \fBcrl\fR(1), \fBbash\fR(1) and the websites https://testssl\.sh/ and https://github\.com/drwetter/testssl\.sh/ \.
+\fBciphers\fR(1), \fBopenssl\fR(1), \fBs_client\fR(1), \fBx509\fR(1), \fBverify\fR(1), \fBocsp\fR(1), \fBcrl\fR(1), \fBbash\fR(1) and the websites https://testssl\.sh/ and https://github\.com/testssl/testssl\.sh/ \.
diff --git a/doc/testssl.1.html b/doc/testssl.1.html
index dbcbba5..0336c4b 100644
--- a/doc/testssl.1.html
+++ b/doc/testssl.1.html
@@ -681,7 +681,7 @@ from. That helps us to get bugfixes, other feedback and more contributions.
SEE ALSO
-ciphers
(1), openssl
(1), s_client
(1), x509
(1), verify
(1), ocsp
(1), crl
(1), bash
(1) and the websites https://testssl.sh/ and https://github.com/drwetter/testssl.sh/ .
+ciphers
(1), openssl
(1), s_client
(1), x509
(1), verify
(1), ocsp
(1), crl
(1), bash
(1) and the websites https://testssl.sh/ and https://github.com/testssl/testssl.sh/ .