fixed broken dns rebinding mitigation and secured peer adding

master
Kevin Froman 2018-01-26 18:10:38 -06:00
parent c35242be1a
commit 64b14720c1
No known key found for this signature in database
GPG Key ID: 0D414D0FE405B63B
3 changed files with 29 additions and 10 deletions

View File

@ -176,7 +176,7 @@ class API:
# Validate host header, to protect against DNS rebinding attacks # Validate host header, to protect against DNS rebinding attacks
host = self.host host = self.host
if hostType == 'private': if hostType == 'private':
if not request.host.startswith('127'): if not request.host.startswith('127') and not self._utils.checkIsIP(request.host):
abort(403) abort(403)
elif hostType == 'public': elif hostType == 'public':
if not request.host.endswith('onion') and not request.host.endswith('i2p'): if not request.host.endswith('onion') and not request.host.endswith('i2p'):

View File

@ -69,6 +69,13 @@ class OnionrUtils:
finally: finally:
sock.close() sock.close()
return retVal return retVal
def checkIsIP(self, ip):
try:
socket.inet_aton(ip)
except:
return False
else:
return True
def exportMyPubkey(self): def exportMyPubkey(self):
'''Export our PGP key if it exists''' '''Export our PGP key if it exists'''
if not os.path.exists(self.fingerprintFile): if not os.path.exists(self.fingerprintFile):
@ -107,26 +114,38 @@ class OnionrUtils:
idLength = len(id) idLength = len(id)
retVal = True retVal = True
idNoDomain = '' idNoDomain = ''
#if idLength != 60 and idLength != 22 and idLength != 62: peerType = ''
# i2p b32 addresses are 60 characters long (including .b32.i2p)
if idLength == 60: if idLength == 60:
if not id.endsWith('.b32.i2p'): peerType = 'i2p'
if not id.endswith('.b32.i2p'):
retVal = False retVal = False
else: else:
idNoDomain = id.split('.b32.i2p')[0] idNoDomain = id.split('.b32.i2p')[0]
# Onion v2's are 22 (including .onion), v3's are 62 with .onion
elif idLength == 22 or idLength == 62: elif idLength == 22 or idLength == 62:
if not id.endsWith('.onion'): peerType = 'onion'
if not id.endswith('.onion'):
retVal = False retVal = False
else: else:
idNoDomain = id.split('.onion')[0] idNoDomain = id.split('.onion')[0]
else: else:
retVal = False retVal = False
if retVal: if retVal:
if id.endsWith('.onion'): if peerType == 'i2p':
try: try:
int(idNoDomain, 16) id.split('.b32.i2p')[2]
except ValueError: except:
pass
else:
retVal = False
elif peerType == 'onion':
try:
id.split('.onion')[2]
except:
pass
else:
retVal = False retVal = False
elif id.endsWith('.b32.i2p'):
if not idNoDomain.isalnum(): if not idNoDomain.isalnum():
retVal = False retVal = False
return retVal return retVal

View File

@ -51,7 +51,7 @@ class OnionrTests(unittest.TestCase):
myCore = core.Core() myCore = core.Core()
if not os.path.exists('data/peers.db'): if not os.path.exists('data/peers.db'):
myCore.createPeerDB() myCore.createPeerDB()
if myCore.addPeer('test'): if myCore.addPeer('facebookcorewwwi.onion') and not myCore.addPeer('invalidpeer.onion'):
self.assertTrue(True) self.assertTrue(True)
else: else:
self.assertTrue(False) self.assertTrue(False)