Skip to content

Commit 01ab3ac

Browse files
committed
Strict parser for HSTS
As suggested in #2381 this parses strictly the value for mag-age in the HSTS header line. While it is implemented only in run_hsts() it could be extracted to a separate functioni in the future and used elsewhere too. The improvement is more strict and catches e.g. '==' signs and issues a warning. See https://www.rfc-editor.org/rfc/rfc6797#section-6.1.1 . Also it is picky regarding quotes now which are only allowed enclosing the value.
1 parent 1e7219f commit 01ab3ac

1 file changed

Lines changed: 32 additions & 20 deletions

File tree

testssl.sh

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2715,28 +2715,40 @@ run_hsts() {
27152715
match_httpheader_key "Strict-Transport-Security" "HSTS" "$spaces" "true"
27162716
if [[ $? -ne 0 ]]; then
27172717
echo "$HEADERVALUE" >$TMPFILE
2718-
hsts_age_sec="${HEADERVALUE//[^0-9]/}"
2718+
# strict parsing now as suggested in #2381
2719+
hsts_age_sec="${HEADERVALUE#*=}"
2720+
hsts_age_sec=${hsts_age_sec%%;*}
2721+
if [[ $hsts_age_sec =~ \" ]]; then
2722+
# remove first an last " in $hsts_age_sec (borrowed from strip_trailing_space/strip_leading_space):
2723+
hsts_age_sec=$(printf "%s" "${hsts_age_sec#"${hsts_age_sec%%[!\"]*}"}")
2724+
hsts_age_sec=$(printf "%s" "${hsts_age_sec%"${hsts_age_sec##*[!\"]}"}")
2725+
fi
27192726
debugme echo "hsts_age_sec: $hsts_age_sec"
2720-
if [[ -n $hsts_age_sec ]]; then
2721-
hsts_age_days=$(( hsts_age_sec / 86400))
2722-
else
2723-
hsts_age_days=-1
2724-
fi
2725-
if [[ $hsts_age_days -eq -1 ]]; then
2726-
pr_svrty_medium "misconfiguration: HSTS max-age (recommended > $HSTS_MIN seconds = $((HSTS_MIN/86400)) days ) is required but missing"
2727-
fileout "${jsonID}_time" "MEDIUM" "misconfiguration, parameter max-age (recommended > $HSTS_MIN seconds = $((HSTS_MIN/86400)) days) missing"
2728-
set_grade_cap "A" "HSTS max-age is misconfigured"
2729-
elif [[ $hsts_age_sec -eq 0 ]]; then
2730-
pr_svrty_low "HSTS max-age is set to 0. HSTS is disabled"
2731-
fileout "${jsonID}_time" "LOW" "0. HSTS is disabled"
2732-
set_grade_cap "A" "HSTS is disabled"
2733-
elif [[ $hsts_age_sec -ge $HSTS_MIN ]]; then
2734-
pr_svrty_good "$hsts_age_days days" ; out "=$hsts_age_sec s"
2735-
fileout "${jsonID}_time" "OK" "$hsts_age_days days (=$hsts_age_sec seconds) > $HSTS_MIN seconds"
2727+
if ! is_number "$hsts_age_sec"; then
2728+
pr_svrty_medium "misconfiguration: \'"$hsts_age_sec"\' is not a valid max-age specification"
2729+
fileout "${jsonID}_time" "MEDIUM" "misconfiguration, specified not a number for max-age"
27362730
else
2737-
pr_svrty_medium "$hsts_age_sec s = $hsts_age_days days is too short ( >= $HSTS_MIN seconds recommended)"
2738-
fileout "${jsonID}_time" "MEDIUM" "max-age too short. $hsts_age_days days (=$hsts_age_sec seconds) < $HSTS_MIN seconds"
2739-
set_grade_cap "A" "HSTS max-age is too short"
2731+
if [[ -n $hsts_age_sec ]]; then
2732+
hsts_age_days=$(( hsts_age_sec / 86400))
2733+
else
2734+
hsts_age_days=-1
2735+
fi
2736+
if [[ $hsts_age_days -eq -1 ]]; then
2737+
pr_svrty_medium "misconfiguration: HSTS max-age (recommended > $HSTS_MIN seconds = $((HSTS_MIN/86400)) days ) is required but missing"
2738+
fileout "${jsonID}_time" "MEDIUM" "misconfiguration, parameter max-age (recommended > $HSTS_MIN seconds = $((HSTS_MIN/86400)) days) missing"
2739+
set_grade_cap "A" "HSTS max-age is misconfigured"
2740+
elif [[ $hsts_age_sec -eq 0 ]]; then
2741+
pr_svrty_low "HSTS max-age is set to 0. HSTS is disabled"
2742+
fileout "${jsonID}_time" "LOW" "0. HSTS is disabled"
2743+
set_grade_cap "A" "HSTS is disabled"
2744+
elif [[ $hsts_age_sec -ge $HSTS_MIN ]]; then
2745+
pr_svrty_good "$hsts_age_days days" ; out "=$hsts_age_sec s"
2746+
fileout "${jsonID}_time" "OK" "$hsts_age_days days (=$hsts_age_sec seconds) > $HSTS_MIN seconds"
2747+
else
2748+
pr_svrty_medium "$hsts_age_sec s = $hsts_age_days days is too short ( >= $HSTS_MIN seconds recommended)"
2749+
fileout "${jsonID}_time" "MEDIUM" "max-age too short. $hsts_age_days days (=$hsts_age_sec seconds) < $HSTS_MIN seconds"
2750+
set_grade_cap "A" "HSTS max-age is too short"
2751+
fi
27402752
fi
27412753
if includeSubDomains "$TMPFILE"; then
27422754
fileout "${jsonID}_subdomains" "OK" "includes subdomains"

0 commit comments

Comments
 (0)