electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit 426cd6dd60c512a7b2a066c9660c192d6a8e527a
parent e874ea2b7c22bc58d76a2a078200149cd5085808
Author: ThomasV <thomasv@electrum.org>
Date:   Thu, 22 Dec 2016 06:06:16 +0100

Merge pull request #2086 from alexander255/master

Properly handle invalid payment request URLs
Diffstat:
Mlib/paymentrequest.py | 39+++++++++++++++++++++++++++++----------
1 file changed, 29 insertions(+), 10 deletions(-)

diff --git a/lib/paymentrequest.py b/lib/paymentrequest.py @@ -67,31 +67,48 @@ PR_PAID = 3 # send and propagated def get_payment_request(url): u = urlparse.urlparse(url) if u.scheme in ['http', 'https']: - response = requests.request('GET', url, headers=REQUEST_HEADERS) - data = response.content - print_error('fetched payment request', url, len(data)) + try: + response = requests.request('GET', url, headers=REQUEST_HEADERS) + response.raise_for_status() + # Guard against `bitcoin:`-URIs with invalid payment request URLs + if "Content-Type" not in response.headers \ + or response.headers["Content-Type"] != "application/bitcoin-paymentrequest": + data = None + error = "payment URL not pointing to a payment request handling server" + else: + data = response.content + print_error('fetched payment request', url, len(response.content)) + except requests.exceptions.RequestException: + data = None + error = "payment URL not pointing to a valid server" elif u.scheme == 'file': - with open(u.path, 'r') as f: - data = f.read() + try: + with open(u.path, 'r') as f: + data = f.read() + except IOError: + data = None + error = "payment URL not pointing to a valid file" else: raise BaseException("unknown scheme", url) - pr = PaymentRequest(data) + pr = PaymentRequest(data, error) return pr class PaymentRequest: - def __init__(self, data): + def __init__(self, data, error=None): self.raw = data + self.error = error self.parse(data) self.requestor = None # known after verify self.tx = None - self.error = None def __str__(self): return self.raw def parse(self, r): + if self.error: + return self.id = bitcoin.sha256(r)[0:16].encode('hex') try: self.data = pb2.PaymentRequest() @@ -113,15 +130,17 @@ class PaymentRequest: #return self.get_outputs() != [(TYPE_ADDRESS, self.get_requestor(), self.get_amount())] def verify(self, contacts): + if self.error: + return False if not self.raw: self.error = "Empty request" - return + return False pr = pb2.PaymentRequest() try: pr.ParseFromString(self.raw) except: self.error = "Error: Cannot parse payment request" - return + return False if not pr.signature: # the address will be dispayed as requestor self.requestor = None