Skip to content

Instantly share code, notes, and snippets.

@homebysix homebysix/https_spotter.py
Last active May 19, 2019

Embed
What would you like to do?
HTTPS Spotter
#!/usr/bin/python
# This Python file uses the following encoding: utf-8
# HTTPS Spotter
# Copyright 2016-2019 Elliot Jordan
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
https_spotter.py
Scans for HTTP URLs in your recipe repos and suggests HTTPS alternatives
wherever possible. Meant to assist with spotting opportunities to improve the
security of AutoPkg recipes.
Suggested usage:
./https_spotter.py | grep "Found:" -B 1
"""
import httplib
import os
import plistlib
from ssl import CertificateError, SSLError
from urlparse import urlparse
from xml.parsers.expat import ExpatError
def check_url(url):
"""Checks HTTP URLs to detect whether an HTTPS equivalent exists."""
try:
parsed_url = urlparse(url)
c = httplib.HTTPSConnection(parsed_url.netloc, timeout=15)
c.request("HEAD", parsed_url.path)
r = c.getresponse()
if r.status < 400:
return url.replace("http:", "https:")
except Exception as err:
return None
def main():
"""Scans all recipes in the RecipeRepos folder for HTTP URLs."""
# Process all recipes looking for HTTP URLs.
for dirpath, dirnames, filenames in os.walk("."):
for dirname in dirnames:
if dirname.startswith("."):
dirnames.remove(dirname)
for filename in filenames:
if filename.endswith(".recipe"):
try:
recipe = plistlib.readPlist(os.path.join(dirpath, filename))
except (ValueError, ExpatError, TypeError) as error:
print("[ERROR] %s (%s)" % (os.path.join(dirpath, filename), error))
try:
for key in recipe["Input"]:
if isinstance(recipe["Input"][key], str) and recipe["Input"][
key
].startswith("http:"):
https_url = check_url(recipe["Input"][key])
if https_url:
print(
"\nRecipe: "
+ os.path.relpath(os.path.join(dirpath, filename))
)
print("New URL: " + https_url)
except KeyError as err:
print("[ERROR] %s (%s)" % (os.path.join(dirpath, filename), err))
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.