Fix bug where general user can change working directory and potentially destroy a system.

Initial commit for path traversal for server config only.
This commit is contained in:
Andrew 2021-11-27 21:52:49 -05:00
parent 0cd8f6b3a7
commit 78834c1ed0
4 changed files with 33 additions and 9 deletions

View File

@ -82,6 +82,9 @@ class Helpers:
logger.error("{} does not exist".format(file))
return True
def get_servers_root_dir(self):
return self.servers_dir
@staticmethod
def check_internet():
try:
@ -274,6 +277,19 @@ class Helpers:
return line
def validate_traversal(self, base_path, filename):
logger.debug("Validating traversal (\"{x}\", \"{y}\")".format(x=base_path, y=filename))
base = pathlib.Path(base_path).resolve()
file = pathlib.Path(filename)
fileabs = base.joinpath(file).resolve()
cp = pathlib.Path(os.path.commonpath([base, fileabs]))
if base == cp:
return fileabs
else:
raise ValueError("Path traversal detected")
def tail_file(self, file_name, number_lines=20):
if not self.check_file_exists(file_name):
logger.warning("Unable to find file to tail: {}".format(file_name))

View File

@ -654,16 +654,19 @@ class PanelHandler(BaseHandler):
execution_command = execution_command.replace(str(stale_executable), str(executable))
server_obj.server_name = server_name
server_obj.path = server_path
server_obj.log_path = log_path
server_obj.executable = executable
server_obj.execution_command = execution_command
server_obj.stop_command = stop_command
if exec_user['superuser']:
if helper.validate_traversal(helper.get_servers_root_dir(), server_path):
server_obj.path = server_path
server_obj.log_path = log_path
if helper.validate_traversal(helper.get_servers_root_dir(), executable):
server_obj.executable = executable
server_obj.execution_command = execution_command
server_obj.stop_command = stop_command
server_obj.server_ip = server_ip
server_obj.server_port = server_port
server_obj.executable_update_url = executable_update_url
server_obj.auto_start_delay = auto_start_delay
server_obj.server_ip = server_ip
server_obj.server_port = server_port
server_obj.auto_start = auto_start
server_obj.executable_update_url = executable_update_url
server_obj.crash_detection = crash_detection
server_obj.logs_delete_after = logs_delete_after
self.controller.servers.update_server(server_obj)

View File

@ -140,7 +140,7 @@
<tr class="rounded">
<th>Permission Name</th>
<th>Authorized ?</th>
<th>Number of Uses Allowed (0=No Limit)</th>
<th>Number of Uses Allowed (-1=No Limit)</th>
</tr>
</thead>
<tbody>

View File

@ -47,8 +47,10 @@
</div>
<div class="form-group">
{% if data['super_user'] %}
<label for="server_path">{{ translate('serverConfig', 'serverPath', data['lang']) }} <small class="text-muted ml-1"> - {{ translate('serverConfig', 'serverPathDesc', data['lang']) }}</small> </label>
<input type="text" class="form-control" name="server_path" id="server_path" value="{{ data['server_stats']['server_id']['path'] }}" placeholder="{{ translate('serverConfig', 'serverPath', data['lang']) }}" required>
</div>
<div class="form-group">
@ -64,6 +66,7 @@
<div class="form-group">
<label for="execution_command">{{ translate('serverConfig', 'serverExecutionCommand', data['lang']) }} <small class="text-muted ml-1"> - {{ translate('serverConfig', 'serverExecutionCommandDesc', data['lang']) }}</small> </label>
<input type="text" class="form-control" name="execution_command" id="execution_command" value="{{ data['server_stats']['server_id']['execution_command'] }}" placeholder="{{ translate('serverConfig', 'serverExecutionCommand', data['lang']) }}" required>
{% end %}
</div>
<div class="form-group">
@ -76,6 +79,7 @@
<input type="number" class="form-control" name="auto_start_delay" id="auto_start_delay" value="{{ data['server_stats']['server_id']['auto_start_delay'] }}" step="1" max="999" min="10" required>
</div>
{% if data['super_user'] %}
<div class="form-group">
<label for="executable_update_url">{{ translate('serverConfig', 'exeUpdateURL', data['lang']) }} <small class="text-muted ml-1"> - {{ translate('serverConfig', 'exeUpdateURLDesc', data['lang']) }}</small> </label>
<input type="text" class="form-control" name="executable_update_url" id="executable_update_url" value="{{ data['server_stats']['server_id']['executable_update_url'] }}" placeholder="{{ translate('serverConfig', 'exeUpdateURL', data['lang']) }}" required>
@ -90,6 +94,7 @@
<label for="server_port">{{ translate('serverConfig', 'serverPort', data['lang']) }} <small class="text-muted ml-1"> - {{ translate('serverConfig', 'serverPortDesc', data['lang']) }} </small> </label>
<input type="number" class="form-control" name="server_port" id="server_port" value="{{ data['server_stats']['server_id']['server_port'] }}" step="1" max="65566" min="1" required>
</div>
{% end %}
<div class="form-group">
<label for="logs_delete_after">{{ translate('serverConfig', 'removeOldLogsAfter', data['lang']) }} <small class="text-muted ml-1"> - {{ translate('serverConfig', 'removeOldLogsAfterDesc', data['lang']) }}</small> </label>