Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion browserstack/local_binary.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,33 @@

try:
from urllib.request import urlopen, Request
from urllib.parse import urlparse
except ImportError:
from urllib2 import urlopen, Request
from urlparse import urlparse

class LocalBinary:
_version = None
ALLOWED_DOWNLOAD_HOSTS = ("browserstack.com",)
ALLOWED_DOWNLOAD_HOST_SUFFIXES = (".browserstack.com",)

@staticmethod
def _validate_source_url(url):
parsed = urlparse(url or "")
if parsed.scheme != "https":
raise BrowserStackLocalError(
"Refusing binary download from non-HTTPS source URL")
host = (parsed.hostname or "").lower()
if not host:
raise BrowserStackLocalError(
"Refusing binary download: source URL has no host")
if host in LocalBinary.ALLOWED_DOWNLOAD_HOSTS:
return url
for suffix in LocalBinary.ALLOWED_DOWNLOAD_HOST_SUFFIXES:
if host.endswith(suffix):
return url
raise BrowserStackLocalError(
"Refusing binary download: host '{}' is not in the allowed host list".format(host))

def __init__(self, key, error_object=None):
self.key = key
Expand Down Expand Up @@ -64,7 +86,9 @@ def fetch_source_url(self):
resp_bytes = response.read()
resp_str = resp_bytes.decode('utf-8')
resp_json = json.loads(resp_str)
return resp_json["data"]["endpoint"]
return self._validate_source_url(resp_json["data"]["endpoint"])
except BrowserStackLocalError:
raise
except Exception as e:
raise BrowserStackLocalError('Error trying to fetch the source url for downloading the binary: {}'.format(e))

Expand Down
Loading