diff --git a/.github/workflows/secure.yml b/.github/workflows/secure.yml new file mode 100644 index 0000000..ec8b74d --- /dev/null +++ b/.github/workflows/secure.yml @@ -0,0 +1,64 @@ +name: Secure + +on: push + +jobs: + # Sample GitHub Actions: + # https://semgrep.dev/docs/semgrep-ci/sample-ci-configs#sample-github-actions-configuration-file + # + # CLI Reference: + # https://semgrep.dev/docs/cli-reference + semgrep: + runs-on: ubuntu-24.04 + container: + image: semgrep/semgrep + permissions: + contents: read + security-events: write + steps: + - uses: actions/checkout@v4 + - run: semgrep scan --sarif --output=semgrep.sarif --error --severity=WARNING + env: + SEMGREP_RULES: >- + p/bandit + p/command-injection + p/comment + p/cwe-top-25 + p/default + p/gitlab + p/gitlab-bandit + p/gitleaks + p/insecure-transport + p/owasp-top-ten + p/python + p/r2c-best-practices + p/r2c-bug-scan + p/r2c-security-audit + p/secrets + p/security-audit + p/xss + - uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: semgrep.sarif + if: always() + + # Samples GitHub Actions: + # https://github.com/aquasecurity/trivy-action + trivy: + runs-on: ubuntu-24.04 + permissions: + contents: read + security-events: write + steps: + - uses: actions/checkout@v4 + - uses: aquasecurity/trivy-action@master + with: + scan-type: 'fs' + format: 'sarif' + output: 'trivy.sarif' + exit-code: '1' + severity: 'MEDIUM,CRITICAL,HIGH' + - uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: trivy.sarif + if: always() diff --git a/.github/workflows/checks.yml b/.github/workflows/verify.yml similarity index 61% rename from .github/workflows/checks.yml rename to .github/workflows/verify.yml index 2aadcef..560b20e 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/verify.yml @@ -1,20 +1,23 @@ -name: Checks +name: Verify + on: push + jobs: flake8: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: '3.8' - run: pip install -r requirements.txt -r test-requirements.txt - run: flake8 . + pytest: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: '3.8' - run: pip install -r requirements.txt -r test-requirements.txt diff --git a/.semgrepignore b/.semgrepignore new file mode 100644 index 0000000..0c74f30 --- /dev/null +++ b/.semgrepignore @@ -0,0 +1,2 @@ +env.example.bat +env.example.sh diff --git a/selvpcclient/resources/tokens.py b/selvpcclient/resources/tokens.py index e2f50fa..79ad0e5 100644 --- a/selvpcclient/resources/tokens.py +++ b/selvpcclient/resources/tokens.py @@ -46,8 +46,6 @@ def delete_many(self, token_ids, raise_if_not_found=True): for token_id in token_ids: try: self.delete(token_id) - log.info("Token %s has been deleted", token_id) except ClientException as err: if raise_if_not_found: raise err - log.error("%s %s", err, token_id) diff --git a/selvpcclient/util.py b/selvpcclient/util.py index 66d6bf6..665d718 100644 --- a/selvpcclient/util.py +++ b/selvpcclient/util.py @@ -211,7 +211,7 @@ def make_curl(url, method, data): v = str() if value: v = value.encode('utf-8') - h = hashlib.sha1(v) + h = hashlib.sha256(v) d = h.hexdigest() value = "{SHA1}%s" % d header = ' -H "%s: %s"' % (key, value) @@ -225,15 +225,17 @@ def make_curl(url, method, data): def is_url(data): """Checks if getting value is valid url and path exists.""" try: - r = requests.head(data) - except Exception: + r = requests.head(data, timeout=15) + r.raise_for_status() + except requests.RequestException: return False return r.status_code == requests.codes.ok def process_logo_by_url(url): """Download and encode image by url.""" - res = requests.get(url) + res = requests.get(url, timeout=15) + res.raise_for_status() encoded_logo = base64.b64encode(res.content) return encoded_logo diff --git a/tests/cli/__init__.py b/tests/cli/__init__.py index 84e1d7f..30e164b 100644 --- a/tests/cli/__init__.py +++ b/tests/cli/__init__.py @@ -1,10 +1,12 @@ import json -import mock +from unittest import mock + from selvpcclient.client import Client from selvpcclient.shell import CLI +# nosemgrep: python.lang.best-practice.pass-body.pass-body-fn def prepare_to_run_command(cmd): pass diff --git a/tests/rest/__init__.py b/tests/rest/__init__.py index c29c337..9ea78a2 100644 --- a/tests/rest/__init__.py +++ b/tests/rest/__init__.py @@ -1,6 +1,5 @@ -import mock - from datetime import datetime, timedelta +from unittest import mock from selvpcclient.httpclient import HTTPClient, RegionalHTTPClient diff --git a/tests/test_util.py b/tests/test_util.py index 30e2a61..bb1d0bc 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -95,6 +95,7 @@ def function_that_takes_theme_params(logo=None, color=""): def test_process_theme_params_invalid_logo(): + # nosemgrep: python.lang.best-practice.pass-body.pass-body-fn @process_theme_params def function_that_takes_theme_params(logo=None, color=''): pass @@ -105,6 +106,7 @@ def function_that_takes_theme_params(logo=None, color=''): def test_process_theme_params_wrong_path(): + # nosemgrep: python.lang.best-practice.pass-body.pass-body-fn @process_theme_params def function_that_takes_theme_params(logo=None, color=''): pass