From d061801257756441a0756433d09d28858f0768c3 Mon Sep 17 00:00:00 2001 From: Joshua Seals Date: Tue, 18 Jul 2023 09:18:10 -0400 Subject: [PATCH 01/17] Adding security scans, updates to dockerfile images --- .../workflows/{flake8.yml => code-checks.yml} | 21 +++++++++++++++++++ Dockerfile | 3 ++- docker/api/Dockerfile | 3 ++- 3 files changed, 25 insertions(+), 2 deletions(-) rename .github/workflows/{flake8.yml => code-checks.yml} (62%) diff --git a/.github/workflows/flake8.yml b/.github/workflows/code-checks.yml similarity index 62% rename from .github/workflows/flake8.yml rename to .github/workflows/code-checks.yml index 0757bb98..6d7acf93 100644 --- a/.github/workflows/flake8.yml +++ b/.github/workflows/code-checks.yml @@ -35,3 +35,24 @@ jobs: flake8 --ignore=E,W --exit-zero . # We continue on error here until the code is clean continue-on-error: true + +############################ Bandit ################################ + bandit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.9' + + - name: Install Requirements + run: | + pip install -r requirements.txt + pip install bandit + pip install . + + # Only report high security issues + - name: Test with Bandit + run: | + bandit -r src -n3 -lll \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 9ef31a79..9b0a602b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,5 @@ -FROM python:3.9.0-slim +FROM python:3.12.0b4-slim +# FROM python:3.9.0-slim RUN apt-get update && \ apt-get install -y build-essential libffi-dev libssl-dev git make diff --git a/docker/api/Dockerfile b/docker/api/Dockerfile index 019b5375..439e2309 100644 --- a/docker/api/Dockerfile +++ b/docker/api/Dockerfile @@ -1,4 +1,5 @@ -FROM python:3.7.3-alpine +# FROM python:3.7.3-alpine +FROM python:3.11.4-alpine3.18 WORKDIR / From bbc8302cd4097b8101d380cb8dc1acedc322bbcf Mon Sep 17 00:00:00 2001 From: Joshua Seals Date: Tue, 18 Jul 2023 09:27:28 -0400 Subject: [PATCH 02/17] Bandit adjustments --- .github/dependabot.yml | 13 ------------- .github/workflows/code-checks.yml | 2 +- 2 files changed, 1 insertion(+), 14 deletions(-) delete mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index bff6784e..00000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,13 +0,0 @@ -# To get started with Dependabot version updates, you'll need to specify which -# package ecosystems to update and where the package manifests are located. -# Please see the documentation for all configuration options: -# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates - -version: 2 -updates: - # Maintain dependencies for GitHub Actions - - package-ecosystem: "github-actions" - # Workflow files stored in the default location of `.github/workflows` - directory: "/" - schedule: - interval: "weekly" diff --git a/.github/workflows/code-checks.yml b/.github/workflows/code-checks.yml index 6d7acf93..fa3c7a43 100644 --- a/.github/workflows/code-checks.yml +++ b/.github/workflows/code-checks.yml @@ -55,4 +55,4 @@ jobs: # Only report high security issues - name: Test with Bandit run: | - bandit -r src -n3 -lll \ No newline at end of file + bandit -r tycho/*.py -n 3 -lll \ No newline at end of file From c2c325c6baabe995cfbf8c69f83a90141cdaeb92 Mon Sep 17 00:00:00 2001 From: Joshua Seals Date: Tue, 18 Jul 2023 09:30:00 -0400 Subject: [PATCH 03/17] Testing workflow --- .github/workflows/code-checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/code-checks.yml b/.github/workflows/code-checks.yml index fa3c7a43..a294c2d9 100644 --- a/.github/workflows/code-checks.yml +++ b/.github/workflows/code-checks.yml @@ -6,7 +6,7 @@ on: - README.md - .old_cicd/* - .github/* - - .github/workflows/* + # - .github/workflows/* - LICENSE - .gitignore - .dockerignore From ea410d6f7985b993b9ddf99aada2f3b5c38e5682 Mon Sep 17 00:00:00 2001 From: Joshua Seals Date: Tue, 18 Jul 2023 12:06:56 -0400 Subject: [PATCH 04/17] Fix to high and med vulnerabilities --- tycho/dockerc.py | 2 +- tycho/kube.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tycho/dockerc.py b/tycho/dockerc.py index c4889f94..07f18a19 100644 --- a/tycho/dockerc.py +++ b/tycho/dockerc.py @@ -47,7 +47,7 @@ def run (self): stream.write (env) """ Find and return ports for each container. """ - config = yaml.load (TemplateUtils.apply_environment ( + config = yaml.safe_load(TemplateUtils.apply_environment ( env, self.system.source_text)) logger.debug (f"Building conainer map for system {self.system.name}") diff --git a/tycho/kube.py b/tycho/kube.py index 2595a4a7..5ba9a049 100644 --- a/tycho/kube.py +++ b/tycho/kube.py @@ -277,9 +277,9 @@ def get_service_ip_address (self, service_metadata): exe = shutil.which ('kubectl') command = f"{exe} port-forward --pod-running-timeout=3m0s deployment/{app_id} {node_port}:{port}" logger.debug (f"-- port-forward: {command}") - process = subprocess.Popen (command, - shell=True, - stderr=subprocess.STDOUT) + # process = subprocess.Popen (command, + # shell=True, + # stderr=subprocess.STDOUT) """ process dies when the other end disconnects so no need to clean up in delete. """ #ip_address = "127.0.0.1" except Exception as e: From 0c146443919805551f55b37eb51eea919bb17582 Mon Sep 17 00:00:00 2001 From: Joshua Seals Date: Tue, 18 Jul 2023 12:42:54 -0400 Subject: [PATCH 05/17] Parsing bandit scans and adding skip codes with a few code adjustements --- tycho/actions.py | 4 ++-- tycho/api.py | 6 +++--- tycho/client.py | 7 ++++--- tycho/kube.py | 2 ++ 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/tycho/actions.py b/tycho/actions.py index 08c0ac32..18a48081 100644 --- a/tycho/actions.py +++ b/tycho/actions.py @@ -25,7 +25,7 @@ 'api-schema.yaml') template = None with open(schema_file_path, 'r') as file_obj: - template = yaml.load(file_obj, Loader=yaml.FullLoader) + template = yaml.load(file_obj, Loader=yaml.FullLoader) #nosec B506 backplane = None _tycho = Tycho(backplane=backplane) @@ -45,7 +45,7 @@ def validate(self, request, component): """ Validate a request against the schema. """ if not self.specs: with open(schema_file_path, 'r') as file_obj: - self.specs = yaml.load(file_obj, Loader=yaml.FullLoader) + self.specs = yaml.load(file_obj, Loader=yaml.FullLoader) #nosec B506 to_validate = self.specs["components"]["schemas"][component] try: logger.debug(f"--:Validating obj {request}") diff --git a/tycho/api.py b/tycho/api.py index d8274914..317d52eb 100644 --- a/tycho/api.py +++ b/tycho/api.py @@ -38,7 +38,7 @@ 'api-schema.yaml') template = None with open(schema_file_path, 'r') as file_obj: - template = yaml.load(file_obj, Loader=yaml.FullLoader) + template = yaml.load(file_obj, Loader=yaml.FullLoader) #nosec B506 """ Describe the API. """ app.config['SWAGGER'] = { @@ -73,7 +73,7 @@ def validate (self, request, component): """ Validate a request against the schema. """ if not self.specs: with open(schema_file_path, 'r') as file_obj: - self.specs = yaml.load(file_obj, Loader=yaml.FullLoader) + self.specs = yaml.load(file_obj, Loader=yaml.FullLoader) #nosec B506 to_validate = self.specs["components"]["schemas"][component] try: app.logger.debug (f"--:Validating obj {json.dumps(request.json, indent=2)}") @@ -268,4 +268,4 @@ def post(self): if args.debug: debug = True logging.basicConfig(level=logging.DEBUG) - app.run(host='0.0.0.0', port=args.port, threaded=True, debug=args.debug) + app.run(host='0.0.0.0', port=args.port, threaded=True, debug=args.debug) #nosec B104 diff --git a/tycho/client.py b/tycho/client.py index 95890d14..3ad3aebf 100644 --- a/tycho/client.py +++ b/tycho/client.py @@ -124,7 +124,7 @@ def request (self, service, request): :param request: JSON to send to the API endpoint. """ if os.environ.get("REST_API", "false") == "true": - response = requests.post (f"{self.url}/{service}", json=request) + response = requests.post (f"{self.url}/{service}", json=request) # nosec B113 result_text = f"HTTP status {response.status_code} received from service: {service}" logger.debug (f"TychoClient.request - {result_text}") if not response.status_code == 200: @@ -539,9 +539,10 @@ def getmetadata(self): if os.path.exists (env_file): with open (env_file, 'r') as stream: settings = stream.read () - + # + # added SafeLoader type but not sure if unsafe load is needed. with open(args.file, "r") as stream: - system = yaml.load (stream.read ()) + system = yaml.load (stream.read (), Loader=yaml.SafeLoader) else: """ Generate a docker-compose spec based on the CLI args. """ name = args.name diff --git a/tycho/kube.py b/tycho/kube.py index 5ba9a049..d0b20494 100644 --- a/tycho/kube.py +++ b/tycho/kube.py @@ -277,6 +277,8 @@ def get_service_ip_address (self, service_metadata): exe = shutil.which ('kubectl') command = f"{exe} port-forward --pod-running-timeout=3m0s deployment/{app_id} {node_port}:{port}" logger.debug (f"-- port-forward: {command}") + # commented out July 18 2023 by Joshua Seals. Want to make sure this is not needed. + # shell=true was flagged as vulnerability by bandit. https://cwe.mitre.org/data/definitions/78.html # process = subprocess.Popen (command, # shell=True, # stderr=subprocess.STDOUT) From 72ee7fc084272da6f8313e492da99348e7f31faf Mon Sep 17 00:00:00 2001 From: Joshua Seals Date: Mon, 31 Jul 2023 13:46:30 -0400 Subject: [PATCH 06/17] Adding chuck and harit changes to requirements.txt --- requirements.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index 0ccfb093..9c316c4e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,7 @@ Flask-RESTful==0.3.9 Jinja2==3.0.3 MarkupSafe==2.0.1 PyJWT==2.3.0 -PyYAML==5.4.1 +PyYAML==6.0.1 Werkzeug==2.0.3 adal==1.2.7 aniso8601==9.0.1 @@ -19,7 +19,7 @@ certifi==2021.10.8 cffi==1.15.0 chardet==4.0.0 coverage==6.3.1 -cryptography==36.0.1 +cryptography==41.0.2 deepmerge==1.0.1 docker==5.0.3 docker-compose==1.29.2 @@ -52,7 +52,7 @@ pytest-cov==3.0.0 pytest-mock==3.7.0 python-dateutil==2.8.2 pytz==2021.3 -requests==2.27.1 +requests==2.31.0 requests-cache==0.9.2 requests-oauthlib==1.3.1 rsa==4.8 From 64813421be77ff3bec2471eeac485c19f50c1296 Mon Sep 17 00:00:00 2001 From: Joshua Seals Date: Mon, 31 Jul 2023 13:49:58 -0400 Subject: [PATCH 07/17] Uncomment ignore section of action --- .github/workflows/code-checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/code-checks.yml b/.github/workflows/code-checks.yml index a294c2d9..fa3c7a43 100644 --- a/.github/workflows/code-checks.yml +++ b/.github/workflows/code-checks.yml @@ -6,7 +6,7 @@ on: - README.md - .old_cicd/* - .github/* - # - .github/workflows/* + - .github/workflows/* - LICENSE - .gitignore - .dockerignore From 5f37db1d4075186612e225575626a372f24dfeb1 Mon Sep 17 00:00:00 2001 From: Joshua Seals Date: Mon, 31 Jul 2023 14:39:47 -0400 Subject: [PATCH 08/17] Testing --- .github/workflows/code-checks.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/code-checks.yml b/.github/workflows/code-checks.yml index fa3c7a43..6c9cfdd5 100644 --- a/.github/workflows/code-checks.yml +++ b/.github/workflows/code-checks.yml @@ -25,10 +25,10 @@ jobs: uses: actions/setup-python@v4 with: python-version: '3.x' - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt + # - name: Install dependencies + # run: | + # python -m pip install --upgrade pip + # pip install -r requirements.txt - name: Lint with flake8 run: | pip install flake8 From 5acaf946ca880b4940a0543972bbe24129a703c5 Mon Sep 17 00:00:00 2001 From: Joshua Seals Date: Mon, 31 Jul 2023 14:40:26 -0400 Subject: [PATCH 09/17] Testing --- .github/workflows/code-checks.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/code-checks.yml b/.github/workflows/code-checks.yml index 6c9cfdd5..97cb4287 100644 --- a/.github/workflows/code-checks.yml +++ b/.github/workflows/code-checks.yml @@ -5,8 +5,8 @@ on: paths-ignore: - README.md - .old_cicd/* - - .github/* - - .github/workflows/* + # - .github/* + # - .github/workflows/* - LICENSE - .gitignore - .dockerignore From d2335a831bc6ac70ddadac7762a60f11bc26a234 Mon Sep 17 00:00:00 2001 From: Joshua Seals Date: Mon, 31 Jul 2023 14:51:49 -0400 Subject: [PATCH 10/17] testing pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 4f64fa52..9688d274 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,7 +33,7 @@ dependencies = [ "jsonschema==3.2.0", "kubernetes==25.3.0", "netifaces==0.11.0", - "PyYAML==5.4.1", + "PyYAML==6.0.1", "requests==2.27.1", "requests_cache==0.9.2", ] From 8ae66b8faee556b7ac7f384174e828deb7b52dca Mon Sep 17 00:00:00 2001 From: Joshua Seals Date: Mon, 31 Jul 2023 15:33:29 -0400 Subject: [PATCH 11/17] updates to pyproject.toml --- pyproject.toml | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9688d274..4f64fa52 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,7 +33,7 @@ dependencies = [ "jsonschema==3.2.0", "kubernetes==25.3.0", "netifaces==0.11.0", - "PyYAML==6.0.1", + "PyYAML==5.4.1", "requests==2.27.1", "requests_cache==0.9.2", ] diff --git a/requirements.txt b/requirements.txt index 9c316c4e..7aea7578 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,7 @@ Flask-RESTful==0.3.9 Jinja2==3.0.3 MarkupSafe==2.0.1 PyJWT==2.3.0 -PyYAML==6.0.1 +PyYAML==5.4.1 Werkzeug==2.0.3 adal==1.2.7 aniso8601==9.0.1 From ff1152a74e88aac32a89d0c3c73272e110a40819 Mon Sep 17 00:00:00 2001 From: Joshua Seals Date: Tue, 1 Aug 2023 09:43:57 -0400 Subject: [PATCH 12/17] Removing unncessary language in workflows --- .github/workflows/code-checks.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/code-checks.yml b/.github/workflows/code-checks.yml index 97cb4287..422a1258 100644 --- a/.github/workflows/code-checks.yml +++ b/.github/workflows/code-checks.yml @@ -25,10 +25,7 @@ jobs: uses: actions/setup-python@v4 with: python-version: '3.x' - # - name: Install dependencies - # run: | - # python -m pip install --upgrade pip - # pip install -r requirements.txt + - name: Lint with flake8 run: | pip install flake8 @@ -48,9 +45,8 @@ jobs: - name: Install Requirements run: | - pip install -r requirements.txt + pip install --upgrade pip pip install bandit - pip install . # Only report high security issues - name: Test with Bandit From 374a9cc0c142fa0fa8b7b4e3ecd6bf202118f738 Mon Sep 17 00:00:00 2001 From: Joshua Seals Date: Tue, 1 Aug 2023 12:32:20 -0400 Subject: [PATCH 13/17] Removing docker-compose import --- pyproject.toml | 3 +-- requirements.txt | 7 +++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 4f64fa52..0dbc3428 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,6 @@ classifiers = [ ] dependencies = [ "deepmerge==1.0.1", - "docker_compose==1.29.2", "flasgger==0.9.5", "Flask==2.0.3", "flask_cors==3.0.10", @@ -33,7 +32,7 @@ dependencies = [ "jsonschema==3.2.0", "kubernetes==25.3.0", "netifaces==0.11.0", - "PyYAML==5.4.1", + "PyYAML==6.0.1", "requests==2.27.1", "requests_cache==0.9.2", ] diff --git a/requirements.txt b/requirements.txt index 7aea7578..3f98a9db 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,7 @@ Flask-RESTful==0.3.9 Jinja2==3.0.3 MarkupSafe==2.0.1 PyJWT==2.3.0 -PyYAML==5.4.1 +PyYAML==6.0.1 Werkzeug==2.0.3 adal==1.2.7 aniso8601==9.0.1 @@ -21,9 +21,8 @@ chardet==4.0.0 coverage==6.3.1 cryptography==41.0.2 deepmerge==1.0.1 -docker==5.0.3 -docker-compose==1.29.2 -docker-pycreds==0.4.0 +docker==5.0.3 +docker-pycreds==0.4.0 dockerpty==0.4.1 docopt==0.6.2 flasgger==0.9.5 From f7e3190178f697777b45590085a36a7286d7a7c8 Mon Sep 17 00:00:00 2001 From: Joshua Seals <117867292+joshua-seals@users.noreply.github.com> Date: Thu, 3 Aug 2023 12:07:31 -0400 Subject: [PATCH 14/17] Revert "security updates, includes Chuck and Harit updates to requirements.txt" --- .../workflows/{code-checks.yml => flake8.yml} | 29 ++++--------------- Dockerfile | 3 +- docker/api/Dockerfile | 3 +- pyproject.toml | 3 +- requirements.txt | 11 +++---- tycho/actions.py | 4 +-- tycho/api.py | 6 ++-- tycho/client.py | 7 ++--- tycho/dockerc.py | 2 +- tycho/kube.py | 8 ++--- 10 files changed, 28 insertions(+), 48 deletions(-) rename .github/workflows/{code-checks.yml => flake8.yml} (56%) diff --git a/.github/workflows/code-checks.yml b/.github/workflows/flake8.yml similarity index 56% rename from .github/workflows/code-checks.yml rename to .github/workflows/flake8.yml index 422a1258..0757bb98 100644 --- a/.github/workflows/code-checks.yml +++ b/.github/workflows/flake8.yml @@ -5,8 +5,8 @@ on: paths-ignore: - README.md - .old_cicd/* - # - .github/* - # - .github/workflows/* + - .github/* + - .github/workflows/* - LICENSE - .gitignore - .dockerignore @@ -25,30 +25,13 @@ jobs: uses: actions/setup-python@v4 with: python-version: '3.x' - + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt - name: Lint with flake8 run: | pip install flake8 flake8 --ignore=E,W --exit-zero . # We continue on error here until the code is clean continue-on-error: true - -############################ Bandit ################################ - bandit: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.9' - - - name: Install Requirements - run: | - pip install --upgrade pip - pip install bandit - - # Only report high security issues - - name: Test with Bandit - run: | - bandit -r tycho/*.py -n 3 -lll \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 9b0a602b..9ef31a79 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,4 @@ -FROM python:3.12.0b4-slim -# FROM python:3.9.0-slim +FROM python:3.9.0-slim RUN apt-get update && \ apt-get install -y build-essential libffi-dev libssl-dev git make diff --git a/docker/api/Dockerfile b/docker/api/Dockerfile index 439e2309..019b5375 100644 --- a/docker/api/Dockerfile +++ b/docker/api/Dockerfile @@ -1,5 +1,4 @@ -# FROM python:3.7.3-alpine -FROM python:3.11.4-alpine3.18 +FROM python:3.7.3-alpine WORKDIR / diff --git a/pyproject.toml b/pyproject.toml index 0dbc3428..4f64fa52 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ ] dependencies = [ "deepmerge==1.0.1", + "docker_compose==1.29.2", "flasgger==0.9.5", "Flask==2.0.3", "flask_cors==3.0.10", @@ -32,7 +33,7 @@ dependencies = [ "jsonschema==3.2.0", "kubernetes==25.3.0", "netifaces==0.11.0", - "PyYAML==6.0.1", + "PyYAML==5.4.1", "requests==2.27.1", "requests_cache==0.9.2", ] diff --git a/requirements.txt b/requirements.txt index 3f98a9db..0ccfb093 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,7 @@ Flask-RESTful==0.3.9 Jinja2==3.0.3 MarkupSafe==2.0.1 PyJWT==2.3.0 -PyYAML==6.0.1 +PyYAML==5.4.1 Werkzeug==2.0.3 adal==1.2.7 aniso8601==9.0.1 @@ -19,10 +19,11 @@ certifi==2021.10.8 cffi==1.15.0 chardet==4.0.0 coverage==6.3.1 -cryptography==41.0.2 +cryptography==36.0.1 deepmerge==1.0.1 -docker==5.0.3 -docker-pycreds==0.4.0 +docker==5.0.3 +docker-compose==1.29.2 +docker-pycreds==0.4.0 dockerpty==0.4.1 docopt==0.6.2 flasgger==0.9.5 @@ -51,7 +52,7 @@ pytest-cov==3.0.0 pytest-mock==3.7.0 python-dateutil==2.8.2 pytz==2021.3 -requests==2.31.0 +requests==2.27.1 requests-cache==0.9.2 requests-oauthlib==1.3.1 rsa==4.8 diff --git a/tycho/actions.py b/tycho/actions.py index 18a48081..08c0ac32 100644 --- a/tycho/actions.py +++ b/tycho/actions.py @@ -25,7 +25,7 @@ 'api-schema.yaml') template = None with open(schema_file_path, 'r') as file_obj: - template = yaml.load(file_obj, Loader=yaml.FullLoader) #nosec B506 + template = yaml.load(file_obj, Loader=yaml.FullLoader) backplane = None _tycho = Tycho(backplane=backplane) @@ -45,7 +45,7 @@ def validate(self, request, component): """ Validate a request against the schema. """ if not self.specs: with open(schema_file_path, 'r') as file_obj: - self.specs = yaml.load(file_obj, Loader=yaml.FullLoader) #nosec B506 + self.specs = yaml.load(file_obj, Loader=yaml.FullLoader) to_validate = self.specs["components"]["schemas"][component] try: logger.debug(f"--:Validating obj {request}") diff --git a/tycho/api.py b/tycho/api.py index 317d52eb..d8274914 100644 --- a/tycho/api.py +++ b/tycho/api.py @@ -38,7 +38,7 @@ 'api-schema.yaml') template = None with open(schema_file_path, 'r') as file_obj: - template = yaml.load(file_obj, Loader=yaml.FullLoader) #nosec B506 + template = yaml.load(file_obj, Loader=yaml.FullLoader) """ Describe the API. """ app.config['SWAGGER'] = { @@ -73,7 +73,7 @@ def validate (self, request, component): """ Validate a request against the schema. """ if not self.specs: with open(schema_file_path, 'r') as file_obj: - self.specs = yaml.load(file_obj, Loader=yaml.FullLoader) #nosec B506 + self.specs = yaml.load(file_obj, Loader=yaml.FullLoader) to_validate = self.specs["components"]["schemas"][component] try: app.logger.debug (f"--:Validating obj {json.dumps(request.json, indent=2)}") @@ -268,4 +268,4 @@ def post(self): if args.debug: debug = True logging.basicConfig(level=logging.DEBUG) - app.run(host='0.0.0.0', port=args.port, threaded=True, debug=args.debug) #nosec B104 + app.run(host='0.0.0.0', port=args.port, threaded=True, debug=args.debug) diff --git a/tycho/client.py b/tycho/client.py index 3ad3aebf..95890d14 100644 --- a/tycho/client.py +++ b/tycho/client.py @@ -124,7 +124,7 @@ def request (self, service, request): :param request: JSON to send to the API endpoint. """ if os.environ.get("REST_API", "false") == "true": - response = requests.post (f"{self.url}/{service}", json=request) # nosec B113 + response = requests.post (f"{self.url}/{service}", json=request) result_text = f"HTTP status {response.status_code} received from service: {service}" logger.debug (f"TychoClient.request - {result_text}") if not response.status_code == 200: @@ -539,10 +539,9 @@ def getmetadata(self): if os.path.exists (env_file): with open (env_file, 'r') as stream: settings = stream.read () - # - # added SafeLoader type but not sure if unsafe load is needed. + with open(args.file, "r") as stream: - system = yaml.load (stream.read (), Loader=yaml.SafeLoader) + system = yaml.load (stream.read ()) else: """ Generate a docker-compose spec based on the CLI args. """ name = args.name diff --git a/tycho/dockerc.py b/tycho/dockerc.py index 07f18a19..c4889f94 100644 --- a/tycho/dockerc.py +++ b/tycho/dockerc.py @@ -47,7 +47,7 @@ def run (self): stream.write (env) """ Find and return ports for each container. """ - config = yaml.safe_load(TemplateUtils.apply_environment ( + config = yaml.load (TemplateUtils.apply_environment ( env, self.system.source_text)) logger.debug (f"Building conainer map for system {self.system.name}") diff --git a/tycho/kube.py b/tycho/kube.py index d0b20494..2595a4a7 100644 --- a/tycho/kube.py +++ b/tycho/kube.py @@ -277,11 +277,9 @@ def get_service_ip_address (self, service_metadata): exe = shutil.which ('kubectl') command = f"{exe} port-forward --pod-running-timeout=3m0s deployment/{app_id} {node_port}:{port}" logger.debug (f"-- port-forward: {command}") - # commented out July 18 2023 by Joshua Seals. Want to make sure this is not needed. - # shell=true was flagged as vulnerability by bandit. https://cwe.mitre.org/data/definitions/78.html - # process = subprocess.Popen (command, - # shell=True, - # stderr=subprocess.STDOUT) + process = subprocess.Popen (command, + shell=True, + stderr=subprocess.STDOUT) """ process dies when the other end disconnects so no need to clean up in delete. """ #ip_address = "127.0.0.1" except Exception as e: From e870ff2236c3e12efddce011c498c3ae772d6aa4 Mon Sep 17 00:00:00 2001 From: Joshua Seals Date: Fri, 11 Aug 2023 11:15:05 -0400 Subject: [PATCH 15/17] Security updates, docker version update, workflow tweaks for better dev experience --- .github/workflows/build-project.yml | 22 +--------------- .../workflows/{flake8.yml => code-checks.yml} | 25 ++++++++++++++++--- .github/workflows/pypi-dev-upload.yml | 10 +++++--- Dockerfile | 2 +- pyproject.toml | 4 +-- requirements.txt | 8 +++--- tycho/actions.py | 4 +-- tycho/api.py | 6 ++--- tycho/client.py | 6 ++--- tycho/dockerc.py | 2 +- 10 files changed, 44 insertions(+), 45 deletions(-) rename .github/workflows/{flake8.yml => code-checks.yml} (60%) diff --git a/.github/workflows/build-project.yml b/.github/workflows/build-project.yml index 2c38d9c4..7a4f157a 100644 --- a/.github/workflows/build-project.yml +++ b/.github/workflows/build-project.yml @@ -1,26 +1,6 @@ name: Build-Project run-name: Build-Project -on: - # Any push with exception to the below listed - # as they will be built in pypi-upload task. - push: - branches-ignore: - - master - - main - paths-ignore: - - README.md - - .old_cicd/* - - .github/* - - .github/workflows/* - - LICENSE - - .gitignore - - .dockerignore - - .githooks - tags-ignore: - - 'v[0-9]+.[0-9]+.*' - # We still test to ensure the build is successful - # for a 'potential PR' when opened. If additions to PR - # are pushed, we catch in the push section. +on: pull_request: branches: [ master, develop, main ] types: [ opened ] diff --git a/.github/workflows/flake8.yml b/.github/workflows/code-checks.yml similarity index 60% rename from .github/workflows/flake8.yml rename to .github/workflows/code-checks.yml index 0757bb98..f228fc9a 100644 --- a/.github/workflows/flake8.yml +++ b/.github/workflows/code-checks.yml @@ -25,13 +25,30 @@ jobs: uses: actions/setup-python@v4 with: python-version: '3.x' - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt + - name: Lint with flake8 run: | pip install flake8 flake8 --ignore=E,W --exit-zero . # We continue on error here until the code is clean continue-on-error: true + +############################ Bandit ################################ + bandit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.9' + + - name: Install Requirements + run: | + pip install --upgrade pip + pip install bandit + + # Only report high security issues + - name: Test with Bandit + run: | + bandit -r tycho/*.py -n 3 -lll \ No newline at end of file diff --git a/.github/workflows/pypi-dev-upload.yml b/.github/workflows/pypi-dev-upload.yml index 50965ca2..16f44496 100644 --- a/.github/workflows/pypi-dev-upload.yml +++ b/.github/workflows/pypi-dev-upload.yml @@ -1,9 +1,12 @@ +# This workflow will create an image for any tycho development taking place, not in master branch. +# We use the {{ github.ref_name }} ie branch name and date to ensure uniqueness of the package. name: upload-dev-pypi run-name: Package and Upload develop image to Pypi on: push: - branches: - - develop + branches-ignore: + - master + - main paths-ignore: - README.md - .old_cicd/* @@ -30,12 +33,11 @@ jobs: # Important, this does not change the current version of __init__.py in the # Github repo itself, only updates within container for the specific run. - # Each new push will trigger a dev build on develop. - - name: Edit __init__.py version for develop release run: | R_VERSION=$(grep VERSION ./tycho/__init__.py | awk '{ print $3 }' | tr -d '"') date=$(date '+%Y%m%d%H%M%S') + BRANCH=$(echo ${{ github.ref_name}} | sed 's/[_-]//g') DEV_VERSION=${R_VERSION}.dev${date} echo VERSION=\"$DEV_VERSION\" > ./tycho/__init__.py diff --git a/Dockerfile b/Dockerfile index 9ef31a79..26467ca4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.9.0-slim +FROM python:3.11.4-slim-bullseye RUN apt-get update && \ apt-get install -y build-essential libffi-dev libssl-dev git make diff --git a/pyproject.toml b/pyproject.toml index 4f64fa52..e9b05ee8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,6 @@ classifiers = [ ] dependencies = [ "deepmerge==1.0.1", - "docker_compose==1.29.2", "flasgger==0.9.5", "Flask==2.0.3", "flask_cors==3.0.10", @@ -34,7 +33,8 @@ dependencies = [ "kubernetes==25.3.0", "netifaces==0.11.0", "PyYAML==5.4.1", - "requests==2.27.1", + "requests==2.31.0", + "docker-compose==1.29.2", "requests_cache==0.9.2", ] dynamic = ["version"] diff --git a/requirements.txt b/requirements.txt index 0ccfb093..b827abc9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,11 +19,11 @@ certifi==2021.10.8 cffi==1.15.0 chardet==4.0.0 coverage==6.3.1 -cryptography==36.0.1 +cryptography==41.0.2 deepmerge==1.0.1 docker==5.0.3 -docker-compose==1.29.2 -docker-pycreds==0.4.0 +docker-compose==1.29.2 +docker-pycreds==0.4.0 dockerpty==0.4.1 docopt==0.6.2 flasgger==0.9.5 @@ -52,7 +52,7 @@ pytest-cov==3.0.0 pytest-mock==3.7.0 python-dateutil==2.8.2 pytz==2021.3 -requests==2.27.1 +requests==2.31.0 requests-cache==0.9.2 requests-oauthlib==1.3.1 rsa==4.8 diff --git a/tycho/actions.py b/tycho/actions.py index 08c0ac32..18a48081 100644 --- a/tycho/actions.py +++ b/tycho/actions.py @@ -25,7 +25,7 @@ 'api-schema.yaml') template = None with open(schema_file_path, 'r') as file_obj: - template = yaml.load(file_obj, Loader=yaml.FullLoader) + template = yaml.load(file_obj, Loader=yaml.FullLoader) #nosec B506 backplane = None _tycho = Tycho(backplane=backplane) @@ -45,7 +45,7 @@ def validate(self, request, component): """ Validate a request against the schema. """ if not self.specs: with open(schema_file_path, 'r') as file_obj: - self.specs = yaml.load(file_obj, Loader=yaml.FullLoader) + self.specs = yaml.load(file_obj, Loader=yaml.FullLoader) #nosec B506 to_validate = self.specs["components"]["schemas"][component] try: logger.debug(f"--:Validating obj {request}") diff --git a/tycho/api.py b/tycho/api.py index d8274914..317d52eb 100644 --- a/tycho/api.py +++ b/tycho/api.py @@ -38,7 +38,7 @@ 'api-schema.yaml') template = None with open(schema_file_path, 'r') as file_obj: - template = yaml.load(file_obj, Loader=yaml.FullLoader) + template = yaml.load(file_obj, Loader=yaml.FullLoader) #nosec B506 """ Describe the API. """ app.config['SWAGGER'] = { @@ -73,7 +73,7 @@ def validate (self, request, component): """ Validate a request against the schema. """ if not self.specs: with open(schema_file_path, 'r') as file_obj: - self.specs = yaml.load(file_obj, Loader=yaml.FullLoader) + self.specs = yaml.load(file_obj, Loader=yaml.FullLoader) #nosec B506 to_validate = self.specs["components"]["schemas"][component] try: app.logger.debug (f"--:Validating obj {json.dumps(request.json, indent=2)}") @@ -268,4 +268,4 @@ def post(self): if args.debug: debug = True logging.basicConfig(level=logging.DEBUG) - app.run(host='0.0.0.0', port=args.port, threaded=True, debug=args.debug) + app.run(host='0.0.0.0', port=args.port, threaded=True, debug=args.debug) #nosec B104 diff --git a/tycho/client.py b/tycho/client.py index 95890d14..2f0be331 100644 --- a/tycho/client.py +++ b/tycho/client.py @@ -124,7 +124,7 @@ def request (self, service, request): :param request: JSON to send to the API endpoint. """ if os.environ.get("REST_API", "false") == "true": - response = requests.post (f"{self.url}/{service}", json=request) + response = requests.post (f"{self.url}/{service}", json=request) #nosec B113 result_text = f"HTTP status {response.status_code} received from service: {service}" logger.debug (f"TychoClient.request - {result_text}") if not response.status_code == 200: @@ -539,9 +539,9 @@ def getmetadata(self): if os.path.exists (env_file): with open (env_file, 'r') as stream: settings = stream.read () - + # added safeloader here, per bandit instructions. with open(args.file, "r") as stream: - system = yaml.load (stream.read ()) + system = yaml.load (stream.read (), Loader=yaml.SafeLoader) else: """ Generate a docker-compose spec based on the CLI args. """ name = args.name diff --git a/tycho/dockerc.py b/tycho/dockerc.py index c4889f94..8f1d0812 100644 --- a/tycho/dockerc.py +++ b/tycho/dockerc.py @@ -47,7 +47,7 @@ def run (self): stream.write (env) """ Find and return ports for each container. """ - config = yaml.load (TemplateUtils.apply_environment ( + config = yaml.safe_load (TemplateUtils.apply_environment ( env, self.system.source_text)) logger.debug (f"Building conainer map for system {self.system.name}") From 5825f0f1ae80b31b84fa390231755de532e2bdf6 Mon Sep 17 00:00:00 2001 From: Joshua Seals Date: Fri, 11 Aug 2023 11:19:06 -0400 Subject: [PATCH 16/17] Removing one variable due to bandit flag --- tycho/kube.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tycho/kube.py b/tycho/kube.py index 2595a4a7..3a6791b8 100644 --- a/tycho/kube.py +++ b/tycho/kube.py @@ -277,9 +277,12 @@ def get_service_ip_address (self, service_metadata): exe = shutil.which ('kubectl') command = f"{exe} port-forward --pod-running-timeout=3m0s deployment/{app_id} {node_port}:{port}" logger.debug (f"-- port-forward: {command}") - process = subprocess.Popen (command, - shell=True, - stderr=subprocess.STDOUT) + # commented out due to bandit High Severity flag for this process. + # The variable 'process' was not accessed so this should not cause issue. + # Leaving for now just in case there are problems encountered. + # process = subprocess.Popen (command, + # shell=True, + # stderr=subprocess.STDOUT) """ process dies when the other end disconnects so no need to clean up in delete. """ #ip_address = "127.0.0.1" except Exception as e: From 69a3acfeaf0c3f886b89ce200121db503a7dc089 Mon Sep 17 00:00:00 2001 From: Joshua Seals Date: Fri, 11 Aug 2023 14:28:27 -0400 Subject: [PATCH 17/17] Adding dependabot.yml --- .github/dependabot.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..d1377896 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,25 @@ +# Note directory is relative to the root of the repo, with exception to github-actions ecosystem. +# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#directory +version: 2 +updates: + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + reviewers: + - "joshua-seals" + + - package-ecosystem: "pip" + directory: "/tycho" + schedule: + interval: "weekly" + reviewers: + - "joshua-seals" + - "Hoid" + - "waTeim" + - "pj-linebaugh" + - "ptlharit2" + - "frostyfan109" + - "cnbennett3" +