Merge pull request #25 from avatao-content/usersep

Fix webide vulnerabilities
This commit is contained in:
Bokros Bálint 2018-04-05 17:22:04 +02:00 committed by GitHub
commit b942c1cf53
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 15 deletions

View File

@ -53,14 +53,17 @@ COPY nginx/nginx.conf ${TFW_NGINX_CONF}
COPY nginx/default.conf ${TFW_NGINX_DEFAULT} COPY nginx/default.conf ${TFW_NGINX_DEFAULT}
COPY lib ${TFW_LIB_DIR} COPY lib ${TFW_LIB_DIR}
RUN for dir in "${TFW_LIB_DIR}" "/etc/nginx" "/etc/supervisor"; do \
chown -R root:root "$dir" && chmod -R 700 "$dir"; \
done
ONBUILD ARG BUILD_CONTEXT="." ONBUILD ARG BUILD_CONTEXT="."
ONBUILD ARG NOFRONTEND="" ONBUILD ARG NOFRONTEND=""
ONBUILD COPY ${BUILD_CONTEXT}/nginx/components/ ${TFW_NGINX_COMPONENTS} ONBUILD COPY ${BUILD_CONTEXT}/nginx/components/ ${TFW_NGINX_COMPONENTS}
ONBUILD COPY ${BUILD_CONTEXT}/supervisor/components/ ${TFW_SUPERVISORD_COMPONENTS} ONBUILD COPY ${BUILD_CONTEXT}/supervisor/components/ ${TFW_SUPERVISORD_COMPONENTS}
ONBUILD RUN chown -R ${AVATAO_USER} /var/log/nginx /var/lib/nginx &&\ ONBUILD RUN for f in "${TFW_NGINX_DEFAULT}" ${TFW_NGINX_COMPONENTS}/*.conf; do \
for f in "${TFW_NGINX_DEFAULT}" ${TFW_NGINX_COMPONENTS}/*.conf; do \
envsubst "$(printenv | cut -d= -f1 | grep TFW_ | sed -e 's/^/$/g')" < $f > $f~ && mv $f~ $f ;\ envsubst "$(printenv | cut -d= -f1 | grep TFW_ | sed -e 's/^/$/g')" < $f > $f~ && mv $f~ $f ;\
done done
ONBUILD VOLUME ["/etc/nginx", "/var/lib/nginx", "/var/log/nginx"] ONBUILD VOLUME ["/etc/nginx", "/var/lib/nginx", "/var/log/nginx"]

View File

@ -1,7 +1,7 @@
# Copyright (C) 2018 Avatao.com Innovative Learning Kft. # Copyright (C) 2018 Avatao.com Innovative Learning Kft.
# All Rights Reserved. See LICENSE file for details. # All Rights Reserved. See LICENSE file for details.
from os.path import isfile, join, relpath, exists, isdir from os.path import isfile, join, relpath, exists, isdir, realpath
from glob import glob from glob import glob
from fnmatch import fnmatchcase from fnmatch import fnmatchcase
from collections import Iterable from collections import Iterable
@ -13,9 +13,10 @@ from tfw.config.logs import logging
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
class FileManager: class FileManager: # pylint: disable=too-many-instance-attributes
def __init__(self, working_directory, selected_file=None, exclude=None): def __init__(self, working_directory, allowed_directories, selected_file=None, exclude=None):
self._exclude, self.exclude = None, exclude self._exclude, self.exclude = None, exclude
self._allowed_directories, self.allowed_directories = None, allowed_directories
self._workdir, self.workdir = None, working_directory self._workdir, self.workdir = None, working_directory
self._filename, self.filename = None, selected_file or self.files[0] self._filename, self.filename = None, selected_file or self.files[0]
@ -39,8 +40,18 @@ class FileManager:
def workdir(self, directory): def workdir(self, directory):
if not exists(directory) or not isdir(directory): if not exists(directory) or not isdir(directory):
raise EnvironmentError('"{}" is not a directory!'.format(directory)) raise EnvironmentError('"{}" is not a directory!'.format(directory))
if not self._is_whitelisted(directory):
raise EnvironmentError('Directory "{}" is not in whitelist!'.format(directory))
self._workdir = directory self._workdir = directory
@property
def allowed_directories(self):
return self._allowed_directories
@allowed_directories.setter
def allowed_directories(self, directories):
self._allowed_directories = directories
@property @property
def filename(self): def filename(self):
return self._filename return self._filename
@ -54,8 +65,9 @@ class FileManager:
@property @property
def files(self): def files(self):
return [self._relpath(file) for file in glob(join(self._workdir, '**/*'), recursive=True) return [self._relpath(file) for file in glob(join(self._workdir, '**/*'), recursive=True)
if isfile(file) and if isfile(file)
not any(fnmatchcase(file, blacklisted) for blacklisted in self.exclude)] and self._is_whitelisted(file)
and not any(fnmatchcase(file, blacklisted) for blacklisted in self.exclude)]
@property @property
def file_contents(self): def file_contents(self):
@ -67,6 +79,9 @@ class FileManager:
with open(self._filepath(self.filename), 'w', errors='surrogateescape') as ofile: with open(self._filepath(self.filename), 'w', errors='surrogateescape') as ofile:
ofile.write(value) ofile.write(value)
def _is_whitelisted(self, file):
return any(realpath(file).startswith(allowed_dir) for allowed_dir in self.allowed_directories)
def _filepath(self, filename): def _filepath(self, filename):
return join(self._workdir, filename) return join(self._workdir, filename)
@ -75,9 +90,11 @@ class FileManager:
class SourceCodeEventHandler(TriggerlessEventHandler): class SourceCodeEventHandler(TriggerlessEventHandler):
def __init__(self, key, directory, selected_file=None, exclude=None): # pylint: disable=too-many-arguments
def __init__(self, key, directory, allowed_directories, selected_file=None, exclude=None):
super().__init__(key) super().__init__(key)
self.filemanager = FileManager(directory, selected_file=selected_file, exclude=exclude) self.filemanager = FileManager(allowed_directories=allowed_directories, working_directory=directory,
selected_file=selected_file, exclude=exclude)
self.commands = {'read': self.read, self.commands = {'read': self.read,
'write': self.write, 'write': self.write,

View File

@ -5,6 +5,7 @@ from tfw.components.terminado_mini_server import TerminadoMiniServer
from tfw.event_handler_base import TriggerlessEventHandler from tfw.event_handler_base import TriggerlessEventHandler
from tfw.config import TFWENV from tfw.config import TFWENV
from tfw.config.logs import logging from tfw.config.logs import logging
from tao.config import TAOENV
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -14,7 +15,8 @@ class TerminadoEventHandler(TriggerlessEventHandler):
super().__init__(key) super().__init__(key)
self.working_directory = TFWENV.TERMINADO_DIR self.working_directory = TFWENV.TERMINADO_DIR
self._historymonitor = monitor self._historymonitor = monitor
self.terminado_server = TerminadoMiniServer('/terminal', TFWENV.TERMINADO_PORT, TFWENV.TERMINADO_WD, ['bash']) bash_as_user_cmd = ['sudo', '-u', TAOENV.USER, 'bash']
self.terminado_server = TerminadoMiniServer('/terminal', TFWENV.TERMINADO_PORT, TFWENV.TERMINADO_WD, bash_as_user_cmd)
self.commands = {'write': self.write, self.commands = {'write': self.write,
'read': self.read} 'read': self.read}
if self._historymonitor: if self._historymonitor:

View File

@ -1,5 +1,5 @@
[supervisord] [supervisord]
user=user user=root
logfile = /tmp/supervisord.log logfile = /tmp/supervisord.log
loglevel = debug loglevel = debug
pidfile = /tmp/supervisord.pid pidfile = /tmp/supervisord.pid
@ -18,9 +18,5 @@ command=/usr/sbin/nginx -g 'daemon off;'
autostart=true autostart=true
autorestart=true autorestart=true
[program:app]
directory=%(ENV_TFW_APP_DIR)s
command=python3 app.py
[include] [include]
files=%(ENV_TFW_SUPERVISORD_COMPONENTS)s/*.conf files=%(ENV_TFW_SUPERVISORD_COMPONENTS)s/*.conf