From e6140b9b4ea31127e5e8ae0e64f6d96e0459cf7d Mon Sep 17 00:00:00 2001 From: Kristofer Tingdahl <10433010+tingdahl@users.noreply.github.com> Date: Sun, 30 Oct 2022 01:01:23 +0200 Subject: [PATCH 1/4] Added optoins for min-grade and min-score to integrate in CI/CD systems. --- httpobs/scripts/httpobs-local-scan | 38 ++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/httpobs/scripts/httpobs-local-scan b/httpobs/scripts/httpobs-local-scan index a7163ea3..a444e387 100755 --- a/httpobs/scripts/httpobs-local-scan +++ b/httpobs/scripts/httpobs-local-scan @@ -8,6 +8,9 @@ import json from operator import itemgetter from urllib.parse import urlparse +MIN_GRADE_DEFAULT = 'F' +MIN_SCORE_DEFAULT = 0 +GRADES = ['F', 'D-', 'D', 'D+', 'C-', 'C', 'C+', 'B-', 'B', 'B+', 'A-', 'A', 'A+'] if __name__ == "__main__": parser = argparse.ArgumentParser() @@ -36,6 +39,15 @@ if __name__ == "__main__": default=argparse.SUPPRESS, help='headers to send in scan (json formatted)', type=json.loads) + parser.add_argument('--min-grade', + default=MIN_GRADE_DEFAULT, + help='testing: this grade or better, or exit(1)', + choices=GRADES, + type=str) + parser.add_argument('--min-score', + default=MIN_SCORE_DEFAULT, + help='testing: this score or better (>=0), or exit(1)', + type=int) parser.add_argument('--format', default='json', help='output format (json or report), default of json', @@ -46,12 +58,16 @@ if __name__ == "__main__": args = vars(parser.parse_args()) - # Remove the -- from the name, change - to underscore + # Remove the -- from the name, change - o underscore args = {k.split('--')[-1].replace('-', '_'): v for k, v in args.items()} output_format = args.pop('format').lower() + # Get minimum grade and score + min_grade = args.pop('min_grade') + min_score = args.pop('min_score') + # print out help if no arguments are specified, or bad arguments - if len(args) == 0 or output_format not in ('json', 'report'): + if len(args) == 0 or output_format not in ('json', 'report') or min_score<0: parser.print_help() parser.exit(-1) @@ -96,3 +112,21 @@ if __name__ == "__main__": print(' {test:<30} [{modifier:>3}] {reason}'.format(test=score[0], modifier=score[1], reason=score[2])) + + # Check for minimum score + score = r['scan']['score'] + if score Date: Sun, 30 Oct 2022 01:28:29 +0200 Subject: [PATCH 2/4] Added grading --- httpobs/scripts/httpobs-local-scan | 38 ++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/httpobs/scripts/httpobs-local-scan b/httpobs/scripts/httpobs-local-scan index a7163ea3..a444e387 100755 --- a/httpobs/scripts/httpobs-local-scan +++ b/httpobs/scripts/httpobs-local-scan @@ -8,6 +8,9 @@ import json from operator import itemgetter from urllib.parse import urlparse +MIN_GRADE_DEFAULT = 'F' +MIN_SCORE_DEFAULT = 0 +GRADES = ['F', 'D-', 'D', 'D+', 'C-', 'C', 'C+', 'B-', 'B', 'B+', 'A-', 'A', 'A+'] if __name__ == "__main__": parser = argparse.ArgumentParser() @@ -36,6 +39,15 @@ if __name__ == "__main__": default=argparse.SUPPRESS, help='headers to send in scan (json formatted)', type=json.loads) + parser.add_argument('--min-grade', + default=MIN_GRADE_DEFAULT, + help='testing: this grade or better, or exit(1)', + choices=GRADES, + type=str) + parser.add_argument('--min-score', + default=MIN_SCORE_DEFAULT, + help='testing: this score or better (>=0), or exit(1)', + type=int) parser.add_argument('--format', default='json', help='output format (json or report), default of json', @@ -46,12 +58,16 @@ if __name__ == "__main__": args = vars(parser.parse_args()) - # Remove the -- from the name, change - to underscore + # Remove the -- from the name, change - o underscore args = {k.split('--')[-1].replace('-', '_'): v for k, v in args.items()} output_format = args.pop('format').lower() + # Get minimum grade and score + min_grade = args.pop('min_grade') + min_score = args.pop('min_score') + # print out help if no arguments are specified, or bad arguments - if len(args) == 0 or output_format not in ('json', 'report'): + if len(args) == 0 or output_format not in ('json', 'report') or min_score<0: parser.print_help() parser.exit(-1) @@ -96,3 +112,21 @@ if __name__ == "__main__": print(' {test:<30} [{modifier:>3}] {reason}'.format(test=score[0], modifier=score[1], reason=score[2])) + + # Check for minimum score + score = r['scan']['score'] + if score Date: Sun, 30 Oct 2022 01:36:00 +0200 Subject: [PATCH 3/4] Fixed typo. --- httpobs/scripts/httpobs-local-scan | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpobs/scripts/httpobs-local-scan b/httpobs/scripts/httpobs-local-scan index a444e387..e805f7e5 100755 --- a/httpobs/scripts/httpobs-local-scan +++ b/httpobs/scripts/httpobs-local-scan @@ -58,7 +58,7 @@ if __name__ == "__main__": args = vars(parser.parse_args()) - # Remove the -- from the name, change - o underscore + # Remove the -- from the name, change - to underscore args = {k.split('--')[-1].replace('-', '_'): v for k, v in args.items()} output_format = args.pop('format').lower() From 5a1f604834fe8b93bb9a4be650edc6320f76215e Mon Sep 17 00:00:00 2001 From: Kristofer Tingdahl <10433010+tingdahl@users.noreply.github.com> Date: Sat, 5 Nov 2022 06:03:51 +0100 Subject: [PATCH 4/4] Removed printing of thresholding messages if thresholding was disabled. --- httpobs/scripts/httpobs-local-scan | 101 ++++++++++++++++++++++------- 1 file changed, 78 insertions(+), 23 deletions(-) diff --git a/httpobs/scripts/httpobs-local-scan b/httpobs/scripts/httpobs-local-scan index a444e387..ba5e7d81 100755 --- a/httpobs/scripts/httpobs-local-scan +++ b/httpobs/scripts/httpobs-local-scan @@ -8,10 +8,16 @@ import json from operator import itemgetter from urllib.parse import urlparse -MIN_GRADE_DEFAULT = 'F' -MIN_SCORE_DEFAULT = 0 +NO_MIN_GRADE = '' +NO_MIN_SCORE = 0 GRADES = ['F', 'D-', 'D', 'D+', 'C-', 'C', 'C+', 'B-', 'B', 'B+', 'A-', 'A', 'A+'] +#All keys used more than once +FORMAT_JSON_KEY = 'json' +FORMAT_REPORT_KEY = 'report' +RESULT_SCAN_KEY = 'scan' +RESULT_ERROR_KEY = 'error' + if __name__ == "__main__": parser = argparse.ArgumentParser() @@ -40,16 +46,16 @@ if __name__ == "__main__": help='headers to send in scan (json formatted)', type=json.loads) parser.add_argument('--min-grade', - default=MIN_GRADE_DEFAULT, + default=NO_MIN_GRADE, help='testing: this grade or better, or exit(1)', choices=GRADES, type=str) parser.add_argument('--min-score', - default=MIN_SCORE_DEFAULT, + default=NO_MIN_SCORE, help='testing: this score or better (>=0), or exit(1)', type=int) parser.add_argument('--format', - default='json', + default=FORMAT_JSON_KEY, help='output format (json or report), default of json', type=str) parser.add_argument('hostname', @@ -58,7 +64,7 @@ if __name__ == "__main__": args = vars(parser.parse_args()) - # Remove the -- from the name, change - o underscore + # Remove the -- from the name, change - to underscore args = {k.split('--')[-1].replace('-', '_'): v for k, v in args.items()} output_format = args.pop('format').lower() @@ -67,7 +73,7 @@ if __name__ == "__main__": min_score = args.pop('min_score') # print out help if no arguments are specified, or bad arguments - if len(args) == 0 or output_format not in ('json', 'report') or min_score<0: + if len(args) == 0 or output_format not in ('json', 'report') or min_scoreNO_MIN_SCORE: + thresholding_results['min-score'] = min_score + + score = r[RESULT_SCAN_KEY]['score'] + score_thresholding_passed = score>=min_score + + if score_thresholding_passed: + score_thresholding_text = f'Score thresholding passed as score ({score}) is higher or equal to min-score ({min_score})' + else: + score_thresholding_text = f'Score thresholding failed as score ({score}) is lower than the minimum score ({min_score})' + thresholding_passed = False + + thresholding_results['score-test-text'] = score_thresholding_text + thresholding_results['score-test-passed'] = score_thresholding_passed + + # Compare grade to threshold + if min_grade!=NO_MIN_GRADE: + thresholding_results['min-grade'] = min_grade + grade = r[RESULT_SCAN_KEY]['grade'] + grade_index = GRADES.index(grade) + min_grade_index = GRADES.index(min_grade) + grade_thresholding_passed = grade_index>=min_grade_index + + if grade_thresholding_passed: + grade_thresholding_text = \ + f'Grade thresholding passed as grade ({grade}) is higher or equal to min-grade ({min_grade})' + else: + grade_thresholding_text = \ + f'Grade thresholding failed as grade ({grade}) is lower than the minimum grade ({min_grade})' + thresholding_passed = False + + thresholding_results['grade-test-text'] = grade_thresholding_text + thresholding_results['grade-test-passed'] = grade_thresholding_passed + + #Integrate the results + if len(thresholding_results): + thresholding_results['passed'] = thresholding_passed + r['thresholding-results'] = thresholding_results + # print out the results to the command line if output_format == 'json': print(json.dumps(r, indent=4, sort_keys=True)) elif output_format == 'report': - print('Score: {0} [{1}]'.format(r['scan']['score'], - r['scan']['grade'])) + print('Score: {0} [{1}]'.format(score, grade)) + + if len(score_thresholding_text): + print(f'Score threshold: {score_thresholding_text}') + + if len(grade_thresholding_text): + print(f'Grade threshold: {grade_thresholding_text}') print('Modifiers:') @@ -113,20 +181,7 @@ if __name__ == "__main__": modifier=score[1], reason=score[2])) - # Check for minimum score - score = r['scan']['score'] - if score