From 42dd0c8e5fc84e17e1d3578d18aaea169eece474 Mon Sep 17 00:00:00 2001 From: Kris Date: Tue, 17 Jan 2023 13:28:17 -0800 Subject: [PATCH 1/2] Fix regex bug, and several python 3 fixes --- safeurl/safeurl.py | 20 +++++------------- safeurl/safeurl_examples.py | 41 ------------------------------------- safeurl/safeurl_tests.py | 26 ++++++++++++++++++----- 3 files changed, 26 insertions(+), 61 deletions(-) delete mode 100755 safeurl/safeurl_examples.py diff --git a/safeurl/safeurl.py b/safeurl/safeurl.py index 933b28d..a43c918 100755 --- a/safeurl/safeurl.py +++ b/safeurl/safeurl.py @@ -12,21 +12,12 @@ from numbers import Number from socket import gethostbyname_ex -import re import netaddr import pycurl import socket -import StringIO - -# Python 2.7/3 urlparse -try: - # Python 2.7 - from urlparse import urlparse - from urllib import quote -except: - # Python 3 - from urllib.parse import urlparse - from urllib.parse import quote +import io +from urllib.parse import urlparse +from urllib.parse import quote class ObsoletePyCurlException(Exception): pass class InvalidOptionException(Exception): pass @@ -204,10 +195,9 @@ def isInList(self, lst, type_, value): else: return False - # For domains, a regex match is needed if type_ == "domain": for domain in dst: - if re.match("(?i)^%s" % domain, value) is not None: + if domain.lower() == value.lower(): return True return False else: @@ -661,7 +651,7 @@ def execute(self, url): self._handle.setopt(pycurl.URL, url["cleanUrl"]) # Execute the cURL request - response = StringIO.StringIO() + response = io.BytesIO() self._handle.setopt(pycurl.OPENSOCKETFUNCTION, self._openSocketCallback) self._handle.setopt(pycurl.WRITEFUNCTION, response.write) self._handle.perform() diff --git a/safeurl/safeurl_examples.py b/safeurl/safeurl_examples.py deleted file mode 100755 index e2f0261..0000000 --- a/safeurl/safeurl_examples.py +++ /dev/null @@ -1,41 +0,0 @@ -import safeurl -import sys - -# Default -try: - sc = safeurl.SafeURL() - res = sc.execute("https://fin1te.net") -except: - print "Unexpected error:", sys.exc_info() - -# options -try: - sc = safeurl.SafeURL() - - opt = safeurl.Options() - opt.clearList("whitelist") - opt.clearList("blacklist") - opt.setList("whitelist", ["google.com", "youtube.com"], "domain") - - sc.setOptions(opt) - res = sc.execute("http://www.youtube.com") -except: - print "Unexpected error:", sys.exc_info() - -# url -try: - url = safeurl.Url.validateUrl("http://google.com", safeurl.Options()) -except: - print "Unexpected error:", sys.exc_info() - -# redirects -try: - sc = safeurl.SafeURL() - - opt = safeurl.Options() - opt.enableFollowLocation().setFollowLocationLimit(10) - sc.setOptions(opt) - - res = sc.execute("http://fin1te.net") -except: - print "Unexpected error:", sys.exc_info() diff --git a/safeurl/safeurl_tests.py b/safeurl/safeurl_tests.py index f0d2333..34dddb0 100755 --- a/safeurl/safeurl_tests.py +++ b/safeurl/safeurl_tests.py @@ -6,7 +6,7 @@ sc = safeurl.SafeURL() res = sc.execute("https://fin1te.net") except: - print "Unexpected error:", sys.exc_info() + print("Unexpected error:", sys.exc_info()) # options try: @@ -20,13 +20,13 @@ sc.setOptions(opt) res = sc.execute("http://www.youtube.com") except: - print "Unexpected error:", sys.exc_info() + print("Unexpected error:", sys.exc_info()) # url try: url = safeurl.Url.validateUrl("http://google.com", safeurl.Options()) except: - print "Unexpected error:", sys.exc_info() + print("Unexpected error:", sys.exc_info()) # redirects try: @@ -38,7 +38,7 @@ res = sc.execute("http://fin1te.net") except: - print "Unexpected error:", sys.exc_info() + print("Unexpected error:", sys.exc_info()) # forbidden host @@ -51,4 +51,20 @@ res = sc.execute("http://localhost") except: - print "Error:", sys.exc_info() + print("Error:", sys.exc_info()) + + +# regex bug +try: + sc = safeurl.SafeURL() + + opt = safeurl.Options() + opt.setList("whitelist", ["exam.le"], "domain") + sc.setOptions(opt) + + res = sc.execute("https://example.com/") + +except: + print("Error:", sys.exc_info()) + + From 7b8596171b7bae9a9a15ebaf6cd22202140cd18f Mon Sep 17 00:00:00 2001 From: Kris Date: Tue, 17 Jan 2023 13:33:10 -0800 Subject: [PATCH 2/2] Switch from setup.py to pyproject.toml --- pyproject.toml | 12 ++++++++++++ setup.py | 15 --------------- 2 files changed, 12 insertions(+), 15 deletions(-) create mode 100644 pyproject.toml delete mode 100755 setup.py diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..57a1b17 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,12 @@ +[project] +name = "SafeURL" +version="1.2" +description="SafeURL is a library that aids developers in protecting against a class of vulnerabilities known as Server Side Request Forgery." +readme="README.md" +dependencies = [ + "pycurl", + "netaddr" +] + +[project.urls] +"Homepage" = "https://github.com/IncludeSecurity/safeurl-python" diff --git a/setup.py b/setup.py deleted file mode 100755 index ca69687..0000000 --- a/setup.py +++ /dev/null @@ -1,15 +0,0 @@ -from distutils.core import setup - -with open("README.md") as readme_fh: - long_description = readme_fh.read() - -setup( - name="SafeURL", - url="https://github.com/IncludeSecurity/safeurl-python", - version="1.1", - license="MIT License", - requires=[ - "pycurl>=7.19.3", - ], - long_description=long_description, -)