Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bandit security recommendations for Cylc 8 target #2998

Merged
merged 102 commits into from
Mar 20, 2019
Merged
Show file tree
Hide file tree
Changes from 95 commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
15c342b
Merge pull request #1 from cylc/master
MartinRyan Dec 10, 2018
1f6d88a
bandit security remediation
MartinRyan Dec 12, 2018
7d1a86f
Merge remote-tracking branch 'origin/master'
MartinRyan Dec 12, 2018
1976c65
bandit security remediation
MartinRyan Dec 13, 2018
0023eb6
bandit security remediation
MartinRyan Dec 13, 2018
9b716c3
using defusedxml to replace xmlrpclib
MartinRyan Dec 14, 2018
3cef7ac
defusedxml comments
MartinRyan Dec 16, 2018
dc873b0
defused xml
MartinRyan Dec 17, 2018
ea3f75d
wip: defusedxml monkey patching
MartinRyan Dec 18, 2018
0c0a70f
bandit security remediation
MartinRyan Dec 19, 2018
e0cb850
address feedback and build issue
MartinRyan Dec 20, 2018
d7b0931
address feedback and build issue
MartinRyan Jan 2, 2019
24825c3
remove unused unsafe source files from cherrypy
MartinRyan Jan 2, 2019
3fa3780
address feedback
MartinRyan Jan 2, 2019
e7a37d2
fix state check
MartinRyan Jan 2, 2019
a3ab495
remove import
MartinRyan Jan 3, 2019
cb8548d
change import for subprocess-safe
MartinRyan Jan 4, 2019
e4a5950
autoescape for jinja2 rc files disabled
MartinRyan Jan 4, 2019
c24ad41
test subprocess_safe
MartinRyan Jan 4, 2019
fcd320c
comment
MartinRyan Jan 4, 2019
ba66ef6
remove popen variables
MartinRyan Jan 7, 2019
062bdc0
changed comment
MartinRyan Jan 7, 2019
21e261a
shebang update
MartinRyan Jan 7, 2019
0ce8368
bandit remediation
MartinRyan Jan 7, 2019
5e11ff9
nosec for codacy
MartinRyan Jan 7, 2019
1ff5445
removed trailing whitespace
MartinRyan Jan 7, 2019
f542fff
bandit issues
MartinRyan Jan 8, 2019
51ce3c9
pcylc - add debug info
MartinRyan Jan 8, 2019
a8fc616
slight change to formatting
MartinRyan Jan 8, 2019
5639fd4
comment additions
MartinRyan Jan 9, 2019
ee06418
comments and logging changes
MartinRyan Jan 9, 2019
6fb57a8
pep8 changes
MartinRyan Jan 10, 2019
84a9e5d
pep8 changes
MartinRyan Jan 10, 2019
64f0f2f
pcylc comments
MartinRyan Jan 10, 2019
20b8a66
moved nosec
MartinRyan Jan 10, 2019
c2977b2
updated test and revert logging in pcylc
MartinRyan Jan 11, 2019
5717399
Revert "updated test and revert logging in pcylc"
MartinRyan Jan 11, 2019
d370056
updated 16-timeout test, revert pcylc debug.log
MartinRyan Jan 11, 2019
2dfa2d0
wip:
MartinRyan Jan 14, 2019
85a0aa9
pcylc changes
MartinRyan Jan 15, 2019
a8aa1b4
correct import and arg, update comments
MartinRyan Jan 15, 2019
e5e5eb3
splitcmd arg shlex.split in pcylc
MartinRyan Jan 15, 2019
389b0b7
wip: debug build errors
MartinRyan Jan 15, 2019
c39aee4
shlex.split
MartinRyan Jan 16, 2019
a6bc0e4
prefer use of secrets over random when generating suite passwords
MartinRyan Jan 16, 2019
50fa189
Merge branch 'master' into master
MartinRyan Jan 16, 2019
c158f68
specify textfixtures version in travis.yml
MartinRyan Jan 16, 2019
c7fd6c8
Merge remote-tracking branch 'origin/master'
MartinRyan Jan 16, 2019
513cf4d
testfixtures version
MartinRyan Jan 16, 2019
6d9bf07
add testfixtures to install.sh
MartinRyan Jan 16, 2019
f51af34
implicitly import secrets
MartinRyan Jan 18, 2019
4eeb49c
use compare instead of assert
MartinRyan Jan 18, 2019
34a2811
Use higher contrast link colours.
arjclark Feb 1, 2019
154b3e8
removed testfixtures line
MartinRyan Feb 11, 2019
690c111
Merge pull request #2948 from hjoliver/doc_link_colours_2
sadielbartholomew Feb 11, 2019
8cbb853
Fixes: top-level makefile command
sadielbartholomew Feb 12, 2019
8e4b902
remrun
MartinRyan Feb 13, 2019
92f09ec
spurious blank line removed
MartinRyan Feb 13, 2019
158d01a
refactor naming
MartinRyan Feb 13, 2019
75e8427
fix typo
MartinRyan Feb 13, 2019
8d6eee7
remove blank line
MartinRyan Feb 13, 2019
25361af
correct year
MartinRyan Feb 13, 2019
676e8c9
removed a noqa
MartinRyan Feb 13, 2019
fcf661e
replace noqa E402
MartinRyan Feb 13, 2019
82e4a59
noqas
MartinRyan Feb 13, 2019
1357549
fix under indent
MartinRyan Feb 13, 2019
01a3dc4
removed E402 noqas
MartinRyan Feb 13, 2019
1832035
using master version of .travis.yml
MartinRyan Feb 13, 2019
f0431f2
Fix missing import in gcylc cfgspec.
hjoliver Feb 14, 2019
6442cb9
remove unused import
MartinRyan Feb 14, 2019
19d51e3
removed innaccurate comment
MartinRyan Feb 15, 2019
b0646c0
Merge pull request #2952 from sadielbartholomew/7.8.x-compat-i2950-to…
oliver-sanders Feb 15, 2019
cda7326
Merge branch 'master' into mryan-dev-001
MartinRyan Feb 17, 2019
4f8e425
resolve conflict - remove import
MartinRyan Feb 17, 2019
03a4523
Merge remote-tracking branch 'origin/mryan-dev-001' into mryan-dev-001
MartinRyan Feb 17, 2019
f89fe0e
Revert "resolve conflict - remove import"
MartinRyan Feb 17, 2019
c6a0ab5
remove import
MartinRyan Feb 17, 2019
46ce95e
resolve codacy error
MartinRyan Feb 17, 2019
946ec4c
Merge pull request #2955 from hjoliver/fix-missing-import
matthewrmshin Feb 25, 2019
33a4a8a
Fix missing python2 lines.
hjoliver Feb 26, 2019
7325985
General single- and multi-page User Guides.
hjoliver Feb 26, 2019
c042ff8
Minor suggestions to adapt docs source for single-page HTML
sadielbartholomew Feb 27, 2019
86f4b2a
Merge pull request #7 from sadielbartholomew/sphinx-doc-single-additions
hjoliver Feb 27, 2019
3ff6140
Merge pull request #2970 from hjoliver/sphinx-doc-single
hjoliver Feb 27, 2019
033c3bb
Merge pull request #2969 from hjoliver/python2
matthewrmshin Mar 1, 2019
4e0cdcf
Fix issue #2898: close app nicely on CTRL+C
kinow Mar 11, 2019
45300f4
Merge pull request #2986 from kinow/fix-issue-2898-2
hjoliver Mar 11, 2019
76c3a6a
Backport #2981
hjoliver Mar 12, 2019
70dd301
Merge pull request #2992 from hjoliver/event_time_instead
kinow Mar 12, 2019
e148921
Merge branch '7.8.x' into mryan-dev-001
MartinRyan Mar 12, 2019
8ac7e97
cylc-8 target for bandit remediation
MartinRyan Mar 13, 2019
2cf6204
shebang
MartinRyan Mar 13, 2019
3e2bd17
py3 changes for merge
MartinRyan Mar 13, 2019
e073cf8
py3 changes for bandit reccomendations
MartinRyan Mar 13, 2019
a90e931
fix pycodestyle errors
MartinRyan Mar 13, 2019
db0cfbd
revert jinja2 changes
MartinRyan Mar 13, 2019
33bbc0c
orderedDict import
MartinRyan Mar 14, 2019
0407724
Merge branch 'master' into MartinRyan-mryan-dev-002
MartinRyan Mar 14, 2019
abe646a
Merge branch 'master' into MartinRyan-mryan-dev-002
MartinRyan Mar 15, 2019
c934fc5
fix for 01-help.t error
MartinRyan Mar 18, 2019
37efca6
Merge branch 'master' into HEAD
hjoliver Mar 20, 2019
04d749a
Use stdlib mock.
hjoliver Mar 20, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ if grep -E '(unit-tests|functional-tests)' <<< "${args[@]}"; then
fi

if grep 'unit-tests' <<< "${args[@]}"; then
pip install pycodestyle pytest
pip install pycodestyle pytest mock testfixtures
hjoliver marked this conversation as resolved.
Show resolved Hide resolved
# TODO: EmPy removed from testing, see: #2958
fi

Expand Down
27 changes: 15 additions & 12 deletions bin/cylc-check-software
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@ Arguments:
valid module arguments (lower-case equivalents accepted).
"""

import sys
import re
import os
from subprocess import check_call, PIPE, Popen, CalledProcessError
import re
import sys
from subprocess import PIPE, CalledProcessError, check_call

from cylc.cylc_subproc import procopen

# Standardised output messages
FOUND_NOVER_MSG = 'FOUND'
Expand Down Expand Up @@ -72,7 +74,7 @@ opt_result = {}

def output_width(min_width=65, max_width=90):
"""Return a suitable output alignment width given user terminal width."""
proc = Popen(['stty', 'size'], stdout=PIPE)
proc = procopen(['stty', 'size'], stdoutpipe=True)
if proc.wait():
return int((min_width + max_width) / 2)
else:
Expand Down Expand Up @@ -176,7 +178,7 @@ def tex_module_search(tex_module, write=True):
cmd = ['kpsewhich', '%s.sty' % tex_module]
# This is less intensive & quicker than searching via 'find' or 'locate'.
try:
process = Popen(cmd, stdin=open(os.devnull), stdout=PIPE)
process = procopen(cmd, stdin=open(os.devnull), stdoutpipe=True)
check_call(['test', '-n', process.communicate()[0].strip()],
stdin=open(os.devnull), stdout=PIPE, stderr=PIPE)
except (CalledProcessError, OSError):
Expand All @@ -189,8 +191,8 @@ def tex_module_search(tex_module, write=True):
return True


def cmd_find_ver(
module, min_ver, cmd_base, ver_opt, ver_extr, outfile=1, write=True):
def cmd_find_ver(module, min_ver, cmd_base, ver_opt, ver_extr, outfile=1,
write=True):
"""Print outcome & return Boolean (True for pass) of local module version
requirement test using relevant custom command base keyword(s),
version-checking option(s) & version-extraction regex.
Expand All @@ -199,14 +201,15 @@ def cmd_find_ver(
min_ver is not None else 'any')
for cmd in cmd_base:
try_next_cmd = True
if Popen(['which', cmd], stdin=open(os.devnull), stdout=PIPE,
stderr=PIPE).wait():
if procopen(['which', cmd], stdin=open(os.devnull),
stdoutpipe=True, stderrpipe=True).wait():
res = [NOTFOUND_MSG, False]
else:
try:
output = Popen([cmd, ver_opt], stdin=open(os.devnull),
stdout=PIPE, stderr=PIPE
).communicate()[outfile - 1].decode().strip()
output = procopen([cmd, ver_opt], stdoutpipe=True,
stdin=open(os.devnull),
stderrpipe=True).communicate()
[outfile - 1].decode().strip()
version = re.search(ver_extr, output).groups()[0]
try_next_cmd = False
if min_ver is None:
Expand Down
10 changes: 6 additions & 4 deletions bin/cylc-check-versions
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,19 @@ Use -v/--verbose to see the command invoked to determine the remote version
site dependent -- see cylc global config documentation."""

import os
import shlex
import sys
from subprocess import Popen, PIPE
from time import sleep

import cylc.flags
from cylc.option_parsers import CylcOptionParser as COP
from cylc.version import CYLC_VERSION
from cylc.config import SuiteConfig
from cylc.option_parsers import CylcOptionParser as COP
from cylc.cylc_subproc import procopen
from cylc.subprocpool import SuiteProcPool
from cylc.suite_srv_files_mgr import SuiteSrvFilesManager
from cylc.task_remote_mgr import TaskRemoteMgr
from cylc.templatevars import load_template_vars
from cylc.version import CYLC_VERSION


def main():
Expand Down Expand Up @@ -112,7 +113,8 @@ def main():
user_at_host = host
if verbose:
print("%s: %s" % (user_at_host, ' '.join(argv)))
proc = Popen(argv, stdin=open(os.devnull), stdout=PIPE, stderr=PIPE)
proc = procopen(argv, stdin=open(os.devnull), stdoutpipe=True,
stderrpipe=True)
out, err = proc.communicate()
out = out.decode()
err = err.decode()
Expand Down
13 changes: 6 additions & 7 deletions etc/dev-bin/defn-order-test.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#!/usr/bin/env python3

import secrets
import string
import time
from string import ascii_letters
import random
from copy import deepcopy

# This is a standalone performance test of the algorithm used in gcylc to
Expand All @@ -16,17 +16,16 @@
# order").
names = []
for i in range(0, N):
names.append(''.join(
random.choice(ascii_letters)
for n in range(5 + random.randrange(10))))
names.append(''.join(secrets.choice(string.ascii_letters)
for n in range(5 + secrets.randrange(10))))

# N lists with 2-7 names each (c.f. tree view paths of the inheritance
# hierarchy).
paths1 = []
for i in range(0, N):
p = []
for j in range(0, 2 + random.randrange(6)):
z = random.randrange(0, N)
for j in range(0, 2 + secrets.randrange(6)):
z = secrets.randrange(0, N)
p.append(names[z])
paths1.append(p)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,7 @@ def cylc_kafka_consumer(kafka_server, kafka_topic, group_id, message, debug):

A match occurs Kafka if all message dict items match, and the result
returned is the sub-dict of the actual values of items containing
angle-bracket-delineated regex patterns.
E.g. above {'data': 'nwp-2025.nc'}.
angle-bracket-delineated regex patterns. E.g. above {'data': 'nwp-2025.nc'}

"""

Expand Down
40 changes: 18 additions & 22 deletions lib/cylc/batch_sys_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,27 +107,24 @@

"""

import os
import json
import os
import shlex
from shutil import rmtree
from signal import SIGKILL
import stat
from subprocess import Popen, PIPE
import sys
import traceback


from parsec.OrderedDict import OrderedDict

from shutil import rmtree
from signal import SIGKILL

from cylc.task_message import (
CYLC_JOB_PID, CYLC_JOB_INIT_TIME, CYLC_JOB_EXIT_TIME, CYLC_JOB_EXIT,
CYLC_MESSAGE)
from cylc.cylc_subproc import procopen
from cylc.task_job_logs import (JOB_LOG_ERR, JOB_LOG_JOB, JOB_LOG_OUT,
JOB_LOG_STATUS)
from cylc.task_outputs import TASK_OUTPUT_SUCCEEDED
from cylc.task_job_logs import (
JOB_LOG_JOB, JOB_LOG_OUT, JOB_LOG_ERR, JOB_LOG_STATUS)
from cylc.wallclock import get_current_time_string
from parsec import OrderedDict


class JobPollContext(object):
Expand Down Expand Up @@ -419,8 +416,8 @@ def job_kill(self, st_file_path):
command = shlex.split(
batch_sys.KILL_CMD_TMPL % {"job_id": job_id})
try:
proc = Popen(
command, stdin=open(os.devnull), stderr=PIPE)
proc = procopen(command, stdin=open(os.devnull),
stderrpipe=True)
except OSError as exc:
# subprocess.Popen has a bad habit of not setting the
# filename of the executable when it raises an OSError.
Expand Down Expand Up @@ -552,8 +549,8 @@ def _jobs_poll_batch_sys(self, job_log_root, batch_sys_name, my_ctx_list):
# Simple poll command that takes a list of job IDs
cmd = [batch_sys.POLL_CMD] + exp_ids
try:
proc = Popen(
cmd, stdin=open(os.devnull), stderr=PIPE, stdout=PIPE)
proc = procopen(cmd, stdin=open(os.devnull),
stderrpipe=True, stdoutpipe=True)
except OSError as exc:
# subprocess.Popen has a bad habit of not setting the
# filename of the executable when it raises an OSError.
Expand Down Expand Up @@ -662,18 +659,17 @@ def _job_submit_impl(
# that we do not have a shell, and still manage to get as far
# as here.
batch_sys_cmd = batch_submit_cmd_tmpl % {"job": job_file_path}
proc = Popen(
batch_sys_cmd,
stdin=proc_stdin_arg, stdout=PIPE, stderr=PIPE,
shell=True, env=env)
proc = procopen(batch_sys_cmd, stdin=proc_stdin_arg,
stdoutpipe=True, stderrpipe=True, usesh=True,
env=env)
# calls to open a shell are aggregated in
# cylc_subproc.procopen()
else:
command = shlex.split(
batch_sys.SUBMIT_CMD_TMPL % {"job": job_file_path})
try:
proc = Popen(
command,
stdin=proc_stdin_arg, stdout=PIPE, stderr=PIPE,
env=env)
proc = procopen(command, stdin=proc_stdin_arg,
stdoutpipe=True, stderrpipe=True, env=env)
except OSError as exc:
# subprocess.Popen has a bad habit of not setting the
# filename of the executable when it raises an OSError.
Expand Down
58 changes: 58 additions & 0 deletions lib/cylc/cylc_subproc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/usr/bin/env python3

# THIS FILE IS PART OF THE CYLC SUITE ENGINE.
# Copyright (C) 2008-2018 NIWA & British Crown (Met Office) & Contributors.
#
# 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
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

""" A wrapper function to aggregate these calls in one file.
Bandit B602: subprocess_popen_with_shell_equals_true
https://docs.openstack.org/developer/bandit/plugins/subprocess_popen_with_shell_equals_true.html
B605: start_process_with_a_shell
https://docs.openstack.org/developer/bandit/plugins/start_process_with_a_shell.html
"""
from shlex import split
from subprocess import PIPE, STDOUT, Popen # nosec

# pylint: disable=too-many-arguments
# pylint: disable=too-many-locals


def procopen(cmd, bufsize=0, executable=None, stdin=None, stdout=None,
stderr=None, preexec_fn=None, close_fds=False, usesh=False,
cwd=None, env=None, universal_newlines=False, startupinfo=None,
creationflags=0, splitcmd=False, stdoutpipe=False,
stdoutout=False, stderrpipe=False, stderrout=False):

shell = usesh

if stdoutpipe is True:
stdout = PIPE
elif stdoutout is True:
stdout = STDOUT
if stderrpipe is True:
stderr = PIPE
elif stderrout is True:
stderr = STDOUT

if splitcmd is True:
command = split(cmd)
else:
command = cmd

process = Popen(command, bufsize, executable, stdin, stdout, # nosec
stderr, preexec_fn, close_fds, shell, cwd, env,
universal_newlines, startupinfo, creationflags)

return process
17 changes: 11 additions & 6 deletions lib/cylc/profiling/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,18 @@

import os
import shutil
from subprocess import Popen, PIPE, call
import sys
import tempfile
import time
import traceback
from subprocess import PIPE, Popen, call # nosec

from . import (PROFILE_MODE_TIME, PROFILE_MODE_CYLC, PROFILE_MODES,
PROFILE_FILES, SUITE_STARTUP_STRING)
from cylc.cylc_subproc import procopen

from . import (PROFILE_FILES, PROFILE_MODE_CYLC, PROFILE_MODE_TIME,
PROFILE_MODES, SUITE_STARTUP_STRING)
from .analysis import extract_results
from .git import (checkout, describe, GitCheckoutError,)
from .git import GitCheckoutError, checkout, describe


def cylc_env(cylc_conf_path=''):
Expand Down Expand Up @@ -187,8 +189,11 @@ def run_suite(reg, options, out_file, profile_modes, mode='live',
# Execute.
print('$ ' + ' '.join(cmds))
try:
proc = Popen(' '.join(cmds), shell=True, stderr=open(time_err, 'w+'),
stdout=open(startup_file, 'w+'), env=env)
proc = procopen([' '.join(cmds)], usesh=True,
stderr=open(time_err, 'w+'),
# calls to open a shell are aggregated in
# cylc_subproc.procopen()
stdout=open(startup_file, 'w+'), env=env)
if proc.wait():
raise SuiteFailedException(run_cmds, cmd_out, cmd_err)
except KeyboardInterrupt:
Expand Down
9 changes: 5 additions & 4 deletions lib/cylc/run_get_stdout.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@

from os import devnull, killpg, setpgrp
from signal import SIGTERM
from subprocess import Popen, PIPE
from time import sleep, time

from cylc.cylc_subproc import procopen


ERR_TIMEOUT = "ERROR: command timed out (>%ds), terminated by signal %d\n%s"
ERR_SIGNAL = "ERROR: command terminated by signal %d\n%s"
Expand All @@ -44,9 +45,9 @@ def run_get_stdout(command, timeout=None, poll_delay=None):

"""
try:
proc = Popen(
command, shell=True, preexec_fn=setpgrp, stdin=open(devnull),
stderr=PIPE, stdout=PIPE)
proc = procopen(command, usesh=True, preexec_fn=setpgrp,
stdin=open(devnull), stderrpipe=True, stdoutpipe=True)
# calls to open a shell are aggregated in cylc_subproc.procopen()
is_killed_after_timeout = False
if timeout:
if poll_delay is None:
Expand Down
Loading