├── .gitignore ├── src ├── @orb_compatability_version.yml ├── executors │ └── default.yml ├── @orb.yml ├── examples │ └── run-tests-check-vulnerabilities.yml ├── jobs │ └── check-vulnerabilities.yml └── commands │ └── check-vulnerabilities.yml ├── README.md └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | orb.yml -------------------------------------------------------------------------------- /src/@orb_compatability_version.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 -------------------------------------------------------------------------------- /src/executors/default.yml: -------------------------------------------------------------------------------- 1 | description: > 2 | CircleCI's Python convenience image: 3 | https://hub.docker.com/r/circleci/python 4 | 5 | docker: 6 | - image: <>:<> 7 | 8 | parameters: 9 | image: 10 | description: The name of image 11 | default: circleci/python 12 | type: string 13 | tag: 14 | description: The image version tag 15 | default: 2.7.16-jessie-node-browsers-legacy 16 | type: string 17 | -------------------------------------------------------------------------------- /src/@orb.yml: -------------------------------------------------------------------------------- 1 | description: > 2 | Install and configure/use Contrast Security on CircleCI 3 | The Contrast agent begins securing your code by adding sensors to the entire software stack of your applications - from runtime to custom code - to directly measure vulnerabilities and attacks. Contrast Assess continuously monitors all your code, including your libraries, for known and unknown vulnerabilities, and produces accurate results without dependence on application security experts. 4 | 5 | display: 6 | source_url: https://github.com/Contrast-Security-OSS/contrast-security-orb 7 | home_url: https://contrastsecurity.com 8 | 9 | -------------------------------------------------------------------------------- /src/examples/run-tests-check-vulnerabilities.yml: -------------------------------------------------------------------------------- 1 | description: > 2 | Query the Contrast API to check if vulnerabilites have been found in this application. 3 | If vulnerabilites have been found above the set threshold, then fail the build. 4 | 5 | usage: 6 | version: 2.1 7 | 8 | orbs: 9 | contrastsecurity: contrastsecurity/verify@x.y.z 10 | 11 | jobs: 12 | contrast-verify: 13 | executor: contrastsecurity/default 14 | steps: 15 | - checkout 16 | 17 | - contrastsecurity/check-vulnerabilities: 18 | severities: CRITICAL,HIGH,MEDIUM 19 | org-id: (your org id) 20 | application-id: (your application id) 21 | contrast-url: https://app.contrastsecurity.com/Contrast 22 | 23 | workflows: 24 | test: 25 | jobs: 26 | - contrast-verify 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # contrast-security-orb 2 | 3 | Contrast Security Orb for CircleCI 4 | 5 | The Contrast agent begins securing your code by adding sensors to the entire software stack of your applications - from runtime to custom code - to directly measure vulnerabilities and attacks. Contrast Assess continuously monitors all your code, including your libraries, for known and unknown vulnerabilities, and produces accurate results without dependence on application security experts. 6 | 7 | ## Documentation 8 | 9 | https://circleci.com/orbs/registry/orb/contrastsecurity/verify 10 | 11 | ## Contributing 12 | 13 | We welcome [issues](https://github.com/Contrast-Security-OSS/contrast-security-orb/issues) to and [pull requests](https://github.com/Contrast-Security-OSS/contrast-security-orb/pulls) against this repository! 14 | 15 | For further questions/comments about this or other orbs, visit [CircleCI's orbs discussion forum](https://discuss.circleci.com/c/orbs). 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Contrast Security 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/jobs/check-vulnerabilities.yml: -------------------------------------------------------------------------------- 1 | description: > 2 | After running your tests, query the Contrast API to see if any new 3 | vulnerabilities were found in your build 4 | 5 | parameters: 6 | executor: 7 | type: executor 8 | default: default 9 | description: > 10 | Executor within which to run this job, defaults to this orb's own 11 | `default` executor. The given execution environment should have 12 | Python and pip preinstalled. 13 | 14 | python-path: 15 | type: string 16 | default: /usr/local/bin/python 17 | description: > 18 | Absolute path to an installed Python shell 19 | 20 | severities: 21 | type: string 22 | default: CRITICAL,HIGH,MEDIUM,LOW,NOTE 23 | description: > 24 | A comma-delimited list of serverities to use when filtering for vulnerabilities. 25 | 26 | application-id: 27 | type: string 28 | default: "" 29 | description: > 30 | ID of your application in Contrast 31 | 32 | username: 33 | type: env_var_name 34 | default: CONTRAST_USERNAME 35 | description: > 36 | Name of environment variable storing your Contrast username 37 | 38 | service-key: 39 | type: env_var_name 40 | default: CONTRAST_SERVICE_KEY 41 | description: > 42 | Name of environment variable storing your Contrast service key 43 | 44 | contrast-url: 45 | type: string 46 | default: https://app.contrastsecurity.com/Contrast 47 | description: > 48 | The Contrast url for your instance. The default is https://app.contrastsecurity.com/Contrast 49 | 50 | org-id: 51 | type: string 52 | default: "" 53 | description: > 54 | The organization id for your Contrast organization. This can be found on the "Your Account" page in the Contrast UI. 55 | 56 | api-key: 57 | type: env_var_name 58 | default: CONTRAST_API_KEY 59 | description: > 60 | Name of environment variable storing your Contrast API key 61 | 62 | vulnerability-threshold: 63 | type: integer 64 | default: 0 65 | description: > 66 | For what number or greater of open vulnerabilities would you like 67 | your build to fail? 68 | 69 | executor: <> 70 | 71 | steps: 72 | - check-vulnerabilities: 73 | python-path: <> 74 | severities: <> 75 | application-id: <> 76 | username: <> 77 | service-key: <> 78 | contrast-url: <> 79 | org-id: <> 80 | api-key: <> 81 | vulnerability-threshold: <> 82 | -------------------------------------------------------------------------------- /src/commands/check-vulnerabilities.yml: -------------------------------------------------------------------------------- 1 | description: > 2 | After running your tests, query the Contrast API to see if any new 3 | vulnerabilities were found in your build. Requirements: Python, pip 4 | 5 | parameters: 6 | python-path: 7 | type: string 8 | default: /usr/local/bin/python 9 | description: > 10 | Absolute path to an installed Python shell 11 | 12 | severities: 13 | type: string 14 | default: CRITICAL,HIGH,MEDIUM,LOW,NOTE 15 | description: > 16 | A comma-delimited list of serverities to use when filtering for vulnerabilities. 17 | 18 | application-id: 19 | type: string 20 | default: "" 21 | description: > 22 | ID of your application in Contrast 23 | 24 | username: 25 | type: env_var_name 26 | default: CONTRAST_USERNAME 27 | description: > 28 | Name of environment variable storing your Contrast username 29 | 30 | service-key: 31 | type: env_var_name 32 | default: CONTRAST_SERVICE_KEY 33 | description: > 34 | Name of environment variable storing your Contrast service key 35 | 36 | contrast-url: 37 | type: string 38 | default: https://app.contrastsecurity.com/Contrast 39 | description: > 40 | The Contrast url for your instance. The default is https://app.contrastsecurity.com/Contrast 41 | 42 | org-id: 43 | type: string 44 | default: "" 45 | description: > 46 | The organization id for your Contrast organization. This can be found on the "Your Account" page in the Contrast UI. 47 | 48 | api-key: 49 | type: env_var_name 50 | default: CONTRAST_API_KEY 51 | description: > 52 | Name of environment variable storing your Contrast API key 53 | 54 | vulnerability-threshold: 55 | type: integer 56 | default: 0 57 | description: > 58 | For what number or greater of open vulnerabilities would you like 59 | your build to fail? 60 | 61 | 62 | steps: 63 | - run: 64 | name: Check for Python presence 65 | command: | 66 | if [[ $EUID == 0 ]]; then export SUDO=""; else export SUDO="sudo"; fi 67 | 68 | $SUDO pip install requests 69 | 70 | - run: 71 | name: Install Python modules 72 | command: | 73 | if [[ $EUID == 0 ]]; then export SUDO=""; else export SUDO="sudo"; fi 74 | 75 | $SUDO pip install requests 76 | 77 | - run: 78 | name: Check Contrast for vulnerabilities 79 | shell: <> 80 | command: | 81 | import base64 82 | import datetime 83 | import json 84 | import requests 85 | import urllib 86 | import sys 87 | import os 88 | 89 | # Set the severities you are interested in 90 | SEVERITIES = os.path.expandvars("${<>}") 91 | 92 | headers = { 93 | 'Accept': 'application/json', 94 | 'API-Key': os.path.expandvars("${<>}"), 95 | 'Authorization': base64.b64encode(os.path.expandvars("${<>}:${<>}")) 96 | } 97 | 98 | # Contrast Security API request to get vulnerabilities 99 | url = "<>/api/ng/<>/traces/<>/quick?severities=<>" 100 | 101 | print ('HTTP GET ' + url) 102 | response = requests.get(url, headers = headers) 103 | 104 | # Check the status of the request 105 | if (not response.ok): 106 | print ('We could not contact Contrast. Please make sure contrast-url, application-id, org-id, and all credentials are correct') 107 | sys.exit(1) 108 | 109 | # Parse the JSON content 110 | json_data = json.loads(response.content) 111 | 112 | vulns_all = 0 113 | vulns_open = 0 114 | 115 | for filter in json_data['filters']: 116 | if (filter['name'] == 'All'): 117 | vulns_all = filter['count'] 118 | elif (filter['name'] == 'Open'): 119 | vulns_open = filter['count'] 120 | 121 | print ('All vulnerabilities: ' + str(vulns_all)) 122 | print ('Open vulnerabilities: ' + str(vulns_open)) 123 | 124 | # TODO Set the threshold for the number of vulnerabilities (of given severities) 125 | if (vulns_open > <>): 126 | print("Above the vulnerabilities threshold. Failing build.") 127 | sys.exit(1) 128 | 129 | --------------------------------------------------------------------------------