Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more security headers #2619

Merged
merged 7 commits into from
Jan 23, 2025
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
54 changes: 26 additions & 28 deletions t/61_diff_testsslsh.t
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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`;

$diff = diff $socket_csv, $master_socket_csv;
printf "\n%s\n", "Diff unit test (IPv4) against \"$uri\"";
printf "@args\n";
system("@args") == 0
or die ("FAILED: \"@args\" ");

$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;
$cat_csv =~ s/HTTP_clock_skew.*\n//g;
$baseline_csv =~ s/HTTP_clock_skew.*\n//g;

# HTTP time
$cat_csv =~ s/HTTP_headerTime.*\n//g;
$baseline_csv =~ s/HTTP_headerTime.*\n//g;

# DROWN
$socket_csv=~ s/censys.io.*\n//g;
$master_socket_csv=~ s/censys.io.*\n//g;
$cat_csv =~ s/censys.io.*\n//g;
$baseline_csv =~ s/censys.io.*\n//g;

# HTTP time
$socket_csv=~ s/HTTP_headerTime.*\n//g;
$master_socket_csv=~ s/HTTP_headerTime.*\n//g;
$diff = diff \$cat_csv, \$baseline_csv;

# Compare the differences to the master file -- and print differences if there were detected.
# 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

6 changes: 4 additions & 2 deletions t/baseline_data/default_testssl.csvfile
Original file line number Diff line number Diff line change
Expand Up @@ -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","",""
Expand All @@ -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"
Expand All @@ -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"
Expand Down
31 changes: 19 additions & 12 deletions testssl.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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 "<span style=\"color:#008817;\">$(html_reserved "$1")</span>" || html_out "<span style=\"color:#0000ee;\">$(html_reserved "$1")</span>"; } || html_out "$(html_reserved "$1")"; }
Expand Down Expand Up @@ -3127,11 +3125,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/${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" \
-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" \
Expand All @@ -3141,7 +3141,7 @@ emphasize_stuff_in_headers(){
if "$do_html"; then
if [[ $COLOR -ge 2 ]]; then
html_out "$(tm_out "$1" | sed -e 's/\&/\&amp;/g' \
-e 's/</\&lt;/g' -e 's/>/\&gt;/g' -e 's/"/\&quot;/g' -e "s/'/\&apos;/g" \
-e 's/</\&lt;/g' -e 's/>/\&gt;/g' -e 's/\"/\&quot;/g' -e "s/\'/\&apos;/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" \
Expand Down Expand Up @@ -3177,18 +3177,19 @@ 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/${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
Expand Down Expand Up @@ -3435,16 +3436,22 @@ 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 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" \
"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" \
"Expect-CT INFO" \
"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" \
"Permissions-Policy INFO" \
"Upgrade INFO" \
"X-Served-By INFO" \
"Referrer-Policy INFO" \
Expand Down
Loading