Bin: analyse-headers: better csp, x-xss, referer-policy and simple mode

The changes amount to the following.

x-xss-protection now "passes" if it's set to 1; mode=block

The CSP now fails if it doesn't have either a script-src or a
default-src.

It now checks for referrer-policy

simple mode is available which doesn't use colours, and instead prepends
each line with either "Misconfigured", "Good", or "Missing. Useful for
automating"
master
Jonathan Hodgson 10 months ago
parent 2945b1f58b
commit f7d545b57e
  1. 69
      bin/.bin/webtest/analyse-headers

@ -65,11 +65,20 @@ drawInBox(){
# 1 = yellow # 1 = yellow
# 2 = red # 2 = red
getColour(){ getColour(){
case "$1" in if [ "$simple" == "true" ]; then
0) echo -en "$GREEN" ;; case "$1" in
1) echo -en "$YELLOW" ;; 0) echo "Good - " ;;
2) echo -en "$RED" ;; 1) echo "Misconfigured - " ;;
esac 2) echo "Missing - " ;;
esac
else
case "$1" in
0) echo -en "$GREEN" ;;
1) echo -en "$YELLOW" ;;
2) echo -en "$RED" ;;
esac
fi
} }
printKey(){ printKey(){
@ -126,8 +135,8 @@ test_x-powered-by(){
test_x-xss-protection(){ test_x-xss-protection(){
local value local value
value="$(echo "$1" | cut -d ':' -f 2 | grep -oE '[0-9]+' )" value="$(echo "$1" | cut -d ':' -f 2 | trimWhitespace )"
if [ "$value" = "0" ]; then if [ "$value" = "0" ] || [ "$value" = "1; mode=block" ]; then
return 0 return 0
else else
echo "X-XSS-Protection" | drawInBox echo "X-XSS-Protection" | drawInBox
@ -387,6 +396,7 @@ attacks (XSS).\n\n"
local reportURI=false local reportURI=false
local reportTO=false local reportTO=false
local scriptOrDefaultSrc=false
[ -f "$lotsfile" ] || message+="WARNING: Lots file not available. Run with --fetch-lots in order to get it\n\n" [ -f "$lotsfile" ] || message+="WARNING: Lots file not available. Run with --fetch-lots in order to get it\n\n"
@ -398,6 +408,9 @@ attacks (XSS).\n\n"
"report-to" ) reportTO=true ;; "report-to" ) reportTO=true ;;
*"-src") *"-src")
# check sources # check sources
if [ "$directiveName" = "script-src" ] | [ "$directiveName" = "default-src" ]; then
scriptOrDefaultSrc=true;
fi
while read source; do while read source; do
sourcemessage='' sourcemessage=''
case "$source" in case "$source" in
@ -462,6 +475,12 @@ Eventually the report-to header will deprecate this directive, but it is not \
yet supported in most browsers so including both is recomended.\n\n" yet supported in most browsers so including both is recomended.\n\n"
ret=$((ret>1 ? ret : 1)) ret=$((ret>1 ? ret : 1))
fi fi
if [ "$scriptOrDefaultSrc" == "false" ]; then
message+="The content security policy doesn't include the \
${ORANGE}script-src${NC} or ${ORANGE}script-src${NC} directive which are used \
add allowed script sources. Without either, any scripts are allowed by default.\n\n"
ret=$((ret>1 ? ret : 1))
fi
# elif echo "$value" | grep -q 'unsafe-eval'; then # elif echo "$value" | grep -q 'unsafe-eval'; then
# ret=$((ret>1 ? ret : 1)) # ret=$((ret>1 ? ret : 1))
@ -715,6 +734,17 @@ they should not be cached. In order to enforce this, add the no-store directive.
} }
test_referrer-policy(){
local value
value="$(echo "$1" | cut -d ':' -f 2- | trimWhitespace)"
if [ -z "$1" ] || ! echo "$value" | grep -q "strict-origin"; then
echo "Referrer-policy" | drawInBox
wecho "This allows control over what information is sent to another site within the referrer header. The referrer header is commonly used in site analytics to understand where traffic to a site is coming from.\n"
echo -e "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control\n\n"
[ -z "$1" ] && return 2 || return 1
fi
}
usage(){ usage(){
echo -n "analyse-headers [OPTIONS]... URL echo -n "analyse-headers [OPTIONS]... URL
@ -767,6 +797,7 @@ set -- "${options[@]}"
unset options unset options
insecure="" insecure=""
simple="false"
windowsjoke=false windowsjoke=false
if grep -q Microsoft /proc/version; then if grep -q Microsoft /proc/version; then
@ -778,6 +809,7 @@ while [[ $1 = -?* ]]; do
case $1 in case $1 in
-h|--help) usage; exit;; -h|--help) usage; exit;;
-k|--insecure) insecure="-k" ;; -k|--insecure) insecure="-k" ;;
--simple) simple="true" ;;
--fetch-lots ) fetchLots; exit ;; --fetch-lots ) fetchLots; exit ;;
--nojoke ) windowsjoke=false ;; --nojoke ) windowsjoke=false ;;
--) shift; break ;; --) shift; break ;;
@ -806,7 +838,8 @@ x-xss-protection
x-content-type-options x-content-type-options
permissions-policy permissions-policy
feature-policy feature-policy
cache-control" cache-control
referrer-policy"
tmpfile="$(mktemp)" tmpfile="$(mktemp)"
touch "$tmpfile" touch "$tmpfile"
@ -815,9 +848,11 @@ if [ "$windowsjoke" == "true" ]; then
echo "Why would you use windows, do you hate yourself?" echo "Why would you use windows, do you hate yourself?"
fi fi
printKey if [ "$simple" == "false" ]; then
printKey
echo "" echo ""
fi
echo "$headers" | sed -n '1p' echo "$headers" | sed -n '1p'
@ -837,19 +872,27 @@ while read -r line; do
colour="$(getColour "$?")" colour="$(getColour "$?")"
echo -e "${colour}$line${NC}" echo -e "${colour}$line${NC}"
else else
echo "$line" if [ "$simple" == "false" ]; then
echo "$line"
fi
fi fi
done<<<"$(echo "$headers" | sed '1d')" # We don't want the initial http banner done<<<"$(echo "$headers" | sed '1d')" # We don't want the initial http banner
echo "$missingHeaders" | while read -r line; do echo "$missingHeaders" | while read -r line; do
echo -e "${RED}$line${NC}" if [ "$simple" == "false" ]; then
echo -e "${RED}$line${NC}"
else
echo "Missing - $line"
fi
functionName="test_$line" functionName="test_$line"
"$functionName" >> "$tmpfile" "$functionName" >> "$tmpfile"
done done
echo "" echo ""
cat "$tmpfile" if [ "$simple" == "false" ]; then
cat "$tmpfile"
fi
rm "$tmpfile" rm "$tmpfile"

Loading…
Cancel
Save