work on api, client, and added protection against HTTP metadata leaks (timebleed)

master
Kevin Froman 2017-12-26 19:13:19 -06:00
parent 5256670da2
commit b6e9e2e002
No known key found for this signature in database
GPG Key ID: 0D414D0FE405B63B
3 changed files with 60 additions and 7 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
__pycache__/
data/config.ini
data/*.db

40
api.py
View File

@ -13,9 +13,41 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
''' '''
from flask import Flask from flask import Flask, request
app = Flask(__name__) app = Flask(__name__)
import configparser, sys, random
'''
Main API
'''
class API: class API:
def __init__(self):
return def __init__(self, config, debug):
self.config = config
bindPort = int(self.config['CLIENT']['PORT'])
clientToken = self.config['CLIENT']['CLIENT HMAC']
if not debug:
hostNums = [random.randint(1, 255), random.randint(1, 255), random.randint(1, 255)]
self.host = '127.' + str(hostNums[0]) + '.' + str(hostNums[1]) + '.' + str(hostNums[2])
else:
self.host = '127.0.0.1'
@app.route('/client/hello')
def hello_world():
self.validateHost()
return 'Hello, World!' + request.host
print('Starting client on ' + self.host + ':' + str(bindPort))
print('Client token:', clientToken)
app.run(host=self.host, port=bindPort, debug=True)
def validateHost(self):
# Validate host header, to protect against DNS rebinding attacks
if request.host != '127.0.0.1:' + str(self.config['CLIENT']['PORT']):
sys.exit(1)
# Validate x-requested-with, to protect against CSRF/metadata leaks
try:
request.headers['x-requested-with']
except:
sys.exit(1)

View File

@ -14,9 +14,26 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
''' '''
import sys, api, gui import sys, os, threading, configparser, base64, random
import gui, api
class Onionr: class Onionr:
def __init__(self): def __init__(self):
self.debug = True # Whole application debugging
os.chdir(sys.path[0])
self.config = configparser.ConfigParser()
if os.path.exists('data/config.ini'):
self.config.read('data/config.ini')
else:
# Hostname should only be set if different from 127.x.x.x. Important for DNS rebinding attack prevention.
if debug:
randomPort = 8080
else:
randomPort = random.randint(1024, 65535)
self.config['CLIENT'] = {'CLIENT HMAC': base64.b64encode(os.urandom(32)).decode('utf-8'), 'PORT': randomPort}
with open('data/config.ini', 'w') as configfile:
self.config.write(configfile)
command = '' command = ''
try: try:
command = sys.argv[1].lower() command = sys.argv[1].lower()
@ -32,9 +49,10 @@ class Onionr:
elif command == 'help' or command == '--help': elif command == 'help' or command == '--help':
self.showHelp() self.showHelp()
else: else:
help(Onionr) return
return return
def daemon(self): def daemon(self):
api.API(self.config, self.debug)
return return
def killDaemon(self): def killDaemon(self):
return return
@ -43,4 +61,4 @@ class Onionr:
def showHelp(self): def showHelp(self):
return return
main = Onionr() Onionr()