Skip to content

Commit

Permalink
output format option
Browse files Browse the repository at this point in the history
  • Loading branch information
juerkkil committed Oct 25, 2024
1 parent a7debbf commit 88e3db5
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 7 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ $ pip install secheaders
## Usage
```
$ secheaders --help
usage: secheaders [-h] [--max-redirects N] [--insecure] [--verbose] URL
sage: secheaders [-h] [--max-redirects N] [--insecure] [--format FORMAT] [--verbose] URL
Check HTTP security headers
Scan HTTP security headers
positional arguments:
URL Target URL
Expand All @@ -46,6 +46,7 @@ options:
-h, --help show this help message and exit
--max-redirects N Max redirects, set 0 to disable (default: 2)
--insecure Do not verify TLS certificate chain (default: False)
--format FORMAT Output format, options: text, json (default: text)
--verbose, -v Verbose output (default: False)
```

Expand Down
19 changes: 14 additions & 5 deletions secheaders/securityheaders.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import argparse
import http.client
import json
import re
import socket
import ssl
Expand Down Expand Up @@ -82,7 +83,8 @@ def _follow_redirect_until_response(self, url, follow_redirects=5):
if temp_url.scheme == 'http':
conn = http.client.HTTPConnection(temp_url.netloc, timeout=DEFAULT_TIMEOUT)
elif temp_url.scheme == 'https':
ctx = ssl.create_default_context() if self.verify_ssl else ssl._create_stdlib_context() # pylint: disable=protected-access
# pylint: disable-next=protected-access
ctx = ssl.create_default_context() if self.verify_ssl else ssl._create_stdlib_context()
conn = http.client.HTTPSConnection(temp_url.netloc, context=ctx, timeout=DEFAULT_TIMEOUT)
else:
raise InvalidTargetURL("Unsupported protocol scheme")
Expand Down Expand Up @@ -187,6 +189,7 @@ def check_headers(self):

return retval


def output_cli(headers, https, verbose=False):
for header, value in headers.items():
output_str = ""
Expand Down Expand Up @@ -220,13 +223,15 @@ def output_cli(headers, https, verbose=False):


def main():
parser = argparse.ArgumentParser(description='Check HTTP security headers',
parser = argparse.ArgumentParser(description='Scan HTTP security headers',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('url', metavar='URL', type=str, help='Target URL')
parser.add_argument('--max-redirects', dest='max_redirects', metavar='N', default=2, type=int,
help='Max redirects, set 0 to disable')
parser.add_argument('--insecure', dest='insecure', action='store_true',
help='Do not verify TLS certificate chain')

parser.add_argument('--format', type=str, required=False, default='text', help='Output format, options: text, json')
parser.add_argument('--verbose', '-v', dest='verbose', action='store_true',
help='Verbose output')
args = parser.parse_args()
Expand All @@ -235,15 +240,19 @@ def main():
header_check.fetch_headers()
headers = header_check.check_headers()
except SecurityHeadersException as e:
print(e)
print(e, file=sys.stderr)
sys.exit(1)

if not headers:
print("Failed to fetch headers, exiting...")
print("Failed to fetch headers, exiting...", file=sys.stderr)
sys.exit(1)

https = header_check.test_https()
output_cli(headers, https, args.verbose)
if args.format == 'text':
output_cli(headers, https, args.verbose)
else:
print(json.dumps({'headers': headers, 'https': https}, indent=2))


if __name__ == "__main__":
main()

0 comments on commit 88e3db5

Please sign in to comment.