diff --git a/testssl.sh b/testssl.sh index d9a1679..a6998a2 100755 --- a/testssl.sh +++ b/testssl.sh @@ -196,6 +196,7 @@ CLIENT_AUTH=false NO_SSL_SESSIONID=false HOSTCERT="" HEADERFILE="" +HTTP_STATUS_CODE="" PROTOS_OFFERED="" TLS_EXTENSIONS="" GOST_STATUS_PROBLEM=false @@ -748,66 +749,66 @@ run_http_header() { mv $HEADERFILE.2 $HEADERFILE # sed'ing in place doesn't work with BSD and Linux simultaneously ret=0 - status_code=$(awk '/^HTTP\// { print $2 }' $HEADERFILE 2>>$ERRFILE) - msg_thereafter=$(awk -F"$status_code" '/^HTTP\// { print $2 }' $HEADERFILE 2>>$ERRFILE) # dirty trick to use the status code as a + HTTP_STATUS_CODE=$(awk '/^HTTP\// { print $2 }' $HEADERFILE 2>>$ERRFILE) + msg_thereafter=$(awk -F"$HTTP_STATUS_CODE" '/^HTTP\// { print $2 }' $HEADERFILE 2>>$ERRFILE) # dirty trick to use the status code as a msg_thereafter=$(strip_lf "$msg_thereafter") # field separator, otherwise we need a loop with awk - debugme echo "Status/MSG: $status_code $msg_thereafter" + debugme echo "Status/MSG: $HTTP_STATUS_CODE $msg_thereafter" pr_bold " HTTP Status Code " - [[ -z "$status_code" ]] && pr_cyan "No status code" && return 3 + [[ -z "$HTTP_STATUS_CODE" ]] && pr_cyan "No status code" && return 3 - out " $status_code$msg_thereafter" - case $status_code in + out " $HTTP_STATUS_CODE$msg_thereafter" + case $HTTP_STATUS_CODE in 301|302|307|308) redirect=$(grep -a '^Location' $HEADERFILE | sed 's/Location: //' | tr -d '\r\n') out ", redirecting to \"$redirect\"" if [[ $redirect == "http://"* ]]; then pr_svrty_high " -- Redirect to insecure URL (NOT ok)" - fileout "status_code" "NOT ok" \, "Redirect to insecure URL (NOT ok). Url: \"$redirect\"" + fileout "HTTP_STATUS_CODE" "NOT ok" \, "Redirect to insecure URL (NOT ok). Url: \"$redirect\"" fi - fileout "status_code" "INFO" \ - "Testing HTTP header response @ \"$URL_PATH\", $status_code$msg_thereafter, redirecting to \"$redirect\"" + fileout "HTTP_STATUS_CODE" "INFO" \ + "Testing HTTP header response @ \"$URL_PATH\", $HTTP_STATUS_CODE$msg_thereafter, redirecting to \"$redirect\"" ;; 200) - fileout "status_code" "INFO" \ - "Testing HTTP header response @ \"$URL_PATH\", $status_code$msg_thereafter" + fileout "HTTP_STATUS_CODE" "INFO" \ + "Testing HTTP header response @ \"$URL_PATH\", $HTTP_STATUS_CODE$msg_thereafter" ;; 204) - fileout "status_code" "INFO" \ - "Testing HTTP header response @ \"$URL_PATH\", $status_code$msg_thereafter" + fileout "HTTP_STATUS_CODE" "INFO" \ + "Testing HTTP header response @ \"$URL_PATH\", $HTTP_STATUS_CODE$msg_thereafter" ;; 206) out " -- WTF?" - fileout "status_code" "INFO" \ - "Testing HTTP header response @ \"$URL_PATH\", $status_code$msg_thereafter -- WTF?" + fileout "HTTP_STATUS_CODE" "INFO" \ + "Testing HTTP header response @ \"$URL_PATH\", $HTTP_STATUS_CODE$msg_thereafter -- WTF?" ;; 400) pr_cyan " (Hint: better try another URL)" - fileout "status_code" "INFO" \ - "Testing HTTP header response @ \"$URL_PATH\", $status_code$msg_thereafter (Hint: better try another URL)" + fileout "HTTP_STATUS_CODE" "INFO" \ + "Testing HTTP header response @ \"$URL_PATH\", $HTTP_STATUS_CODE$msg_thereafter (Hint: better try another URL)" ;; 401) grep -aq "^WWW-Authenticate" $HEADERFILE && out " "; strip_lf "$(grep -a "^WWW-Authenticate" $HEADERFILE)" - fileout "status_code" "INFO" \ - "Testing HTTP header response @ \"$URL_PATH\", $status_code$msg_thereafter $(grep -a "^WWW-Authenticate" $HEADERFILE)" + fileout "HTTP_STATUS_CODE" "INFO" \ + "Testing HTTP header response @ \"$URL_PATH\", $HTTP_STATUS_CODE$msg_thereafter $(grep -a "^WWW-Authenticate" $HEADERFILE)" ;; 403) - fileout "status_code" "INFO" \ - "Testing HTTP header response @ \"$URL_PATH\", $status_code$msg_thereafter" + fileout "HTTP_STATUS_CODE" "INFO" \ + "Testing HTTP header response @ \"$URL_PATH\", $HTTP_STATUS_CODE$msg_thereafter" ;; 404) - out " (Hint: supply a path which doesn't give a \"$status_code$msg_thereafter\")" - fileout "status_code" "INFO" \ - "Testing HTTP header response @ \"$URL_PATH\", $status_code$msg_thereafter (Hint: supply a path which doesn't give a \"$status_code$msg_thereafter\")" + out " (Hint: supply a path which doesn't give a \"$HTTP_STATUS_CODE$msg_thereafter\")" + fileout "HTTP_STATUS_CODE" "INFO" \ + "Testing HTTP header response @ \"$URL_PATH\", $HTTP_STATUS_CODE$msg_thereafter (Hint: supply a path which doesn't give a \"$HTTP_STATUS_CODE$msg_thereafter\")" ;; 405) - fileout "status_code" "INFO" \ - "Testing HTTP header response @ \"$URL_PATH\", $status_code$msg_thereafter" + fileout "HTTP_STATUS_CODE" "INFO" \ + "Testing HTTP header response @ \"$URL_PATH\", $HTTP_STATUS_CODE$msg_thereafter" ;; *) - pr_warning ". Oh, didn't expect \"$status_code$msg_thereafter\"" - fileout "status_code" "DEBUG" \ - "Testing HTTP header response @ \"$URL_PATH\", $status_code$msg_thereafter. Oh, didn't expect a $status_code$msg_thereafter" + pr_warning ". Oh, didn't expect \"$HTTP_STATUS_CODE$msg_thereafter\"" + fileout "HTTP_STATUS_CODE" "DEBUG" \ + "Testing HTTP header response @ \"$URL_PATH\", $HTTP_STATUS_CODE$msg_thereafter. Oh, didn't expect a $HTTP_STATUS_CODE$msg_thereafter" ;; esac outln @@ -1202,16 +1203,28 @@ run_cookie_flags() { # ARG1: Path, ARG2: path local -i nr_cookies local nr_httponly nr_secure local negative_word + local msg302="" msg302_="" if [[ ! -s $HEADERFILE ]]; then run_http_header "$1" || return 3 fi + + if ! grep -q 20 <<< "$HTTP_STATUS_CODE"; then + if egrep -q "301|302" <<< "$HTTP_STATUS_CODE"; then + msg302=" -- maybe better try target URL of 30x" + msg302_=" (30x detected, better try target URL of 30x)" + else + msg302=" -- HTTP status $HTTP_STATUS_CODE signals you maybe missed the web application" + msg302_=" (maybe missed the application)" + fi + fi + pr_bold " Cookie(s) " grep -ai '^Set-Cookie' $HEADERFILE >$TMPFILE if [[ $? -eq 0 ]]; then nr_cookies=$(count_lines "$TMPFILE") - out "$nr_cookies issued: " - fileout "cookie_count" "INFO" "$nr_cookies cookie(s) issued at \"$1\"" + out "$nr_cookies issued:" + fileout "cookie_count" "INFO" "$nr_cookies cookie(s) issued at \"$1\"$msg302_" if [[ $nr_cookies -gt 1 ]]; then negative_word="NONE" else @@ -1235,14 +1248,15 @@ run_cookie_flags() { # ARG1: Path, ARG2: path esac out " HttpOnly" if [[ $nr_cookies == $nr_httponly ]]; then - fileout "cookie_httponly" "OK" "All $nr_cookies cookie(s) issued at \"$1\" marked as HttpOnly" + fileout "cookie_httponly" "OK" "All $nr_cookies cookie(s) issued at \"$1\" marked as HttpOnly$msg302_" else - fileout "cookie_httponly" "WARN" "$nr_secure/$nr_cookies cookie(s) issued at \"$1\" marked as HttpOnly" + fileout "cookie_httponly" "WARN" "$nr_secure/$nr_cookies cookie(s) issued at \"$1\" marked as HttpOnly$msg302_" fi + out "$msg302" else - out "(none issued at \"$1\")" - fileout "cookie_count" "INFO" "No cookies issued at \"$1\"" - fi + out "(none issued at \"$1\")$msg302" + fileout "cookie_count" "INFO" "No cookies issued at \"$1\"$msg302_" + fi outln tmpfile_handle $FUNCNAME.txt @@ -1395,6 +1409,7 @@ listciphers() { # argv[1]: cipher list to test # argv[2]: string on console # argv[3]: ok to offer? 0: yes, 1: no +# argv[4]: string for fileout std_cipherlists() { local -i sclient_success local singlespaces proto="" addcmd="" @@ -1402,8 +1417,8 @@ std_cipherlists() { [[ "$OPTIMAL_PROTO" == "-ssl2" ]] && addcmd="$OPTIMAL_PROTO" && proto="$OPTIMAL_PROTO" [[ ! "$OPTIMAL_PROTO" =~ ssl ]] && addcmd="$SNI" - pr_bold "$2 " # indent in order to be in the same row as server preferences - if listciphers "$1" $proto; then # is that locally available?? + pr_bold "$2 " # indenting to be in the same row as server preferences + if listciphers "$1" $proto; then # is that locally available?? $OPENSSL s_client -cipher "$1" $BUGS $STARTTLS -connect $NODEIP:$PORT $PROXY $addcmd 2>$ERRFILE >$TMPFILE