added loading whitelisted endpoints from plugins

This commit is contained in:
Kevin Froman 2019-08-14 18:44:29 -05:00
parent e267bbbead
commit 3c6cbca0ac
6 changed files with 36 additions and 19 deletions

View File

@ -1,9 +1,9 @@
''' """
Onionr - Private P2P Communication Onionr - Private P2P Communication
This file registers plugin's flask blueprints for the client http server This file registers plugin's flask blueprints for the client http server
''' """
''' """
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
@ -16,13 +16,14 @@
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 onionrplugins import onionrplugins
def load_plugin_blueprints(flaskapp, blueprint='flask_blueprint'):
'''Iterate enabled plugins and load any http endpoints they have''' def load_plugin_blueprints(flaskapp, blueprint: str = 'flask_blueprint'):
"""Iterate enabled plugins and load any http endpoints they have"""
for plugin in onionrplugins.get_enabled_plugins(): for plugin in onionrplugins.get_enabled_plugins():
plugin = onionrplugins.get_plugin(plugin) plugin = onionrplugins.get_plugin(plugin)
try: try:
flaskapp.register_blueprint(getattr(plugin, blueprint)) flaskapp.register_blueprint(getattr(plugin, blueprint))
except AttributeError: except AttributeError:
pass pass

View File

@ -20,19 +20,18 @@
import hmac import hmac
from flask import Blueprint, request, abort, g from flask import Blueprint, request, abort, g
from onionrservices import httpheaders from onionrservices import httpheaders
from . import pluginwhitelist
# Be extremely mindful of this. These are endpoints available without a password # Be extremely mindful of this. These are endpoints available without a password
whitelist_endpoints = ('siteapi.site', 'www', 'staticfiles.onionrhome', 'staticfiles.homedata', whitelist_endpoints = ['www', 'staticfiles.homedata', 'staticfiles.sharedContent',
'staticfiles.board', 'staticfiles.profiles', 'staticfiles.friends', 'staticfiles.friendsindex', 'siteapi.site', 'staticfiles.onionrhome']
'staticfiles.profilesindex',
'staticfiles.boardContent', 'staticfiles.sharedContent',
'staticfiles.mail', 'staticfiles.mailindex', 'staticfiles.friends', 'staticfiles.friendsindex',
'staticfiles.chat', 'staticfiles.chatIndex')
class ClientAPISecurity: class ClientAPISecurity:
def __init__(self, client_api): def __init__(self, client_api):
client_api_security_bp = Blueprint('clientapisecurity', __name__) client_api_security_bp = Blueprint('clientapisecurity', __name__)
self.client_api_security_bp = client_api_security_bp self.client_api_security_bp = client_api_security_bp
self.client_api = client_api self.client_api = client_api
pluginwhitelist.load_plugin_security_whitelist_endpoints(whitelist_endpoints)
@client_api_security_bp.before_app_request @client_api_security_bp.before_app_request
def validate_request(): def validate_request():
@ -40,6 +39,13 @@ class ClientAPISecurity:
# For the purpose of preventing DNS rebinding attacks # For the purpose of preventing DNS rebinding attacks
if request.host != '%s:%s' % (client_api.host, client_api.bindPort): if request.host != '%s:%s' % (client_api.host, client_api.bindPort):
abort(403) abort(403)
# Add shared objects
try:
g.too_many = self.client_api._too_many
except KeyError:
g.too_many = None
if request.endpoint in whitelist_endpoints: if request.endpoint in whitelist_endpoints:
return return
try: try:
@ -49,12 +55,6 @@ class ClientAPISecurity:
except KeyError: except KeyError:
if not hmac.compare_digest(request.form['token'], client_api.clientToken): if not hmac.compare_digest(request.form['token'], client_api.clientToken):
abort(403) abort(403)
# Add shared objects
try:
g.too_many = self.client_api._too_many
except KeyError:
g.too_many = None
@client_api_security_bp.after_app_request @client_api_security_bp.after_app_request
def after_req(resp): def after_req(resp):

View File

@ -0,0 +1,13 @@
import onionrplugins
def load_plugin_security_whitelist_endpoints(whitelist: list):
"""Accept a list reference of whitelist endpoints from security/client.py and
append plugin's specified endpoints to them by attribute"""
for plugin in onionrplugins.get_enabled_plugins():
try:
plugin = onionrplugins.get_plugin(plugin)
except FileNotFoundError:
continue
try:
whitelist.extend(getattr(plugin, "security_whitelist"))
except AttributeError:
pass

View File

@ -31,6 +31,7 @@ sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
import controlapi, peerserver import controlapi, peerserver
flask_blueprint = controlapi.flask_blueprint flask_blueprint = controlapi.flask_blueprint
direct_blueprint = peerserver.direct_blueprint direct_blueprint = peerserver.direct_blueprint
security_whitelist = ['staticfiles.chat', 'staticfiles.chatIndex']
def exit_with_error(text=''): def exit_with_error(text=''):
if text != '': if text != '':

View File

@ -30,6 +30,7 @@ import deadsimplekv as simplekv
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__))) sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
import flowapi # import after path insert import flowapi # import after path insert
flask_blueprint = flowapi.flask_blueprint flask_blueprint = flowapi.flask_blueprint
security_whitelist = ['staticfiles.boardContent', 'staticfiles.board']
plugin_name = 'flow' plugin_name = 'flow'
PLUGIN_VERSION = '0.0.1' PLUGIN_VERSION = '0.0.1'

View File

@ -36,6 +36,7 @@ PLUGIN_VERSION = '0.0.1'
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__))) sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
import sentboxdb, mailapi, loadinbox # import after path insert import sentboxdb, mailapi, loadinbox # import after path insert
flask_blueprint = mailapi.flask_blueprint flask_blueprint = mailapi.flask_blueprint
security_whitelist = ['staticfiles.mail', 'staticfiles.mailindex']
def add_deleted(keyStore, bHash): def add_deleted(keyStore, bHash):
existing = keyStore.get('deleted_mail') existing = keyStore.get('deleted_mail')