├── .gitignore ├── Dockerfile ├── LICENSE ├── README.rst ├── ansible ├── .gitignore ├── ansible.cfg ├── download-nvd.yml ├── install-maven.yml ├── install-tools.yml ├── inventories │ ├── inventory_dev │ ├── inventory_prod │ └── inventory_uninstalled ├── roles │ ├── docker │ │ ├── tasks │ │ │ ├── main.yml │ │ │ ├── start.yml │ │ │ └── stop.yml │ │ └── vars │ │ │ ├── docker.yml │ │ │ ├── main.yml │ │ │ └── service_endpoints.yml │ └── install │ │ ├── files │ │ ├── celery-connectors-pom.xml │ │ └── initial-pom.xml │ │ ├── tasks │ │ ├── build-depchecker.yml │ │ ├── build-nvd-dl.yml │ │ ├── clone-depchecker.yml │ │ ├── clone-nvd-dl.yml │ │ ├── install-maven.yml │ │ ├── pull-depchecker-updates.yml │ │ ├── pull-nvd-dl-updates.yml │ │ └── run-nvd-dl.yml │ │ └── vars │ │ └── jenkins-runtime-latest.yml ├── run-bandit-analysis.yml └── run-owasp-analysis.yml ├── build.sh ├── compose-owasp.yml ├── docker ├── bashrc ├── certs │ ├── jenkins_server_cert.pem │ └── jenkins_server_key.pem ├── configs │ └── .gitignore ├── data │ ├── .gitignore │ └── jenkins │ │ ├── .gitignore │ │ ├── cache │ │ └── .gitignore │ │ ├── lib │ │ ├── init.groovy.d │ │ │ └── basic-security.groovy │ │ └── jenkins.install.UpgradeWizard.state │ │ ├── ref │ │ └── plugins.txt │ │ └── secrets │ │ └── initialAdminPassword ├── env │ ├── owasp-dev.env │ └── owasp-test.env └── logs │ └── .gitignore ├── owasp_jenkins ├── __init__.py ├── log │ ├── __init__.py │ ├── build_logstash_formatter.py │ ├── logging.json │ └── setup_logging.py └── scripts │ └── start-container.sh ├── reports └── .gitignore ├── setup.cfg ├── setup.py ├── ssh.sh ├── start.sh ├── stop.sh ├── tests ├── __init__.py ├── base_test.py ├── manual_logstash_test.py └── test_functional.py └── tox.ini /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | .idea 3 | *.swp 4 | *.swo 5 | *.o 6 | *.pickle 7 | *.zlib 8 | *.gz 9 | *.tar 10 | *.doctree 11 | *.bin 12 | *.xgb 13 | *.retry 14 | *.tgz 15 | *.log 16 | build 17 | dist 18 | dump.rdb 19 | nohup.out 20 | venv 21 | py2venv 22 | py3venv 23 | owasp_jenkins.egg-info 24 | 25 | docker/data/tools 26 | docker/data/ansible 27 | docker/data/depchecker 28 | docker/data/nvd 29 | docker/data/persisted 30 | reports/*.html 31 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM jenkins/jenkins:latest 2 | 3 | USER root 4 | 5 | RUN apt-get update \ 6 | && apt-get -y upgrade 7 | 8 | RUN apt-get -y install \ 9 | build-essential \ 10 | software-properties-common \ 11 | git vim \ 12 | python \ 13 | python-dev \ 14 | python3 \ 15 | python3-dev \ 16 | python-setuptools \ 17 | python-virtualenv \ 18 | python-pip \ 19 | net-tools \ 20 | gcc \ 21 | vim \ 22 | openssl \ 23 | libssl-dev \ 24 | make \ 25 | cmake \ 26 | autoconf \ 27 | mono-runtime \ 28 | mono-devel \ 29 | libcurl4-openssl-dev \ 30 | libffi6 \ 31 | libffi-dev \ 32 | ruby \ 33 | curl \ 34 | php-cli \ 35 | php-mbstring \ 36 | unzip 37 | 38 | RUN curl -s https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer \ 39 | # https://jeremylong.github.io/DependencyCheck/analyzers/bundle-audit.html 40 | && gem install bundler-audit \ 41 | && bundle-audit update 42 | 43 | # Install ansible in the system's pips for jenkins 44 | # and in the virtual env for python3 45 | RUN mkdir -p -m 777 /opt/owasp \ 46 | && pip install --upgrade pip \ 47 | && pip install --upgrade setuptools \ 48 | && pip install --upgrade cryptography>=2.1.4 \ 49 | && pip install --upgrade ansible \ 50 | && virtualenv -p python3 /opt/owasp/venv \ 51 | && . /opt/owasp/venv/bin/activate \ 52 | && pip install --upgrade pip \ 53 | && pip install --upgrade setuptools \ 54 | && pip install --upgrade cryptography>=2.1.4 \ 55 | && pip install --upgrade ansible \ 56 | && pip list 57 | 58 | ENV PROJECT_NAME owasp 59 | ENV LOG_DIR /opt/logs 60 | ENV CONFIG_DIR /opt/logs 61 | ENV DATA_DIR /opt/logs 62 | ENV PATH="/opt/tools/apache-maven/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/bin:/sbin:/bin" 63 | ENV JAVA_OPTS="-Djenkins.install.runSetupWizard=false" 64 | 65 | RUN mkdir -p -m 777 /opt/owasp /opt/shared /opt/logs /opt/data /opt/configs /opt/nvd /opt/depchecker /opt/jenkins /opt/certs /opt/reports /opt/scanthisdir 66 | 67 | RUN /bin/echo "Installing Plugins" 68 | 69 | COPY ./docker/data/jenkins/ref/plugins.txt /usr/share/jenkins/ref/plugins.txt 70 | RUN /usr/local/bin/install-plugins.sh < /usr/share/jenkins/ref/plugins.txt 71 | 72 | WORKDIR /opt/owasp/ansible 73 | 74 | COPY ./ansible /opt/owasp/ansible 75 | 76 | RUN chmod 777 /opt/owasp/ansible \ 77 | && ls -l /opt/owasp/ansible 78 | 79 | RUN /bin/echo "Starting OWASP build" 80 | 81 | # default user is jenkins with home dir in /var/jenkins_home 82 | RUN /bin/echo 'PATH="/opt/tools/apache-maven/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/bin:/sbin:/bin"' >> /var/jenkins_home/.bashrc 83 | 84 | RUN /bin/echo "Installing Maven using Ansible" \ 85 | && . /opt/owasp/venv/bin/activate \ 86 | && cd /opt/owasp/ansible \ 87 | && ansible-playbook -i inventories/inventory_dev install-maven.yml -e install_maven=1 -vvvv 88 | 89 | RUN /bin/echo "Installing NIST National Vulnerability Database and NVD Dependency Checker using Ansible and Maven" \ 90 | && . /opt/owasp/venv/bin/activate \ 91 | && cd /opt/owasp/ansible \ 92 | && ansible-playbook -i inventories/inventory_dev install-tools.yml -e clone_depchecker=1 -e clone_nvd_dl=1 -vvvv 93 | 94 | RUN /bin/echo "Downloading NIST National Vulnerability Database file" \ 95 | && . /opt/owasp/venv/bin/activate \ 96 | && cd /opt/owasp/ansible \ 97 | && ansible-playbook -i inventories/inventory_dev download-nvd.yml -vvvv 98 | 99 | RUN /bin/echo "Generating National Vulnerability H2 Database for increasing OWASP analysis performance" \ 100 | && . /opt/owasp/venv/bin/activate \ 101 | && cd /opt/owasp/ansible \ 102 | && ansible-playbook -i inventories/inventory_dev run-owasp-analysis.yml -e rebuild_nvd=1 -e owasp_scan_dir="/opt/owasp/venv/bin" -vvvv 103 | 104 | RUN /bin/echo "Installing ZAP community scripts in: /opt/zapscripts" \ 105 | && git clone https://github.com/zaproxy/community-scripts.git /opt/zapscripts 106 | 107 | RUN /bin/echo "Installing Certs" 108 | 109 | COPY ./docker/bashrc /root/.bashrc 110 | ADD docker/certs /opt/certs 111 | 112 | RUN /bin/echo "Installing Python Utilities" 113 | 114 | COPY owasp-jenkins-latest.tgz /opt/owasp 115 | 116 | RUN cd /opt/owasp \ 117 | && tar xvf owasp-jenkins-latest.tgz \ 118 | && ls /opt/owasp 119 | 120 | RUN cd /opt/owasp \ 121 | && . /opt/owasp/venv/bin/activate \ 122 | && pip install -e . \ 123 | && pip list 124 | 125 | ENTRYPOINT /opt/owasp/owasp_jenkins/scripts/start-container.sh 126 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright [2018] [Jay Johnson] 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | OWASP Jenkins in Docker 2 | ======================= 3 | 4 | Want to automate testing your web applications and REST API service layers using the latest OWASP security toolchains and the NIST National Vulnerability Database (NVD)? 5 | 6 | This repository uses Ansible to create a docker container to hold an automatically-configured Jenkins application with the `OWASP Dependency Checker`_, `NIST NVD`_, `Python OWASP ZAP`_, and `Openstack Bandit`_ installed. All Jenkins jobs run inside this docker container and are hosted using self-signed ssl certificates. 7 | 8 | Hopefully this will make securing your applications easier by jumpstarting your testing with the `OWASP Top 10 Application Security Risks - 2017`_. 9 | 10 | .. _NIST NVD: https://nvd.nist.gov/vuln/data-feeds 11 | .. _OWASP Dependency Checker: https://github.com/jeremylong/DependencyCheck 12 | .. _OWASP Top 10 Application Security Risks - 2017: https://www.owasp.org/index.php/Top_10_2017-Top_10 13 | 14 | Quickly Analyze any Repository with OWASP 15 | ----------------------------------------- 16 | 17 | Here's how to scan a repository for security issues. This will download the latest https://hub.docker.com/r/jayjohnson/owasp-jenkins container. Please note: because there are so many known vulnerabilities to test, the container inflates to a size of about ``4.4 GB`` on disk. 18 | 19 | In this example I am testing the Bandit repository https://github.com/openstack/bandit.git and will create the ``owasp-report-.html`` file in the current directory before removing the container. 20 | 21 | #. Check there's nothing in the directory: 22 | 23 | :: 24 | 25 | ls | grep html 26 | 27 | #. Pick a Repository to Scan 28 | 29 | :: 30 | 31 | repo=https://github.com/openstack/bandit.git 32 | 33 | #. Run the OWASP Analysis and Generate the HTML Report 34 | 35 | :: 36 | 37 | docker run --name owasp-jenkins -p 8443:8443 -v $(pwd):/opt/reports -it -d jayjohnson/owasp-jenkins:latest && docker exec -it owasp-jenkins git clone $repo /opt/scanrepo && docker exec -it owasp-jenkins ansible-playbook -i inventories/inventory_dev run-owasp-analysis.yml -e owasp_scan_dir="/opt/scanrepo" -e owasp_report_file="/opt/reports/owasp-report-$(date +'%Y-%m-%d-%H-%M-%S').html" 38 | 39 | This will log something like below: 40 | 41 | :: 42 | 43 | d9d9c4e1945b7c0822f29aaae4db48842454ed693e1cc40d041f8362cd49cb12 44 | Cloning into '/opt/scanrepo'... 45 | remote: Counting objects: 5975, done. 46 | remote: Compressing objects: 100% (26/26), done. 47 | remote: Total 5975 (delta 5), reused 21 (delta 0), pack-reused 5949 48 | Receiving objects: 100% (5975/5975), 1.39 MiB | 0 bytes/s, done. 49 | Resolving deltas: 100% (4104/4104), done. 50 | [WARNING]: log file at /opt/owasp/ansible/"/tmp/owasp-jenkins.log" is not writeable and we cannot create it, aborting 51 | 52 | 53 | PLAY [Running OWASP Analysis] ************************************************** 54 | 55 | TASK [set_fact] **************************************************************** 56 | ok: [localhost] 57 | 58 | TASK [set_fact] **************************************************************** 59 | ok: [localhost] 60 | 61 | TASK [set_fact] **************************************************************** 62 | ok: [localhost] 63 | 64 | TASK [set_fact] **************************************************************** 65 | ok: [localhost] 66 | 67 | TASK [set_fact] **************************************************************** 68 | ok: [localhost] 69 | 70 | TASK [set_fact] **************************************************************** 71 | ok: [localhost] 72 | 73 | TASK [set_fact] **************************************************************** 74 | ok: [localhost] 75 | 76 | TASK [set_fact] **************************************************************** 77 | ok: [localhost] 78 | 79 | TASK [set_fact] **************************************************************** 80 | ok: [localhost] 81 | 82 | TASK [Checking if this is a rebuild_nvd=0] ************************************* 83 | skipping: [localhost] 84 | 85 | TASK [Building OWASP Arguments] ************************************************ 86 | ok: [localhost] 87 | 88 | TASK [Running OWASP Report depchecker=/opt/tools/depcheck/dependency-check-cli/target/release/bin/dependency-check.sh owasp_args= -n --enableExperimental true --out /opt/reports/owasp-report-2018-01-10-20-21-18.html --scan /opt/scanrepo -P /opt/owasp/ansible/roles/install/files/initial-pom.xml --project analyze-this-code --data /opt/nvd] *** 89 | changed: [localhost] 90 | 91 | TASK [Checking if the OWASP Report=/opt/reports/owasp-report-2018-01-10-20-21-18.html exists] *** 92 | ok: [localhost] 93 | 94 | TASK [Verifying OWASP Report=/opt/reports/owasp-report-2018-01-10-20-21-18.html was created] *** 95 | skipping: [localhost] 96 | 97 | PLAY RECAP ********************************************************************* 98 | localhost : ok=12 changed=1 unreachable=0 failed=0 99 | 100 | #. Verify the OWASP HTML Report Exists 101 | 102 | :: 103 | 104 | ls | grep html 105 | owasp-report-2018-01-10-20-21-18.html 106 | 107 | #. Cleanup the Docker Container 108 | 109 | :: 110 | 111 | docker stop owasp-jenkins; docker rm owasp-jenkins 112 | owasp-jenkins 113 | owasp-jenkins 114 | 115 | Analyzing Popular GitHub Repositories 116 | ===================================== 117 | 118 | I hope this container makes it easy to find security risks in your code and in any third-party dependencies. Here's examples for analyzing some of the most popular GitHub repositories: 119 | 120 | Scan Django 121 | ----------- 122 | 123 | Scan Django and generate an OWASP HTML Report for third-party vulnerabilities: 124 | 125 | :: 126 | 127 | repo=https://github.com/django/django.git 128 | docker run --name owasp-jenkins -p 8443:8443 -v $(pwd):/opt/reports -it -d jayjohnson/owasp-jenkins:latest && docker exec -it owasp-jenkins git clone $repo /opt/scanrepo && docker exec -it owasp-jenkins ansible-playbook -i inventories/inventory_dev run-owasp-analysis.yml -e owasp_scan_dir="/opt/scanrepo" -e owasp_report_file="/opt/reports/owasp-django-report-$(date +'%Y-%m-%d-%H-%M-%S').html" && docker stop owasp-jenkins && docker rm owasp-jenkins 129 | ls -l owasp-django-report-*.html 130 | 131 | Scan React 132 | ---------- 133 | 134 | Scan React and generate an OWASP HTML Report for third-party vulnerabilities: 135 | 136 | :: 137 | 138 | repo=https://github.com/facebook/react.git 139 | docker run --name owasp-jenkins -p 8443:8443 -v $(pwd):/opt/reports -it -d jayjohnson/owasp-jenkins:latest && docker exec -it owasp-jenkins git clone $repo /opt/scanrepo && docker exec -it owasp-jenkins ansible-playbook -i inventories/inventory_dev run-owasp-analysis.yml -e owasp_scan_dir="/opt/scanrepo" -e owasp_report_file="/opt/reports/owasp-react-report-$(date +'%Y-%m-%d-%H-%M-%S').html" && docker stop owasp-jenkins && docker rm owasp-jenkins 140 | ls -l owasp-react-report-*.html 141 | 142 | Scan Vue 143 | -------- 144 | 145 | Scan Vue and generate an OWASP HTML Report for third-party vulnerabilities: 146 | 147 | :: 148 | 149 | repo=https://github.com/vuejs/vue.git 150 | docker run --name owasp-jenkins -p 8443:8443 -v $(pwd):/opt/reports -it -d jayjohnson/owasp-jenkins:latest && docker exec -it owasp-jenkins git clone $repo /opt/scanrepo && docker exec -it owasp-jenkins ansible-playbook -i inventories/inventory_dev run-owasp-analysis.yml -e owasp_scan_dir="/opt/scanrepo" -e owasp_report_file="/opt/reports/owasp-vue-report-$(date +'%Y-%m-%d-%H-%M-%S').html" && docker stop owasp-jenkins && docker rm owasp-jenkins 151 | ls -l owasp-vue-report-*.html 152 | 153 | Scan Angular 154 | ------------ 155 | 156 | Scan Angular and generate an OWASP HTML Report for third-party vulnerabilities: 157 | 158 | :: 159 | 160 | repo=https://github.com/angular/angular.git 161 | docker run --name owasp-jenkins -p 8443:8443 -v $(pwd):/opt/reports -it -d jayjohnson/owasp-jenkins:latest && docker exec -it owasp-jenkins git clone $repo /opt/scanrepo && docker exec -it owasp-jenkins ansible-playbook -i inventories/inventory_dev run-owasp-analysis.yml -e owasp_scan_dir="/opt/scanrepo" -e owasp_report_file="/opt/reports/owasp-angular-report-$(date +'%Y-%m-%d-%H-%M-%S').html" && docker stop owasp-jenkins && docker rm owasp-jenkins 162 | ls -l owasp-angular-report-*.html 163 | 164 | Scan Ruby on Rails 165 | ------------------ 166 | 167 | Scan Ruby on Rails and generate an OWASP HTML Report for third-party vulnerabilities: 168 | 169 | :: 170 | 171 | repo=https://github.com/rails/rails 172 | docker run --name owasp-jenkins -p 8443:8443 -v $(pwd):/opt/reports -it -d jayjohnson/owasp-jenkins:latest && docker exec -it owasp-jenkins git clone $repo /opt/scanrepo && docker exec -it owasp-jenkins ansible-playbook -i inventories/inventory_dev run-owasp-analysis.yml -e owasp_scan_dir="/opt/scanrepo" -e owasp_report_file="/opt/reports/owasp-ror-report-$(date +'%Y-%m-%d-%H-%M-%S').html" && docker stop owasp-jenkins && docker rm owasp-jenkins 173 | ls -l owasp-ror-report-*.html 174 | 175 | Scan Shadowsocks Windows 176 | ------------------------ 177 | 178 | Scan Shadowsocks Windows and generate an OWASP HTML Report for third-party vulnerabilities: 179 | 180 | :: 181 | 182 | repo=https://github.com/shadowsocks/shadowsocks-windows.git 183 | docker run --name owasp-jenkins -p 8443:8443 -v $(pwd):/opt/reports -it -d jayjohnson/owasp-jenkins:latest && docker exec -it owasp-jenkins git clone $repo /opt/scanrepo && docker exec -it owasp-jenkins ansible-playbook -i inventories/inventory_dev run-owasp-analysis.yml -e owasp_scan_dir="/opt/scanrepo" -e owasp_report_file="/opt/reports/owasp-shadowsockswindows-report-$(date +'%Y-%m-%d-%H-%M-%S').html" && docker stop owasp-jenkins && docker rm owasp-jenkins 184 | ls -l owasp-shadowsockswindows-report-*.html 185 | 186 | Scan Laravel 187 | ------------ 188 | 189 | Scan Laravel and generate an OWASP HTML Report for third-party vulnerabilities: 190 | 191 | :: 192 | 193 | repo=https://github.com/laravel/laravel 194 | docker run --name owasp-jenkins -p 8443:8443 -v $(pwd):/opt/reports -it -d jayjohnson/owasp-jenkins:latest && docker exec -it owasp-jenkins git clone $repo /opt/scanrepo && docker exec -it owasp-jenkins ansible-playbook -i inventories/inventory_dev run-owasp-analysis.yml -e owasp_scan_dir="/opt/scanrepo" -e owasp_report_file="/opt/reports/owasp-laravel-report-$(date +'%Y-%m-%d-%H-%M-%S').html" && docker stop owasp-jenkins && docker rm owasp-jenkins 195 | ls -l owasp-laravel-report-*.html 196 | 197 | Scan Django REST Framework 198 | -------------------------- 199 | 200 | Scan Django REST Framework and generate an OWASP HTML Report for third-party vulnerabilities: 201 | 202 | :: 203 | 204 | repo=https://github.com/encode/django-rest-framework.git 205 | docker run --name owasp-jenkins -p 8443:8443 -v $(pwd):/opt/reports -it -d jayjohnson/owasp-jenkins:latest && docker exec -it owasp-jenkins git clone $repo /opt/scanrepo && docker exec -it owasp-jenkins ansible-playbook -i inventories/inventory_dev run-owasp-analysis.yml -e owasp_scan_dir="/opt/scanrepo" -e owasp_report_file="/opt/reports/owasp-drf-report-$(date +'%Y-%m-%d-%H-%M-%S').html" && docker stop owasp-jenkins && docker rm owasp-jenkins 206 | ls -l owasp-drf-report-*.html 207 | 208 | Want to generate Bandit reports for some of the most popular python projects? 209 | ----------------------------------------------------------------------------- 210 | 211 | Scan Tensorflow and generate a Bandit HTML report (this can take a few minutes depending on your host): 212 | 213 | :: 214 | 215 | repo=https://github.com/tensorflow/tensorflow.git 216 | docker run --name owasp-jenkins -p 8443:8443 -v $(pwd):/opt/reports -it -d jayjohnson/owasp-jenkins:latest && docker exec -it owasp-jenkins git clone $repo /opt/scanrepo && docker exec -it owasp-jenkins ansible-playbook -i inventories/inventory_dev run-bandit-analysis.yml -e bandit_scan_dir="/opt/scanrepo" -e bandit_report_file="/opt/reports/bandit-tf-report-$(date +'%Y-%m-%d-%H-%M-%S').html" && docker stop owasp-jenkins && docker rm owasp-jenkins 217 | ls -l bandit-tf-report-*.html 218 | 219 | Scan Flask and generate a Bandit HTML report: 220 | 221 | :: 222 | 223 | repo=https://github.com/pallets/flask.git 224 | docker run --name owasp-jenkins -p 8443:8443 -v $(pwd):/opt/reports -it -d jayjohnson/owasp-jenkins:latest && docker exec -it owasp-jenkins git clone $repo /opt/scanrepo && docker exec -it owasp-jenkins ansible-playbook -i inventories/inventory_dev run-bandit-analysis.yml -e bandit_scan_dir="/opt/scanrepo" -e bandit_report_file="/opt/reports/bandit-flask-report-$(date +'%Y-%m-%d-%H-%M-%S').html" && docker stop owasp-jenkins && docker rm owasp-jenkins 225 | ls -l bandit-flask-report-*.html 226 | 227 | Scan Ansible and generate a Bandit HTML report (this can take a few minutes depending on your host): 228 | 229 | :: 230 | 231 | repo=https://github.com/ansible/ansible.git 232 | docker run --name owasp-jenkins -p 8443:8443 -v $(pwd):/opt/reports -it -d jayjohnson/owasp-jenkins:latest && docker exec -it owasp-jenkins git clone $repo /opt/scanrepo && docker exec -it owasp-jenkins ansible-playbook -i inventories/inventory_dev run-bandit-analysis.yml -e bandit_scan_dir="/opt/scanrepo" -e bandit_report_file="/opt/reports/bandit-ab-report-$(date +'%Y-%m-%d-%H-%M-%S').html" && docker stop owasp-jenkins && docker rm owasp-jenkins 233 | ls -l bandit-ab-report-*.html 234 | 235 | Setting up Jenkins for Automating your Security Testing 236 | ======================================================= 237 | 238 | Start the Container 239 | ------------------- 240 | 241 | If you want to set up the Jenkins container or onboard an application with OWASP testing you can start the container with: 242 | 243 | :: 244 | 245 | ./start.sh 246 | 247 | Login to Jenkins 248 | ---------------- 249 | 250 | The login for the Jenkins instance is: 251 | 252 | - username: admin 253 | - password: testing 254 | 255 | https://localhost:8443/ 256 | 257 | Running the OWASP Tools Manually 258 | ================================ 259 | 260 | I find it easier to initially integrate my applications with the OWASP + NIST toolchains by manually running tests from inside the container without a Jenkins job to debug at the same time. 261 | 262 | SSH into the container with: 263 | 264 | :: 265 | 266 | docker exec -it owasp-jenkins bash 267 | 268 | or from the base repository directory: 269 | 270 | :: 271 | 272 | ./ssh.sh 273 | 274 | Confirm you're in the ansible directory: 275 | 276 | :: 277 | 278 | pwd 279 | /opt/owasp/ansible 280 | 281 | Run OWASP Analysis and Generate an HTML Report 282 | ---------------------------------------------- 283 | 284 | This command will analyze the repository's ``/opt/owasp/owasp_jenkins/log/*.py`` modules using verbose Ansible terminal output. This is helpful for figuring out what Ansible is doing under the hood. By default the Ansible playbook will create the OWASP html file inside the docker container directory: ``/opt/reports``. This directory is set up in the compose file to auto-mount to the host's directory ``./reports`` from the repository to make sharing and viewing these html reports easier. 285 | 286 | :: 287 | 288 | ansible-playbook -i inventories/inventory_dev run-owasp-analysis.yml -e owasp_scan_dir="/opt/owasp/owasp_jenkins/log" -e owasp_report_file="/opt/reports/owasp-report.html" -vvvv 289 | 290 | Run Bandit Analysis and Generate an HTML Report 291 | ----------------------------------------------- 292 | 293 | This will analyze the Bandit project's own code with the bandit analyzer and generate an html report that will be stored on the host in the ``./reports`` directory. 294 | 295 | :: 296 | 297 | ansible-playbook -i inventories/inventory_dev run-bandit-analysis.yml -e bandit_scan_dir="/opt/owasp/venv/lib/python3.5/site-packages/bandit" -e bandit_report_file="/opt/reports/bandit-report.html" -vvvv 298 | 299 | Onboarding Your Own Application with OWASP 300 | ------------------------------------------ 301 | 302 | The Ansible playbook configures the `Dependency Checker parameters`_ for making onboarding easier even behind a corporate proxy. These are the general steps I run through to get an application automatically scanned within a Jenkins job. 303 | 304 | .. _Dependency Checker parameters: https://github.com/jay-johnson/owasp-jenkins/blob/master/ansible/run-owasp-analysis.yml#L23-L31 305 | 306 | #. Changing the Runtime Parameters 307 | 308 | Please checkout what can be overridden from the ansible-playbook cli using the ``-e =""`` and then port them into your Jenkins build jobs. 309 | 310 | https://github.com/jay-johnson/owasp-jenkins/blob/master/ansible/roles/install/vars/jenkins-runtime-latest.yml 311 | 312 | #. Tuning OWASP Runtime Arguments 313 | 314 | The Dependency Checker supports numerous parameters to test and audit an application. I would recommend periodically reviewing what has changed to make sure you are using the right ones for each application: 315 | 316 | https://jeremylong.github.io/DependencyCheck/dependency-check-maven/configuration.html 317 | 318 | This repository was built to analyze python, but the `default pom.xml file`_ is set up with most of the available `language analyzers`_ enabled (node.js, java, .NET, ruby, php) and uses the default flag: ``owasp_analyzers="--enableExperimental true"`` 319 | 320 | .. _default pom.xml file: https://github.com/jay-johnson/owasp-jenkins/blob/master/ansible/roles/install/files/initial-pom.xml 321 | .. _language analyzers: https://jeremylong.github.io/DependencyCheck/analyzers/index.html 322 | 323 | #. Setting up an OWASP pom.xml file 324 | 325 | There are two sample ``pom.xml`` files in the repo. One is for testing with my `celery-connectors`_ repository and the other is the default. 326 | 327 | - https://github.com/jay-johnson/owasp-jenkins/blob/master/ansible/roles/install/files/initial-pom.xml 328 | - https://github.com/jay-johnson/owasp-jenkins/blob/master/ansible/roles/install/files/celery-connectors-pom.xml 329 | 330 | There are numerous different configurable options that each application should review to ensure they are testing their code accordingly. 331 | 332 | https://jeremylong.github.io/DependencyCheck/dependency-check-maven/index.html 333 | 334 | Once you have a ``pom.xml`` ready for testing you can use it with the ``run-owasp-analysis.yml`` by adding the arguments: 335 | 336 | ``-e owasp_pom=""`` 337 | 338 | .. _celery-connectors: https://github.com/jay-johnson/celery-connectors 339 | 340 | #. Set up OWASP Jenkins Jobs 341 | 342 | I prefer to set up my Jenkins jobs using the ``Execute shell - Command`` to configure my security toolchains in my CI/CD pipelines. These are the shell snippets for how I set up my initial OWASP jobs for a new security-ready CI/CD pipeline. 343 | 344 | #. NIST National Vulnerability Database Update Job 345 | 346 | This job should run every seven days to pull in the latest updates or you can just rebuild this container (just a friendly reminder, don't forget to back up or migrate your jobs): 347 | 348 | https://jeremylong.github.io/DependencyCheck/data/index.html 349 | 350 | :: 351 | 352 | echo "Downloading NIST National Vulnerability Database file" 353 | . /opt/owasp/venv/bin/activate 354 | cd /opt/owasp/ansible 355 | ansible-playbook -i inventories/inventory_dev download-nvd.yml -vvvv 356 | 357 | #. Run OWASP and Bandit Analysis on any new repo PR or merged-PR Job 358 | 359 | I usually assume the Jenkins job has ``WORKSPACE`` as the directory for the source code to check. I also try to automate email delivery by making sure the auto-generated html files are under the job's workspace to ensure the job can send an email with the files attached for review. 360 | 361 | :: 362 | 363 | echo "Running OWASP Analysis on Workspace=${WORKSPACE}" 364 | . /opt/owasp/venv/bin/activate 365 | cd /opt/owasp/ansible 366 | 367 | # If needed, make sure to specify the path to the repository's pom.xml: 368 | # -e owasp_pom="/opt/owasp/ansible/roles/install/files/initial-pom.xml" 369 | # and set the project label to match it: 370 | # -e owasp_project_label="analyze-this-code" 371 | ansible-playbook -i inventories/inventory_dev run-owasp-analysis.yml -e owasp_scan_dir="${WORKSPACE}" -e owasp_report_file="${WORKSPACE}/owasp-report.html" -vvvv 372 | 373 | echo "Running Bandit Analysis on Workspace=${WORKSPACE}" 374 | ansible-playbook -i inventories/inventory_dev run-bandit-analysis.yml -e bandit_scan_dir="${WORKSPACE}" -e bandit_report_file="${WORKSPACE}/bandit-report.html" -vvvv 375 | 376 | #. Update NIST Downloader and Dependency Checker Tools Job 377 | 378 | This job will update the local, cloned repositories for the NIST NVD Downloader and Dependency Checker. This is helpful if you have to maintain an internal fork of these repositories for enhancing or modifying their testing. 379 | 380 | :: 381 | 382 | echo "Installing NIST National Vulnerability Database and NVD Dependency Checker using Ansible and Maven" 383 | . /opt/owasp/venv/bin/activate 384 | cd /opt/owasp/ansible 385 | ansible-playbook -i inventories/inventory_dev install-tools.yml -vvvv 386 | 387 | Build the OWASP Jenkins Container 388 | --------------------------------- 389 | 390 | This will build a large docker container (derived from ``jenkins/jenkins:latest``) by installing the following security packages listed below. If you want to install these later after the build you can run the Ansible playbooks as needed by commenting out the install lines of the Dockerfile (https://github.com/jay-johnson/owasp-jenkins/blob/master/Dockerfile#L84-L102). 391 | 392 | Build the container using this script in the base directory of the repository: 393 | 394 | :: 395 | 396 | ./build.sh 397 | 398 | While you're waiting, here's what is installing inside the container: 399 | 400 | - `OWASP Website`_ 401 | - `NVD Data Feeds`_ 402 | - `Dependency Checker`_ 403 | - `Openstack Bandit`_ 404 | - `Python OWASP ZAP`_ 405 | - `Python OWASP ZAP Community Scripts`_ 406 | 407 | .. _OWASP Website: https://www.owasp.org/index.php/Main_Page 408 | .. _NVD Data Feeds: https://nvd.nist.gov/vuln/data-feeds 409 | .. _Dependency Checker: https://github.com/jeremylong/DependencyCheck 410 | .. _Openstack Bandit: https://github.com/openstack/bandit 411 | .. _Python OWASP ZAP: https://github.com/zaproxy/zap-api-python 412 | .. _Python OWASP ZAP Community Scripts: https://github.com/zaproxy/community-scripts 413 | 414 | Container OWASP Coverage Analysis 415 | ================================= 416 | 417 | So how does this container and approach help cover applications for the `2017 OWASP Top 10 Application Security Risks`_? 418 | 419 | The container was built to help quickly secure python application code with Bandit for `Static Application Security Testing (SAST)`_ and ZAP for `Dynamic Application Security Testing (DAST)`_. There's tradeoffs to adding more and more tools to cover each item because while the tools might help find more security risks the tradeoff is your team just added more testing overhead to support tools and keep them updated with your application builds. 420 | 421 | This is a table to visualize how the container helps tests the OWASP Top 10: 422 | 423 | +---------------------------------------------------+-------+--------+------------------+ 424 | | OWASP Top 10 Application Security Risks - 2017 | DAST_ + SAST_ + Third Party | 425 | +===================================================+=======+========+==================+ 426 | | `A1 Injection`_ | ZAP | Bandit | Dependency Check | 427 | +---------------------------------------------------+-------+--------+------------------+ 428 | | `A2 Broken Authentication`_ | ZAP | Bandit | Dependency Check | 429 | +---------------------------------------------------+-------+--------+------------------+ 430 | | `A3 Sensitive Data Exposure`_ | ZAP | Bandit | Dependency Check | 431 | +---------------------------------------------------+-------+--------+------------------+ 432 | | `A4 XML External Entities`_ | ZAP | Bandit | Dependency Check | 433 | +---------------------------------------------------+-------+--------+------------------+ 434 | | `A5 Broken Access Control`_ | ZAP | Bandit | Dependency Check | 435 | +---------------------------------------------------+-------+--------+------------------+ 436 | | `A6 Security Misconfiguration`_ | ZAP | Bandit | Dependency Check | 437 | +---------------------------------------------------+-------+--------+------------------+ 438 | | `A7 Cross Site Scripting`_ | ZAP | Bandit | Dependency Check | 439 | +---------------------------------------------------+-------+--------+------------------+ 440 | | `A8 Insecure Deserialization`_ | None | Bandit | Dependency Check | 441 | +---------------------------------------------------+-------+--------+------------------+ 442 | | `A9 Using Components with Known Vulnerabilities`_ | ZAP | None | Dependency Check | 443 | +---------------------------------------------------+-------+--------+------------------+ 444 | | `A10 Insufficient Logging and Monitoring`_ | None | None | None | 445 | +---------------------------------------------------+-------+--------+------------------+ 446 | 447 | .. _2017 OWASP Top 10 Application Security Risks: https://www.owasp.org/index.php/Top_10-2017_Top_10 448 | .. _Static Application Security Testing (SAST): https://www.owasp.org/index.php/Source_Code_Analysis_Tools 449 | .. _Dynamic Application Security Testing (DAST): https://www.owasp.org/index.php/Category:Vulnerability_Scanning_Tools 450 | .. _SAST: https://www.owasp.org/index.php/Source_Code_Analysis_Tools 451 | .. _DAST: https://www.owasp.org/index.php/Category:Vulnerability_Scanning_Tools 452 | .. _A1 Injection: https://www.owasp.org/index.php/Top_10-2017_A1-Injection 453 | .. _A2 Broken Authentication: https://www.owasp.org/index.php/Top_10-2017_A2-Broken_Authentication 454 | .. _A3 Sensitive Data Exposure: https://www.owasp.org/index.php/Top_10-2017_A3-Sensitive_Data_Exposure 455 | .. _A4 XML External Entities: https://www.owasp.org/index.php/Top_10-2017_A4-XML_External_Entities_(XXE) 456 | .. _A5 Broken Access Control: https://www.owasp.org/index.php/Top_10-2017_A5-Broken_Access_Control 457 | .. _A6 Security Misconfiguration: https://www.owasp.org/index.php/Top_10-2017_A6-Security_Misconfiguration 458 | .. _A7 Cross Site Scripting: https://www.owasp.org/index.php/Top_10-2017_A7-Cross-Site_Scripting_(XSS) 459 | .. _A8 Insecure Deserialization: https://www.owasp.org/index.php/Top_10-2017_A8-Insecure_Deserialization 460 | .. _A9 Using Components with Known Vulnerabilities: https://www.owasp.org/index.php/Top_10-2017_A9-Using_Components_with_Known_Vulnerabilities 461 | .. _A10 Insufficient Logging and Monitoring: https://www.owasp.org/index.php/Top_10-2017_A10-Insufficient_Logging%26Monitoring 462 | 463 | Force a Rebuild of the NVD H2 files using the Dependency Checker 464 | ---------------------------------------------------------------- 465 | 466 | If you want to manually download the latest NVD updates you can run the included Ansible playbook from inside the container. This can take a while if you're behind a proxy so I usually have a dedicated Jenkins job that handles updating the h2 database during off hours. 467 | 468 | :: 469 | 470 | ansible-playbook -i inventories/inventory_dev run-owasp-analysis.yml -e rebuild_nvd=1 -e owasp_scan_dir="/opt/owasp/owasp_jenkins/log" -vvvv 471 | 472 | Cleaning up Everything on the Host before a Clean Rebuild 473 | --------------------------------------------------------- 474 | 475 | Please be careful. This command will delete all the downloaded NIST NVD data files, maven, and the Dependency Checker tool if you have host-mounted them and commented-out the ansible-playbook install steps in the Docker container. 476 | 477 | :: 478 | 479 | sudo rm -rf ./docker/data/nvd/* ./docker/data/nvd/.git ./docker/data/tools/nvd/* ./docker/data/tools/nvd/.git ./docker/data/tools/depcheck/* ./docker/data/tools/depcheck/.git ./docker/data/tools/* 480 | 481 | Setting up a Development Environment 482 | ------------------------------------ 483 | 484 | Setup the virtual environment with the command: 485 | 486 | :: 487 | 488 | virtualenv -p python3 venv && source venv/bin/activate && pip install -e . 489 | 490 | Linting 491 | ------- 492 | 493 | :: 494 | 495 | pycodestyle --max-line-length=160 --exclude=venv,build,.tox 496 | 497 | License 498 | ------- 499 | 500 | Apache 2.0 - Please refer to the LICENSE_ for more details 501 | 502 | .. _License: https://github.com/jay-johnson/owasp-jenkins/blob/master/LICENSE 503 | 504 | -------------------------------------------------------------------------------- /ansible/.gitignore: -------------------------------------------------------------------------------- 1 | nohup.out 2 | -------------------------------------------------------------------------------- /ansible/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | ask_pass=False 3 | host_key_checking=False 4 | display_skipped_hosts=True 5 | retry_files_save_path=/tmp 6 | transport=paramiko 7 | log_path="/tmp/owasp-jenkins.log" 8 | [ssh_connection] 9 | pipelining = True 10 | control_path = /tmp/owasp-jenkins-ssh-%%h-%%p-%%r 11 | -------------------------------------------------------------------------------- /ansible/download-nvd.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Downloading the latest NIST National Vulnerability Database files" 3 | gather_facts: no 4 | connection: local 5 | hosts: localhost 6 | 7 | vars_files: 8 | - ./roles/install/vars/jenkins-runtime-latest.yml 9 | 10 | environment: 11 | JENKINS_HOME: /var/jenkins_home 12 | M2_HOME: "{{m2_home}}" 13 | M2: "{{m2}}" 14 | PATH: "{{m2}}:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/bin:/sbin:/bin:${PATH}" 15 | 16 | pre_tasks: 17 | - set_fact: nist_dl_data_dir="/opt/nvd" 18 | - set_fact: nist_dl_proxy_params="" 19 | - set_fact: nist_dl_args="" 20 | 21 | tasks: 22 | 23 | - name: "Building NIST NVD Downloader Arguments" 24 | connection: local 25 | set_fact: nist_dl_args="{{nist_dl_proxy_params}} -jar {{nist_dl}} {{nist_dl_data_dir}}" 26 | 27 | - name: "Running NIST NVD Downloader jar={{nist_dl}} args={{nist_dl_args}} saving to dir={{nist_dl_data_dir}}" 28 | connection: local 29 | shell: "cd {{nist_dl_dir}} && unset JAVA_TOOL_OPTIONS && java {{nist_dl_args}}" 30 | -------------------------------------------------------------------------------- /ansible/install-maven.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Install Maven" 3 | gather_facts: no 4 | connection: local 5 | hosts: localhost 6 | 7 | vars_files: 8 | - ./roles/install/vars/jenkins-runtime-latest.yml 9 | 10 | environment: 11 | JENKINS_HOME: /var/jenkins_home 12 | M2_HOME: "{{m2_home}}" 13 | M2: "{{m2}}" 14 | PATH: "{{m2}}:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/bin:/sbin:/bin:${PATH}" 15 | 16 | pre_tasks: 17 | - set_fact: install_maven="1" 18 | - set_fact: update_maven="0" 19 | 20 | tasks: 21 | 22 | - name: Checking java 23 | connection: local 24 | shell: which java && java -version 25 | 26 | - name: Installing Maven 27 | connection: local 28 | include_tasks: ./roles/install/tasks/install-maven.yml 29 | when: install_maven == "1" 30 | -------------------------------------------------------------------------------- /ansible/install-tools.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Installing Dependency Checker and NIST Downloader" 3 | gather_facts: no 4 | connection: local 5 | hosts: localhost 6 | 7 | vars_files: 8 | - ./roles/install/vars/jenkins-runtime-latest.yml 9 | 10 | environment: 11 | JENKINS_HOME: /var/jenkins_home 12 | M2_HOME: "{{m2_home}}" 13 | M2: "{{m2}}" 14 | PATH: "{{m2}}:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/bin:/sbin:/bin:${PATH}" 15 | 16 | pre_tasks: 17 | - set_fact: clone_depchecker="0" 18 | - set_fact: clone_nvd_dl="0" 19 | 20 | tasks: 21 | 22 | - name: Cloning Dependency Checker to dir={{nvd_depcheck_dir}} 23 | connection: local 24 | include_tasks: ./roles/install/tasks/clone-depchecker.yml 25 | when: clone_depchecker == "1" 26 | 27 | - name: Cloning NIST NVD Downloader to dir={{nist_dl_dir}} 28 | connection: local 29 | include_tasks: ./roles/install/tasks/clone-nvd-dl.yml 30 | when: clone_nvd_dl == "1" 31 | 32 | - name: Listing Contents of Dependency Checker dir={{nvd_depcheck_dir}} 33 | connection: local 34 | shell: "ls -l {{nvd_depcheck_dir}}" 35 | 36 | - name: Listing Contents of NIST NVD Downloader dir={{nist_dl_dir}} 37 | connection: local 38 | shell: "ls -l {{nist_dl_dir}}" 39 | 40 | - name: Installing Dependency Checker in dir={{nvd_depcheck_dir}} 41 | connection: local 42 | include_tasks: ./roles/install/tasks/build-depchecker.yml 43 | 44 | - name: Installing NIST NVD Downloader in dir={{nist_dl_dir}} 45 | connection: local 46 | include_tasks: ./roles/install/tasks/build-nvd-dl.yml 47 | 48 | - name: Path to Dependency Checker={{nvd_depcheck}} 49 | connection: local 50 | shell: "ls -lrt {{nvd_depcheck}}" 51 | 52 | - name: Path to NIST NVD Downloader={{nist_dl}} 53 | connection: local 54 | shell: "ls -lrt {{nist_dl}}" 55 | -------------------------------------------------------------------------------- /ansible/inventories/inventory_dev: -------------------------------------------------------------------------------- 1 | [stack] 2 | localhost ansible_python_interpreter="../venv/bin/python" 3 | -------------------------------------------------------------------------------- /ansible/inventories/inventory_prod: -------------------------------------------------------------------------------- 1 | [stack] 2 | docker.prodhost.com ansible_python_interpreter="/opt/owasp/venv/bin/python" ansible_ssh_private_key_file=/path/to/pem_file 3 | -------------------------------------------------------------------------------- /ansible/inventories/inventory_uninstalled: -------------------------------------------------------------------------------- 1 | [stack] 2 | localhost 3 | -------------------------------------------------------------------------------- /ansible/roles/docker/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | -------------------------------------------------------------------------------- /ansible/roles/docker/tasks/start.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Starting {{docker_host}} compose_dir={{docker_compose_dir}} tls_hostname={{docker_tls_hostname}} ca={{docker_ca_cert}} client_cert={{docker_client_cert}} client_key={{docker_client_key}} compose_file={{docker_compose_file}} containers compose_file={{docker_compose_file}}" 3 | connection: local 4 | docker_service: 5 | project_src: "{{docker_compose_dir}}" 6 | docker_host: "{{docker_host}}" 7 | tls_hostname: "{{docker_tls_hostname}}" 8 | tls_ca_cert: "{{docker_ca_cert}}" 9 | tls_client_cert: "{{docker_client_cert}}" 10 | tls_client_key: "{{docker_client_key}}" 11 | files: 12 | - "{{docker_compose_file}}" 13 | state: present 14 | 15 | - name: "Waiting for {{docker_host}} containers to start with a max timeout of 120 seconds and delay of 20 seconds" 16 | connection: local 17 | wait_for: 18 | delay: 20 19 | host: localhost 20 | port: 8443 21 | timeout: 120 22 | sleep: 1 23 | 24 | - name: "Confirming {{docker_host}} --tls --tlsverify --tlscacert={{docker_ca_cert}} --tlscert={{docker_client_cert}} --tlskey={{docker_client_key}} ps -a has container: {{container_name}}" 25 | shell: docker --tls --tlsverify --tlscacert={{docker_ca_cert}} --tlscert={{docker_client_cert}} --tlskey={{docker_client_key}} ps -a | grep -v "CONTAINER ID" | grep {{container_name}} | wc -l 26 | connection: local 27 | register: this_container_stopped 28 | 29 | - name: "Confirm step found containers={{this_container_stopped.stdout}} on {{docker_host}}" 30 | connection: local 31 | fail: 32 | msg: | 33 | "{{docker_host}} does not have {{container_name}} running={{this_container_stopped.stdout}}" 34 | {{ this_container_stopped.stdout }} 35 | {{ this_container_stopped.stderr }} 36 | when: this_container_stopped.stdout == "0" 37 | 38 | -------------------------------------------------------------------------------- /ansible/roles/docker/tasks/stop.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Starting {{docker_host}} containers compose_file={{docker_compose_file}}" 3 | connection: local 4 | docker_service: 5 | project_src: "{{docker_compose_dir}}" 6 | docker_host: "{{docker_host}}" 7 | tls_hostname: "{{docker_tls_hostname}}" 8 | tls_ca_cert: "{{docker_ca_cert}}" 9 | tls_client_cert: "{{docker_client_cert}}" 10 | tls_client_key: "{{docker_client_key}}" 11 | files: 12 | - "{{docker_compose_file}}" 13 | state: absent 14 | 15 | - name: "Confirming {{docker_host}} has stopped: {{container_name}}" 16 | shell: docker ps -a | grep -v "CONTAINER ID" | grep {{container_name}} | grep -v {{container_name}} | wc -l 17 | connection: local 18 | register: this_container_stopped 19 | 20 | - name: "Confirm step found container={{this_container_stopped.stdout}} on {{docker_host}}" 21 | connection: local 22 | fail: 23 | msg: | 24 | "{{docker_host}} has container running={{this_container_stopped.stdout}}" 25 | {{ this_container_stopped.stdout }} 26 | {{ this_container_stopped.stderr }} 27 | when: this_container_stopped.stdout != "0" 28 | 29 | -------------------------------------------------------------------------------- /ansible/roles/docker/vars/docker.yml: -------------------------------------------------------------------------------- 1 | --- 2 | docker_cert_path: "/path/to/docker/certs" 3 | docker_host: "tcp://{{docker_fqdn}}:2376" 4 | docker_compose_dir: "{{playbook_dir}}/../" 5 | docker_compose_file: "{{docker_compose_dir}}/compose-owasp.yml" 6 | docker_tls_hostname: "{{docker_fqdn}}" 7 | docker_ca_cert: "{{docker_cert_path}}/ca.pem" 8 | docker_client_cert: "{{docker_cert_path}}/client_cert.pem" 9 | docker_client_key: "{{docker_cert_path}}/client_key.pem" 10 | -------------------------------------------------------------------------------- /ansible/roles/docker/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | env_name: "local" 3 | project_name: "owasp-jenkins" 4 | container_name: "owasp-jenkins" 5 | venv_dir: "/opt/owasp/venv" 6 | venv_path: "{{venv_dir}}/bin/python" 7 | -------------------------------------------------------------------------------- /ansible/roles/docker/vars/service_endpoints.yml: -------------------------------------------------------------------------------- 1 | --- 2 | base_fqdn: "localdev.com" 3 | docker_fqdn: "docker.{{base_fqdn}}" 4 | jenkins_fqdn: "jenkins.{{base_fqdn}}" 5 | docker_address: "tcp://{docker_fqdn}}:2376" 6 | jenkins_address: "http://{{jenkins_fqdn}}:8443" 7 | project_fqdn: "{{jenkins_fqdn}}" 8 | -------------------------------------------------------------------------------- /ansible/roles/install/files/celery-connectors-pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | jay-johnson 6 | celery-connectors 7 | 6.0.0 8 | 9 | 10 | 11 | org.owasp 12 | dependency-check-maven 13 | 1.4.5 14 | 15 | true 16 | true 17 | true 18 | true 19 | true 20 | true 21 | true 22 | true 23 | true 24 | true 25 | true 26 | true 27 | true 28 | 2 29 | 30 | 0 31 | 32 | 33 | 34 | 35 | check 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /ansible/roles/install/files/initial-pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | owasp.jenkins 6 | analyze-this-code 7 | 6.0.0 8 | 9 | 10 | 11 | org.owasp 12 | dependency-check-maven 13 | 1.4.5 14 | 15 | true 16 | true 17 | true 18 | true 19 | true 20 | true 21 | true 22 | true 23 | true 24 | true 25 | true 26 | true 27 | true 28 | 2 29 | 30 | 0 31 | 32 | 33 | 34 | 35 | check 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /ansible/roles/install/tasks/build-depchecker.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Building NVD Dependency Checker repo={{nvd_depcheck_repo}} in dir={{nvd_depcheck_dir}}" 3 | connection: local 4 | shell: "cd {{nvd_depcheck_dir}} && unset JAVA_TOOL_OPTIONS && mvn {{nvd_depcheck_m2_settings}} install {{maven_proxy_params}} -DskipTests clean package" 5 | 6 | - name: "Checking NVD Dependency Checker is on the PATH" 7 | stat: 8 | path: "{{nvd_depcheck}}" 9 | register: nvd_depchecker_installed 10 | 11 | - name: "Verifying NVD Dependency Checker Exists" 12 | fail: 13 | msg: "Failed to find NVD Dependency Checker script={{nvd_depcheck}} - Please try manually building it with the command: 'cd {{nvd_depcheck_dir}} && unset JAVA_TOOL_OPTIONS && mvn {{nvd_depcheck_m2_settings}} {{maven_proxy_params}} -DskipTests clean package'" 14 | when: not nvd_depchecker_installed.stat.exists 15 | 16 | - name: "Setting NVD Dependency Checker={{nvd_depcheck}} Permissions" 17 | connection: local 18 | file: 19 | path: "{{nvd_depcheck}}" 20 | owner: jenkins 21 | group: jenkins 22 | mode: u=rwx,g=rwx,o=rwx 23 | -------------------------------------------------------------------------------- /ansible/roles/install/tasks/build-nvd-dl.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Building NIST NVD Downloader repo={{nist_dl_repo}} to dir={{nist_dl_dir}}" 3 | connection: local 4 | shell: "cd {{nist_dl_dir}} && unset JAVA_TOOL_OPTIONS && mvn {{nist_dl_m2_settings}} {{maven_proxy_params}} -DskipTests clean package" 5 | 6 | - name: "Checking NIST NVD Downloader is on the PATH" 7 | stat: 8 | path: "{{nist_dl}}" 9 | register: nist_dl_installed 10 | 11 | - name: "Verifying NIST NVD Downloader Exists" 12 | fail: 13 | msg: "Failed to find NIST NVD Downloader jar file={{nist_dl}} - Please try manually building it with the command: 'cd {{nist_dl_dir}} && unset JAVA_TOOL_OPTIONS && mvn {{nist_dl_m2_settings}} {{maven_proxy_params}} -DskipTests clean package'" 14 | when: not nist_dl_installed.stat.exists 15 | 16 | - name: "Setting NIST NVD Downloader Permissions" 17 | file: 18 | path: "{{nist_dl}}" 19 | owner: jenkins 20 | group: jenkins 21 | mode: u=rwx,g=rwx,o=rwx 22 | -------------------------------------------------------------------------------- /ansible/roles/install/tasks/clone-depchecker.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Checking if NVD Dependency Checker is installed" 3 | connection: local 4 | stat: 5 | path: "{{nvd_depcheck_dir}}" 6 | register: nvd_depcheck_installed 7 | 8 | - name: "Should clone={{nvd_depcheck_installed.stat.exists}} NVD Dependency Checker from repo={{nvd_depcheck_repo}}" 9 | connection: local 10 | shell: "ssh-agent bash -c 'ssh-add {{nvd_depcheck_key}}; git clone {{nvd_depcheck_repo}} {{nvd_depcheck_dir}}'" 11 | when: not nvd_depcheck_installed.stat.exists 12 | -------------------------------------------------------------------------------- /ansible/roles/install/tasks/clone-nvd-dl.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Checking if NIST Downloader is installed" 3 | connection: local 4 | stat: 5 | path: "{{nist_dl_dir}}" 6 | register: nist_dl_installed 7 | 8 | - name: "Should clone={{nist_dl_installed.stat.exists}} NIST Downloader from repo={{nist_dl_repo}}" 9 | connection: local 10 | shell: "ssh-agent bash -c 'ssh-add {{nist_dl_key}}; git clone {{nist_dl_repo}} {{nist_dl_dir}}'" 11 | when: not nist_dl_installed.stat.exists 12 | -------------------------------------------------------------------------------- /ansible/roles/install/tasks/install-maven.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Starting Maven Installer Tasks" 3 | connection: local 4 | file: 5 | state: directory 6 | mode: u=rwX,g=rwX,o=rwX 7 | path: "{{tools_base_dir}}" 8 | 9 | # Move to the get_url module once the proxy issues are fixed: 10 | # https://github.com/ansible/ansible/issues/32750 11 | - name: "Downloading Maven with: wget {{wget_proxy_params}} {{proxy_params}} {{maven_download_url}} -O /opt/shared/apachemaven.tgz" 12 | connection: local 13 | shell: "wget {{wget_proxy_params}} {{proxy_params}} {{maven_download_url}} -O /opt/shared/apachemaven.tgz" 14 | 15 | - name: "Installing Maven to: {{m2_home}}" 16 | connection: local 17 | shell: "cd {{tools_base_dir}} && tar xvf /opt/shared/apachemaven.tgz \ 18 | && mv apache-maven-{{maven_build}} {{m2_home}} \ 19 | && rm -f /opt/shared/apachemaven.tgz" 20 | 21 | - name: "Verifying Maven is on the PATH" 22 | connection: local 23 | shell: "mvn -version" 24 | -------------------------------------------------------------------------------- /ansible/roles/install/tasks/pull-depchecker-updates.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Updating Installed NVD Dependency Checker from repo={{nvd_depcheck_repo}} in dir={{nvd_depcheck_dir}}" 3 | connection: local 4 | shell: "pushd {{nvd_depcheck_dir}} && ssh-agent bash -c 'ssh-add {{nvd_depcheck_key}}; git pull' && popd" 5 | -------------------------------------------------------------------------------- /ansible/roles/install/tasks/pull-nvd-dl-updates.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Updating Installed NIST Downloader from repo={{nist_dl_repo}} in dir={{nist_dl_dir}}" 3 | connection: local 4 | shell: "pushd {{nist_dl_dir}} && ssh-agent bash -c 'ssh-add {{nist_dl_key}}; git pull' && popd" 5 | -------------------------------------------------------------------------------- /ansible/roles/install/tasks/run-nvd-dl.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Downloading latest National Vulnerability Database files with jar={{nist_dl}} and storing DB files in dir={{nist_dl_data_dir}}" 3 | connection: local 4 | shell: "unset JAVA_TOOL_OPTIONS && which java && java -version && java {{java_proxy_params}} -jar {{nist_dl}} {{nist_dl_data_dir}}" 5 | -------------------------------------------------------------------------------- /ansible/roles/install/vars/jenkins-runtime-latest.yml: -------------------------------------------------------------------------------- 1 | tools_base_dir: "/opt/tools" 2 | install_maven: "1" 3 | update_maven: "0" 4 | maven_build: "3.5.2" 5 | maven_download_url: "http://www-us.apache.org/dist/maven/maven-3/{{maven_build}}/binaries/apache-maven-{{maven_build}}-bin.tar.gz" 6 | m2_home: "{{tools_base_dir}}/apache-maven" 7 | m2: "{{tools_base_dir}}/apache-maven/bin" 8 | install_nvd: "1" 9 | update_nvd: "0" 10 | proxy_params: "" 11 | wget_proxy_params: "" 12 | maven_proxy_params: "" 13 | java_proxy_params: "" 14 | owasp_proxy_params: "" 15 | jenkins_home: "/var/jenkins_home" 16 | path: "{{tools_base_dir}}/apache-maven/bin:/bin:/usr/bin:/usr/sbin:/usr/local/bin:$PATH" 17 | install_maven_task: "{{playbook_dir}}/roles/install/tasks/install-maven.yml" 18 | install_nvd_task: "{{playbook_dir}}/roles/install/tasks/install-nvd.yml" 19 | install_depchecker_task: "{{playbook_dir}}/roles/install/tasks/install-depchecker.yml" 20 | 21 | nvd_depcheck_dir: "{{tools_base_dir}}/depcheck" 22 | nvd_depcheck: "{{nvd_depcheck_dir}}/dependency-check-cli/target/release/bin/dependency-check.sh" 23 | # if you're using your own fork say on github enterprise or behind a proxy: 24 | nvd_depcheck_m2_settings: "" 25 | nvd_depcheck_repo: "https://github.com/jeremylong/DependencyCheck.git" 26 | nvd_depcheck_key: "/root/.ssh/id_rsa.pub" 27 | 28 | nist_dl_dir: "{{tools_base_dir}}/nvd" 29 | nist_dl: "{{nist_dl_dir}}/target/nist-data-mirror.jar" 30 | nist_dl_data_dir: "/opt/nvd" 31 | # if you're using your own fork say on github enterprise or behind a proxy 32 | nist_dl_proxy_params: "" 33 | nist_dl_m2_settings: "" 34 | nist_dl_repo: "https://github.com/stevespringett/nist-data-mirror.git" 35 | nist_dl_key: "/root/.ssh/id_rsa.pub" 36 | 37 | bandit_scan_dir: "/opt/scanthisdir" 38 | bandit_num_lines: "3" 39 | bandit_level: "-ll" 40 | bandit_formatter: "html" 41 | bandit_report_dir: "/opt/reports" 42 | bandit_report_file: "{{bandit_report_dir}}/bandit-report.html" 43 | bandit_args: "-r {{bandit_scan_dir}} -n {{bandit_num_lines}} {{bandit_level}} -f {{bandit_formatter}} -o {{bandit_report_file}}" 44 | 45 | owasp_scan_dir: "/opt/scanthisdir" 46 | owasp_python_args: "--enableExperimental true" 47 | owasp_run_report: "1" 48 | owasp_pom: "{{playbook_dir}}/roles/install/files/initial-pom.xml" 49 | owasp_project_label: "analyze-this-code" 50 | owasp_report_dir: "/opt/reports" 51 | owasp_report_file: "{{owasp_report_dir}}/owasp-report.html" 52 | owasp_build_h2_db_arg: "-n" 53 | owasp_args: "{{owasp_proxy_params}} {{owasp_build_h2_db_arg}} {{owasp_python_args}} --out {{owasp_report_file}} --scan {{owasp_scan_dir}} -P {{owasp_pom}} --project {{owasp_project_label}} --data {{nist_dl_data_dir}}" 54 | -------------------------------------------------------------------------------- /ansible/run-bandit-analysis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Running Bandit Analysis" 3 | gather_facts: no 4 | connection: local 5 | hosts: localhost 6 | 7 | vars_files: 8 | - ./roles/install/vars/jenkins-runtime-latest.yml 9 | 10 | environment: 11 | JENKINS_HOME: /var/jenkins_home 12 | 13 | pre_tasks: 14 | - set_fact: bandit_scan_dir="/opt/scanthisdir" 15 | - set_fact: bandit_report_file="/opt/reports/bandit-report.html" 16 | - set_fact: bandit_num_lines="3" 17 | - set_fact: bandit_level="-ll" 18 | - set_fact: bandit_formatter="html" 19 | - set_fact: bandit_args="" 20 | 21 | tasks: 22 | 23 | - name: "Building Bandit Report Arguments" 24 | connection: local 25 | set_fact: bandit_args="-r {{bandit_scan_dir}} -n {{bandit_num_lines}} {{bandit_level}} -f {{bandit_formatter}} -o {{bandit_report_file}}" 26 | when: bandit_args == "" 27 | 28 | - name: "Running Bandit Analysis args={{bandit_args}}" 29 | connection: local 30 | shell: ". /opt/owasp/venv/bin/activate && bandit {{bandit_args}} || true" 31 | register: bandit_shell_output 32 | 33 | - name: "Checking if the Bandit Report={{bandit_report_file}} exists" 34 | connection: local 35 | stat: 36 | path: "{{bandit_report_file}}" 37 | register: checked_report_file 38 | 39 | - name: "Verifying Bandit Report={{bandit_report_file}} was created" 40 | fail: 41 | msg: "Failed to create Bandit Report file={{bandit_report_file}} with command: . /opt/owasp/venv/bin/activate && bandit {{bandit_args}}" 42 | when: not checked_report_file.stat.exists 43 | 44 | - name: "Displaying Bandit output" 45 | connection: local 46 | debug: 47 | msg: "{{bandit_shell_output.stdout.replace('\t', '').split('\n')}}" 48 | 49 | -------------------------------------------------------------------------------- /ansible/run-owasp-analysis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Running OWASP Analysis" 3 | gather_facts: no 4 | connection: local 5 | hosts: localhost 6 | 7 | vars_files: 8 | - ./roles/install/vars/jenkins-runtime-latest.yml 9 | 10 | environment: 11 | JENKINS_HOME: /var/jenkins_home 12 | M2_HOME: "{{m2_home}}" 13 | M2: "{{m2}}" 14 | PATH: "{{m2}}:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/bin:/sbin:/bin:${PATH}" 15 | 16 | pre_tasks: 17 | # Rebuild the h2 database once a week or whenever the container is built. 18 | # The rebuild takes time, so skipping it means this will scan the code faster 19 | # 20 | # More details: 21 | # https://jeremylong.github.io/DependencyCheck/data/database.html 22 | # pass in these args on the ansible-playbook to rebuild the NVD: -e rebuild_nvd="1" 23 | - set_fact: rebuild_nvd="0" 24 | - set_fact: owasp_build_h2_db_arg="-n" 25 | - set_fact: owasp_analyzers="--enableExperimental true" 26 | - set_fact: owasp_scan_dir="/opt/scanthisdir" 27 | - set_fact: owasp_pom="/opt/owasp/ansible/roles/install/files/initial-pom.xml" 28 | - set_fact: owasp_project_label="analyze-this-code" 29 | - set_fact: owasp_report_file="/opt/reports/owasp-report.html" 30 | - set_fact: nist_dl_data_dir="/opt/nvd" 31 | - set_fact: owasp_args="" 32 | 33 | tasks: 34 | 35 | - name: "Checking if this is a rebuild_nvd={{rebuild_nvd}}" 36 | connection: local 37 | set_fact: owasp_build_h2_db_arg="" 38 | when: rebuild_nvd == "1" 39 | 40 | - name: "Building OWASP Arguments" 41 | connection: local 42 | set_fact: owasp_args="{{owasp_proxy_params}} {{owasp_build_h2_db_arg}} {{owasp_analyzers}} --out {{owasp_report_file}} --scan {{owasp_scan_dir}} -P {{owasp_pom}} --project {{owasp_project_label}} --data {{nist_dl_data_dir}}" 43 | when: owasp_args == "" 44 | 45 | - name: "Running OWASP Report depchecker={{nvd_depcheck}} owasp_args={{owasp_args}}" 46 | connection: local 47 | shell: "cd {{nvd_depcheck_dir}} && unset JAVA_TOOL_OPTIONS && {{nvd_depcheck}} {{owasp_args}}" 48 | 49 | - name: "Checking if the OWASP Report={{owasp_report_file}} exists" 50 | connection: local 51 | stat: 52 | path: "{{owasp_report_file}}" 53 | register: checked_report_file 54 | 55 | - name: "Verifying OWASP Report={{owasp_report_file}} was created" 56 | fail: 57 | msg: "Failed to create OWASP Report={{owasp_report_file}} with command: cd {{nvd_depcheck_dir}} && unset JAVA_TOOL_OPTIONS && {{nvd_depcheck}} {{owasp_args}}" 58 | when: not checked_report_file.stat.exists 59 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | maintainer=jayjohnson 4 | imagename=owasp-jenkins 5 | tag=$(cat setup.py | grep "version=" | sed -e 's/"/ /g' | awk '{print $2}') 6 | 7 | log=/dev/null 8 | 9 | source ./properties.sh 10 | 11 | rm -f ${imagename}-*.tgz 12 | include_these="owasp_jenkins ansible tests README.rst setup.cfg setup.py tox.ini" 13 | echo "Creating src build tar for tag=${tag} including=${include_these}" 14 | tar zcvf ${imagename}-${tag}.tgz ${include_these} 15 | cp ${imagename}-${tag}.tgz ${imagename}-latest.tgz 16 | 17 | echo "" 18 | echo "--------------------------------------------------------" 19 | echo "Building new Docker image(${maintainer}/${imagename})" 20 | docker build --rm -t $maintainer/$imagename . 21 | last_status=$? 22 | if [[ "${last_status}" == "0" ]]; then 23 | echo "" 24 | if [[ "${tag}" != "" ]]; then 25 | image_csum=$(docker images | grep "${maintainer}/${imagename} " | grep latest | awk '{print $3}') 26 | if [[ "${image_csum}" != "" ]]; then 27 | docker tag $image_csum $maintainer/$imagename:$tag 28 | last_status=$? 29 | if [[ "${last_status}" != "0" ]]; then 30 | echo "Failed to tag image(${imagename}) with Tag(${tag})" 31 | echo "" 32 | exit 1 33 | else 34 | echo "Build Successful Tagged Image(${imagename}) with Tag(${tag})" 35 | fi 36 | 37 | echo "" 38 | exit 0 39 | else 40 | echo "" 41 | echo "Build failed to find latest image(${imagename}) with Tag(${tag})" 42 | echo "" 43 | exit 1 44 | fi 45 | else 46 | echo "Build Successful" 47 | echo "" 48 | exit 0 49 | fi 50 | echo "" 51 | else 52 | echo "" 53 | echo "Build failed with exit code: ${last_status}" 54 | echo "" 55 | exit 1 56 | fi 57 | 58 | exit 0 59 | -------------------------------------------------------------------------------- /compose-owasp.yml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | 3 | services: 4 | 5 | # OWASP with Jenkins 6 | owasp-jenkins: 7 | # derived from: 8 | # https://hub.docker.com/r/jenkins/jenkins/ 9 | # https://github.com/jenkinsci/docker/blob/master/README.md 10 | image: jayjohnson/owasp-jenkins:latest 11 | container_name: "owasp-jenkins" 12 | hostname: owasp-jenkins 13 | entrypoint: "/opt/owasp/owasp_jenkins/scripts/start-container.sh" 14 | environment: 15 | # change these as needed 16 | - ADMIN_JENKINS_USER=admin 17 | - ADMIN_JENKINS_PASSWORD=testing 18 | env_file: 19 | - ./docker/env/owasp-dev.env 20 | ports: 21 | - "8443:8443" 22 | # - "8080:8080" 23 | volumes: 24 | - ./docker/bashrc:/root/.bashrc 25 | - ./docker/data/jenkins/secrets/initialAdminPassword:/var/jenkins_home/secrets/initialAdminPassword 26 | - ./docker/data/jenkins/lib/jenkins.install.UpgradeWizard.state:/var/jenkins_home/jenkins.install.UpgradeWizard.state 27 | - ./docker/data/jenkins/lib/init.groovy.d/basic-security.groovy:/var/jenkins_home/init.groovy.d/basic-security.groovy 28 | - ./docker/data/jenkins/ref/plugins.txt:/usr/share/jenkins/ref/plugins.txt 29 | - ./docker/data/depchecker:/opt/depchecker 30 | - ./docker/data/ansible:/opt/ansible 31 | - ./owasp_jenkins:/opt/owasp/owasp_jenkins 32 | - ./ansible:/opt/owasp/ansible 33 | - ./reports:/opt/reports 34 | -------------------------------------------------------------------------------- /docker/bashrc: -------------------------------------------------------------------------------- 1 | # .bashrc 2 | 3 | # Source global definitions 4 | if [ -f /etc/bashrc ]; then 5 | . /etc/bashrc 6 | fi 7 | 8 | # Uncomment the following line if you don't like systemctl's auto-paging feature: 9 | # export SYSTEMD_PAGER= 10 | 11 | # User specific aliases and functions 12 | # .bashrc 13 | HISTCONTROL=ignoredups:ignorespace 14 | 15 | # append to the history file, don't overwrite it 16 | shopt -s histappend 17 | 18 | # for setting history length see HISTSIZE and HISTFILESIZE in bash(1) 19 | HISTSIZE=1000 20 | HISTFILESIZE=2000 21 | 22 | # check the window size after each command and, if necessary, 23 | # update the values of LINES and COLUMNS. 24 | shopt -s checkwinsize 25 | 26 | # make less more friendly for non-text input files, see lesspipe(1) 27 | [ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)" 28 | 29 | # set variable identifying the chroot you work in (used in the prompt below) 30 | if [ -z "$debian_chroot" ] && [ -r /etc/debian_chroot ]; then 31 | debian_chroot=$(cat /etc/debian_chroot) 32 | fi 33 | 34 | # set a fancy prompt (non-color, unless we know we "want" color) 35 | case "$TERM" in 36 | xterm-color) color_prompt=yes;; 37 | esac 38 | 39 | # uncomment for a colored prompt, if the terminal has the capability; turned 40 | # off by default to not distract the user: the focus in a terminal window 41 | # should be on the output of commands, not on the prompt 42 | #force_color_prompt=yes 43 | 44 | if [ -n "$force_color_prompt" ]; then 45 | if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then 46 | # We have color support; assume it's compliant with Ecma-48 47 | # (ISO/IEC-6429). (Lack of such support is extremely rare, and such 48 | # a case would tend to support setf rather than setaf.) 49 | color_prompt=yes 50 | else 51 | color_prompt= 52 | fi 53 | fi 54 | 55 | if [ "$color_prompt" = yes ]; then 56 | PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' 57 | else 58 | PS1='${debian_chroot:+($debian_chroot)}\u:\w\$ ' 59 | fi 60 | unset color_prompt force_color_prompt 61 | 62 | # If this is an xterm set the title to user@host:dir 63 | case "$TERM" in 64 | xterm*|rxvt*) 65 | PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u: \w\a\]$PS1" 66 | ;; 67 | *) 68 | ;; 69 | esac 70 | 71 | alias gs='git status' 72 | alias gl='git log' 73 | alias gd='git diff' 74 | alias gco='git checkout' 75 | alias vi='vim' 76 | 77 | # enable color support of ls and also add handy aliases 78 | if [ -x /usr/bin/dircolors ]; then 79 | test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" 80 | alias ls='ls --color=auto' 81 | #alias dir='dir --color=auto' 82 | #alias vdir='vdir --color=auto' 83 | alias grep='grep --color=auto' 84 | alias fgrep='fgrep --color=auto' 85 | alias egrep='egrep --color=auto' 86 | fi 87 | 88 | # some more ls aliases 89 | alias ll='ls -alF' 90 | alias la='ls -A' 91 | alias l='ls -CF' 92 | alias rg='grep -rin ' 93 | 94 | # Alias definitions. 95 | # You may want to put all your additions into a separate file like 96 | # ~/.bash_aliases, instead of adding them here directly. 97 | # See /usr/share/doc/bash-doc/examples in the bash-doc package. 98 | 99 | if [ -f ~/.bash_aliases ]; then 100 | . ~/.bash_aliases 101 | fi 102 | 103 | # enable programmable completion features (you don't need to enable 104 | # this, if it's already enabled in /etc/bash.bashrc and /etc/profile 105 | # sources /etc/bash.bashrc). 106 | if [ -f /etc/bash_completion ] && ! shopt -oq posix; then 107 | . /etc/bash_completion 108 | fi 109 | 110 | unset command_not_found_handle 111 | 112 | txtund="" 113 | txtbld="" 114 | blddkg="" 115 | bldred="" 116 | bldblu="" 117 | bldylw="" 118 | bldgrn="" 119 | bldgry="" 120 | bldpnk="" 121 | bldwht="" 122 | txtrst="" 123 | 124 | # check if stdout is a terminal... 125 | if test -t 1; then 126 | if [[ -e /usr/bin/tput ]]; then 127 | # see if it supports colors... 128 | ncolors=$(tput colors) 129 | 130 | if test -n "$ncolors" && test $ncolors -ge 8; then 131 | 132 | txtund=$(tput sgr 0 1) # Underline 133 | txtbld=$(tput bold) # Bold 134 | blddkg=${txtbld}$(tput setaf 0) # Dark Gray 135 | bldred=${txtbld}$(tput setaf 1) # Red 136 | bldblu=${txtbld}$(tput setaf 2) # Blue 137 | bldylw=${txtbld}$(tput setaf 3) # Yellow 138 | bldgrn=${txtbld}$(tput setaf 4) # Green 139 | bldgry=${txtbld}$(tput setaf 5) # Gray 140 | bldpnk=${txtbld}$(tput setaf 6) # Pink 141 | bldwht=${txtbld}$(tput setaf 7) # White 142 | txtrst=$(tput sgr0) # Reset 143 | fi 144 | fi 145 | fi 146 | 147 | dbg() { 148 | cdate=$(date '+%Y-%m-%d %H:%M:%S') 149 | echo "${bldwht}$cdate $@ $txtrst" 150 | } 151 | 152 | inf() { 153 | cdate=$(date '+%Y-%m-%d %H:%M:%S') 154 | echo "$cdate $@" 155 | } 156 | 157 | anmt() { 158 | cdate=$(date '+%Y-%m-%d %H:%M:%S') 159 | echo "${bldylw}$cdate $@ $txtrst" 160 | } 161 | 162 | amnt() { 163 | cdate=$(date '+%Y-%m-%d %H:%M:%S') 164 | echo "${bldylw}$cdate $@ $txtrst" 165 | } 166 | 167 | warn() { 168 | cdate=$(date '+%Y-%m-%d %H:%M:%S') 169 | echo "${bldylw}$cdate $@ $txtrst" 170 | } 171 | 172 | ign() { 173 | cdate=$(date '+%Y-%m-%d %H:%M:%S') 174 | echo "${blddkg}$cdate $@ $txtrst" 175 | } 176 | 177 | good() { 178 | cdate=$(date '+%Y-%m-%d %H:%M:%S') 179 | echo "${bldgrn}$cdate $@ $txtrst" 180 | } 181 | 182 | green() { 183 | cdate=$(date '+%Y-%m-%d %H:%M:%S') 184 | echo "${bldgrn}$@ $txtrst" 185 | } 186 | 187 | err() { 188 | cdate=$(date '+%Y-%m-%d %H:%M:%S') 189 | echo "${bldred}$cdate $@ $txtrst" 190 | } 191 | 192 | lg() { 193 | cdate=$(date '+%Y-%m-%d %H:%M:%S') 194 | echo "$cdate $@" 195 | } 196 | 197 | boom() { 198 | echo "" 199 | if [[ "${2}" != "" ]]; then 200 | echo "${bldred}StatusCode: ${1}. $txtrst" 201 | echo "${bldred}Error: ${2}.$txtrst" 202 | exit $1 203 | else 204 | echo "${bldred}Error: ${@}.$txtrst" 205 | exit 1 206 | fi 207 | } 208 | 209 | xerr() { 210 | last_status=$? 211 | if [[ "${last_status}" != "" ]]; then 212 | if [[ "${last_status}" != "0" ]]; then 213 | echo "" 214 | err "Exiting(${last_status}) Error: ${@}" 215 | exit $last_status 216 | fi 217 | fi 218 | } 219 | 220 | lgenv() { 221 | echo "" 222 | echo "-------------------------------------------" 223 | env | sort 224 | echo "-------------------------------------------" 225 | echo "" 226 | } 227 | 228 | export PATH=/opt/tools/apache-maven/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/bin:/sbin:/bin:${PATH} 229 | alias dev="cd /opt/owasp" 230 | alias lint="pycodestyle --max-line-length=160 --exclude=venv,build,.tox" 231 | # python setup.py sdist bdist_wheel --universal upload -r pypi 232 | 233 | if [[ -e /opt/owasp/venv/bin/activate ]]; then 234 | source /opt/owasp/venv/bin/activate 235 | fi 236 | -------------------------------------------------------------------------------- /docker/certs/jenkins_server_cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIG2zCCBMOgAwIBAgIJAOhbuS7xD2yjMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYD 3 | VQQGEwJVUzELMAkGA1UECAwCV0ExEDAOBgNVBAcMB1JlZG1vbmQxGjAYBgNVBAoM 4 | EVNlY3VyZSBFdmVyeXRoaW5nMSMwIQYDVQQLDBpTZWN1cmUgRXZlcnl0aGluZyBP 5 | cmcgVW5pdDEtMCsGA1UEAwwkU2VjdXJlIEV2ZXJ5dGhpbmcgSW50ZXJuZXQgQXV0 6 | aG9yaXR5MB4XDTE4MDExMDA2MzUyOVoXDTE5MDExMDA2MzUyOVowgYIxCzAJBgNV 7 | BAYTAlVTMQswCQYDVQQIDAJXQTEQMA4GA1UEBwwHUmVkbW9uZDEZMBcGA1UECgwQ 8 | U2VjdXJlRXZlcnl0aGluZzEgMB4GA1UECwwXU2VjdXJlRXZlcnl0aGluZ09yZ1Vu 9 | aXQxFzAVBgNVBAMMDioubG9jYWxkZXYuY29tMIICIjANBgkqhkiG9w0BAQEFAAOC 10 | Ag8AMIICCgKCAgEA1LX8ihWGshUvp+CwEjKDWPriALTwaWX955Iw6VN9MbfOHLgC 11 | hVffenEIUP9WPJnLCSgRW6kbPATR4wfp4+XZH5trgWCIp8d/0bPgUWlqMEUuWCge 12 | p/k0gJUuIdvkhhKmP3UBEClXb1unzqHVdYERY0b6afDtv47OnOYJGyz3rBIbs/QW 13 | YEvjepoTpsuno2fUZrfkkILA5muzkSVsbCZbBpWLX3rwvz1dOCdyPdzHTEF88BPN 14 | O2+sfC6gB5HB/7JBNRmx5uLYKntvjd0H/L0kDeA0IXD0ZcUcSXOuvq+dKmXxlZZi 15 | VS+RE+C6GpPt2Pt+7MpbyD2sbhaG3EYITeyI0X/R6RRmKM8Kgptg8p5Mq7Zhuxx4 16 | BriuLG/pMoGf2cSV5tF7lQvzVzw0oxaFCApCa8iKeIdRRJxboSAP7ZRDgUqaiKFG 17 | gb2kOUGJUeUe36a7qLt3JHvSmJwhpG616+NwQ8fvk9VJ8gXhMi3FNR/vwyZiplPn 18 | cCbq0ghkNxpE9NnKvdmYVtMpN/UMyIh37C1lbkL9QDG8DUenSArx/hJWdDuFDX/R 19 | FB8gKOCw3QLCdb238U4Qslv9YMaIvf4d3CtR5CO82722CEXHVe+tCIKMgbrjhevt 20 | ATmkMyIjEbIZSz8o/BhfH/Akxodf74+dVs0NuDU8JMP3asuc54njkezqXJ0CAwEA 21 | AaOCATYwggEyMIIBGQYDVR0RBIIBEDCCAQyCDioubG9jYWxkZXYuY29tghVyYWJi 22 | aXRtcS5sb2NhbGRldi5jb22CEnJlZGlzLmxvY2FsZGV2LmNvbYIUanVweXRlci5s 23 | b2NhbGRldi5jb22CFGplbmtpbnMubG9jYWxkZXYuY29tghB3d3cubG9jYWxkZXYu 24 | Y29tghBhcGkubG9jYWxkZXYuY29tgg9kYi5sb2NhbGRldi5jb22CFHBnYWRtaW4u 25 | bG9jYWxkZXYuY29tghdwaHBteWFkbWluLmxvY2FsZGV2LmNvbYITa2liYW5hLmxv 26 | Y2FsZGV2LmNvbYIPbGIubG9jYWxkZXYuY29tghNkb2NrZXIubG9jYWxkZXYuY29t 27 | hwR/AAABMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4ICAQAY 28 | Wdh2t2YbGih4/KLFjU0UvItvT1oTetJnI1cEhbtWDokBFr6ZwqHW8LZk6wN3BQC3 29 | jAS1i1RYyOrS4MxfXTZFc+/Y9Xfyfvleq5Ph6O9lbHLJYqOgWDvTpcIOOCze75uk 30 | g4V0R5ZK1zovjN1T/F8CdOvuBfSN33EPZia7a4pZIw4WxJIFs7wvTy5ct2bWageb 31 | DFBA3k9tYMAhKfc3XKVZ9PUKLGlimP0zhADyb5HvoE4cpkbSf3703ycWzjaALkxq 32 | lOrMniJz6SSZNdDbaIR+Pf4mfvw22UHLkfmI95SRRaHza9wl6ctXjtGiSoXfrmn9 33 | zsxTI/WUiqysuCtMve5xQPBw3XdbRIRhepfj4PbPjE45XVhlhsi16mmJEV/bNAAd 34 | T9OrB+jRdXUSuew1omIfe5ltKwSR4UzO/TMnp9LtqKC7RL0KP1i7unVbykQJbgtM 35 | Qp+XyKC1y12hmFOjAg6ZhzIMXTRSrzSzpMmqzG3mGHc8P3oAqkh0qDMt9R2Edt/h 36 | yFYwMXLEKwjz8Ro2oWVL3c9HpQG3AJQvbFb55SYBO+9ChTwolxmY0JjSeNr+ECRj 37 | N8fPkl1AgEwNmNhUNYhIRC344QfXEPu0eMzJumER1+cej+j3bbmvvXdhmmtaAkEO 38 | sRySQ9+7zi0qRQtXELEHsSy/wEX7lvUOvqRf8S8lBw== 39 | -----END CERTIFICATE----- 40 | -------------------------------------------------------------------------------- /docker/certs/jenkins_server_key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIJJwIBAAKCAgEA1LX8ihWGshUvp+CwEjKDWPriALTwaWX955Iw6VN9MbfOHLgC 3 | hVffenEIUP9WPJnLCSgRW6kbPATR4wfp4+XZH5trgWCIp8d/0bPgUWlqMEUuWCge 4 | p/k0gJUuIdvkhhKmP3UBEClXb1unzqHVdYERY0b6afDtv47OnOYJGyz3rBIbs/QW 5 | YEvjepoTpsuno2fUZrfkkILA5muzkSVsbCZbBpWLX3rwvz1dOCdyPdzHTEF88BPN 6 | O2+sfC6gB5HB/7JBNRmx5uLYKntvjd0H/L0kDeA0IXD0ZcUcSXOuvq+dKmXxlZZi 7 | VS+RE+C6GpPt2Pt+7MpbyD2sbhaG3EYITeyI0X/R6RRmKM8Kgptg8p5Mq7Zhuxx4 8 | BriuLG/pMoGf2cSV5tF7lQvzVzw0oxaFCApCa8iKeIdRRJxboSAP7ZRDgUqaiKFG 9 | gb2kOUGJUeUe36a7qLt3JHvSmJwhpG616+NwQ8fvk9VJ8gXhMi3FNR/vwyZiplPn 10 | cCbq0ghkNxpE9NnKvdmYVtMpN/UMyIh37C1lbkL9QDG8DUenSArx/hJWdDuFDX/R 11 | FB8gKOCw3QLCdb238U4Qslv9YMaIvf4d3CtR5CO82722CEXHVe+tCIKMgbrjhevt 12 | ATmkMyIjEbIZSz8o/BhfH/Akxodf74+dVs0NuDU8JMP3asuc54njkezqXJ0CAwEA 13 | AQKCAgBXzGJX8LivSvVnuuOSL01t7ehZWFYfexzJd9s+g9qaKf8mdYF83p9836kK 14 | HcrPqr9WoTZA+lUmeerUZhDRo67yT+mY9mqRrlQBD9kYYYWWNQgDFVRKCx/zrx/i 15 | k+wItyvt53Kv5BCWA2QJc10zajnuG38DOZI4zk5UDtNVZ0M3wCW1KpwN1WUo1u4j 16 | m84vMY1HdMIgMAhFU9FDqQnOvio2VoW3vHwgw8h1hDqwdC/DNwjF47aDwP2WKHyf 17 | gzdrPn2R2HBJF/sX1eleygwg80UtgQyjfQcz9p9NZjWLudsKhBeqoe8msEKWzNyk 18 | WckEFhL21DP8PBCvRBcYVsPYvjheWFn9SbbJqbn8E26DhDaCcbqjQ4W9CvtYQ6Kd 19 | OpR0Hs1ZM/KFo/tCrfD5L0vayiId+4JUqg5fqQu6n9nL0rSkx60Y3W68zEyc/pQ4 20 | hiVCXbY5R9Y+RRcBIbmx1jYjW2QTEsV2xcVRxC3vNQUJR7+l/5Q9iay5RW6cmEzI 21 | evdkRiY7nBa/2xd8g8MYHWYtyKNz8d1DyYQXKCLx0guUs597Gcft1ilqxCk2l2IU 22 | R83k+1rG/RL6spLzPMQVqyVzSzm5hHGchyOnhAKQ/I1sGX2mXRLGhaUH7CN3IO2t 23 | KmocbB4/YjOLWcauCUn2f9ZVRlaVTMF0HDV1/zCv4zmzAlTuFQKCAQEA6ustPz+P 24 | esf52/EHlbcSGJ9zFNrGahmEibWwN0odDnz1joBpcQhWt1aoZCx/euSv9Y6XD8YW 25 | X8EoFjtX3oaqaemKWcIz3NhNA9Hqn+LLgRD9u4N9vLMoZ61qCX1bxq6iNfkgVg+t 26 | oUFETtgxWYD4gpgNH8vOUSKHuK/1Xmlt/321zDvMNU5rK2bJbLReQHzlz9lxTptL 27 | 03shXZQ5q5tgx6+3TpsapBiYjwF/XJxXwxsISAW8asfQtT6t02AFQnoz3JZ8Yxrf 28 | hRMk72U7qCZXZxm6pt6CuycjmsfMOzlUH5TNbDrFBnoweg1aRdLkVnkQPWKjYUA2 29 | B7kZzzZjYqqdowKCAQEA58yghgGEV+z3U3rxlb5HI39wovWWrxY9GkVn6djUcZEo 30 | l7FF3xD7kVCmCsrVhKd7g1XSOhYvSu14xJc3ZnwpFcOynOHeYxQBG0RQxaElKbiR 31 | 8IpBEQJAHQiCDgEtMZdVeYqgjQ2VmuHldUWXXLJThO2mid/GfuETQL+AaeT6h947 32 | 3MWdzQSfk+OudHamwnimE8rEtNohw0SwzHNPCotHJlERRwM4zjlrnRNB4kdr6zo2 33 | B8Zju9Z709ulq7q4x84OnAvzSpeJs3uBI0XkUHDmAK/ghWKN0GbdsI2u3n+st+Ok 34 | ugabFRqgps2oy2zEDVPrRSaUCqRVb9ZMXzvLzlJAvwKCAQBBu6CjjAN31bECbAU1 35 | TU6Q+TzYXwcZ9R3y8pXmQqSywyBqyV+3sx+gmWzw6sqY9piN22JFlaX5ETFIVz6V 36 | E5VnoWOHDiI474VNRlWie3F6Iej9qSNrw63QpOOA2ETv6TmWZKk5q5VoA707Wp8k 37 | bkQbNrSlav/GECVt9j5wNowC64gNJ8ZSPCkcsdw2wJmG7evYJv3fgvDKsi954dnp 38 | PMbt2SsvoZLoy8EUctTScyTTgSLmFETOlC7AKFO3S6ztFwif9rPDf2d/8wVovyjc 39 | Oi5GuRpTSvvFpoP98V4iTD5Pv/FjEWbEEzixTj8uPn6J+8IhixIwSilUK+Ue6BcT 40 | Kq6FAoIBABL+R2Dzmt6BgjqK5mS4tKeJ97bCnNg34EXYzgzxQWcU19imI+2FPLfJ 41 | ffGAcUJvXsWCMLmlu7ZOAwlIwrdZERzBbk9AirJfnz+Wt2+aJqtmfj7RdUdpgctf 42 | ORjgq81WcyCEZWdpZ4rLW7viOebUjddkibLebStUUfmKN4F1y7l6Ujliz+1Opay+ 43 | iTrtxfhFXoZcpQWUohOX+0ylXiKlCu1u0xWYg/0R42l5fHqIE6WwnWDBtsZbasYP 44 | R2Hs6NsmXTgYGpVQGW5lfk1fmrekqJQB1UnYq3oaE6w1z9BXcdWXh5XemLJ//g3s 45 | 6BnTDbVx3ONLp/G/SWjijFt5UNfVEY0CggEAVJU55c1qmkRnzAMw8nUgUHY5UHoX 46 | NhXU4xjLS1pOcYplNWiEtlPzx6OrX7r1LFl44Fwi32vu44SOoJ5CjKSXmlphzsY2 47 | 3/JDlD6kNIHTRoJ9llurn3jW7ZJ8KsLiuA4ArFggb/5ieJIlQ7dZOlYtfoD+RP09 48 | Q//MIy0zajZThJaXEDLAAIp2XdBSVDln1TrXY5/iuN5yQCXWBRWfxWz/+VfMd9z2 49 | l1GKQhjh62Ex+33pPYf/VNnNrHndKifbAIO4IsiapyYWjhJz4+/dO0TssDHUNntc 50 | gVdqZD6mKyawFqU16q8hw5jjUPFjs6M4sSoUASCw2JDOyzmL/q/cbIYwAQ== 51 | -----END RSA PRIVATE KEY----- 52 | -------------------------------------------------------------------------------- /docker/configs/.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | -------------------------------------------------------------------------------- /docker/data/.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | -------------------------------------------------------------------------------- /docker/data/jenkins/.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | -------------------------------------------------------------------------------- /docker/data/jenkins/cache/.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | -------------------------------------------------------------------------------- /docker/data/jenkins/lib/init.groovy.d/basic-security.groovy: -------------------------------------------------------------------------------- 1 | #!groovy 2 | 3 | import jenkins.model.* 4 | import hudson.security.* 5 | 6 | def env = System.getenv() 7 | 8 | def instance = Jenkins.getInstance() 9 | def username = env["ADMIN_JENKINS_USER"] 10 | def password = env["ADMIN_JENKINS_PASSWORD"] 11 | 12 | println "Creating admin user=" + username + " password=" + password 13 | 14 | def hudsonRealm = new HudsonPrivateSecurityRealm(false) 15 | hudsonRealm.createAccount(username, password) 16 | instance.setSecurityRealm(hudsonRealm) 17 | 18 | println "Setting up auth" 19 | def strategy = new FullControlOnceLoggedInAuthorizationStrategy() 20 | strategy.setAllowAnonymousRead(false) 21 | instance.setAuthorizationStrategy(strategy) 22 | instance.save() 23 | println "Ready" 24 | -------------------------------------------------------------------------------- /docker/data/jenkins/lib/jenkins.install.UpgradeWizard.state: -------------------------------------------------------------------------------- 1 | 2.101 -------------------------------------------------------------------------------- /docker/data/jenkins/ref/plugins.txt: -------------------------------------------------------------------------------- 1 | script-security 2 | command-launcher 3 | cloudbees-folder 4 | bouncycastle-api 5 | structs 6 | workflow-step-api 7 | scm-api 8 | workflow-api 9 | junit 10 | antisamy-markup-formatter 11 | workflow-support 12 | workflow-job 13 | token-macro 14 | build-timeout 15 | credentials 16 | ssh-credentials 17 | plain-credentials 18 | credentials-binding 19 | timestamper 20 | durable-task 21 | workflow-durable-task-step 22 | matrix-project 23 | resource-disposer 24 | ws-cleanup 25 | ant 26 | gradle 27 | pipeline-milestone-step 28 | jquery-detached 29 | jackson2-api 30 | ace-editor 31 | workflow-scm-step 32 | workflow-cps 33 | pipeline-input-step 34 | pipeline-stage-step 35 | pipeline-graph-analysis 36 | pipeline-rest-api 37 | handlebars 38 | momentjs 39 | pipeline-stage-view 40 | pipeline-build-step 41 | pipeline-model-api 42 | pipeline-model-extensions 43 | apache-httpcomponents-client-4-api 44 | windows-slaves 45 | display-url-api 46 | mailer 47 | matrix-auth 48 | jsch 49 | git-client 50 | git-server 51 | workflow-cps-global-lib 52 | branch-api 53 | workflow-multibranch 54 | authentication-tokens 55 | docker-commons 56 | docker-workflow 57 | pipeline-stage-tags-metadata 58 | pipeline-model-declarative-agent 59 | workflow-basic-steps 60 | pipeline-model-definition 61 | workflow-aggregator 62 | github-api 63 | git 64 | github 65 | github-branch-source 66 | pipeline-github-lib 67 | mapdb-api 68 | subversion 69 | ssh-slaves 70 | pam-auth 71 | ldap 72 | email-ext 73 | -------------------------------------------------------------------------------- /docker/data/jenkins/secrets/initialAdminPassword: -------------------------------------------------------------------------------- 1 | e781dc1ef04b46cb9b7c2c45704491ca 2 | -------------------------------------------------------------------------------- /docker/env/owasp-dev.env: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jay-johnson/owasp-jenkins/4a78c3e4d04c9559ac46f558c22cd8489ad2a628/docker/env/owasp-dev.env -------------------------------------------------------------------------------- /docker/env/owasp-test.env: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jay-johnson/owasp-jenkins/4a78c3e4d04c9559ac46f558c22cd8489ad2a628/docker/env/owasp-test.env -------------------------------------------------------------------------------- /docker/logs/.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | -------------------------------------------------------------------------------- /owasp_jenkins/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jay-johnson/owasp-jenkins/4a78c3e4d04c9559ac46f558c22cd8489ad2a628/owasp_jenkins/__init__.py -------------------------------------------------------------------------------- /owasp_jenkins/log/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jay-johnson/owasp-jenkins/4a78c3e4d04c9559ac46f558c22cd8489ad2a628/owasp_jenkins/log/__init__.py -------------------------------------------------------------------------------- /owasp_jenkins/log/build_logstash_formatter.py: -------------------------------------------------------------------------------- 1 | import os 2 | import logging 3 | import logging.config 4 | import logstash.formatter 5 | 6 | 7 | def build_logstash_formatter(log): 8 | try: 9 | 10 | class WrappedLogstashFormatter( 11 | logstash.formatter.LogstashFormatterVersion1): 12 | 13 | def set_fields(self, add_fields_dict): 14 | self.fields_to_add = add_fields_dict 15 | 16 | def format(self, msg): 17 | 18 | full_msg = { 19 | "@timestamp": self.format_timestamp(msg.created), 20 | "@version": 1, 21 | "@env": os.getenv( 22 | "ENV_NAME", 23 | "dev"), 24 | "@message": msg.getMessage(), 25 | "@fields": {"logger": os.getenv( 26 | "APP_NAME", 27 | "owasp-jenkins")}, 28 | "host": self.host, 29 | "path": msg.pathname, 30 | "tags": self.tags, 31 | "type": "owasp", 32 | "level": msg.levelname, 33 | "logger_name": msg.name} 34 | 35 | full_msg.update(self.get_extra_fields(msg)) 36 | 37 | if hasattr(msg, 'exec_info'): 38 | full_msg.update(self.get_debug_fields) 39 | 40 | full_msg.update(self.fields_to_add) 41 | 42 | return self.serialize(full_msg) 43 | # end of WrappedLogstashFormatter 44 | 45 | fields_to_add = {"@env": "dev"} 46 | tags = os.getenv("LOGSTASH_TAGS", "dev").split(",") 47 | lgstsh_formatter = WrappedLogstashFormatter("wpdlsh", tags, False) 48 | lgstsh_formatter.set_fields(fields_to_add) 49 | found_handler = False 50 | 51 | for i in logging.root.handlers: 52 | if "logstash" in str(i.__class__.__name__).lower(): 53 | found_handler = True 54 | i.formatter = lgstsh_formatter 55 | 56 | if not found_handler: 57 | new_handler = logstash.TCPLogstashHandler( 58 | os.getenv( 59 | "LOGSTASH_HOST", "localhost"), 60 | port=int(os.getenv( 61 | "LOGSTASH_PORT", "5000").strip().lstrip()), 62 | version=1) 63 | new_handler.formatter = lgstsh_formatter 64 | log.handlers.append(new_handler) 65 | 66 | log.debug("logstash ready") 67 | 68 | except Exception as e: 69 | print(("Failed to build_logstash_formatter with ex={}") 70 | .format(e)) 71 | 72 | # end of build_logstash_formatter 73 | -------------------------------------------------------------------------------- /owasp_jenkins/log/logging.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "disable_existing_loggers": false, 4 | "formatters": { 5 | "simple": { 6 | "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s" 7 | } 8 | }, 9 | "handlers": { 10 | "console": { 11 | "class": "logging.StreamHandler", 12 | "level": "INFO", 13 | "formatter": "simple", 14 | "stream": "ext://sys.stdout" 15 | }, 16 | "info_file_handler": { 17 | "class": "logging.handlers.RotatingFileHandler", 18 | "level": "INFO", 19 | "formatter": "simple", 20 | "filename": "latest.log", 21 | "maxBytes": 10485760, 22 | "backupCount": 20, 23 | "encoding": "utf8" 24 | } 25 | }, 26 | "loggers": { 27 | "my_module": { 28 | "level": "ERROR", 29 | "handlers": ["console"], 30 | "propagate": "no" 31 | } 32 | }, 33 | "root": { 34 | "level": "INFO", 35 | "handlers": ["console", "info_file_handler"] 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /owasp_jenkins/log/setup_logging.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | import logging.config 4 | 5 | 6 | def setup_logging(default_level=logging.INFO, 7 | default_path="{}/logging.json".format( 8 | os.getenv("LOG_DIR", 9 | os.path.dirname(os.path.realpath(__file__))).strip().lstrip()), 10 | env_key='LOG_CFG'): 11 | 12 | """ 13 | Setup logging configuration 14 | """ 15 | path = default_path 16 | value = os.getenv(env_key, None) 17 | if value: 18 | path = value 19 | if os.path.exists(path): 20 | with open(path, 'rt') as f: 21 | config = json.load(f) 22 | logging.config.dictConfig(config) 23 | else: 24 | logging.basicConfig(level=default_level) 25 | # end of setup_logging 26 | -------------------------------------------------------------------------------- /owasp_jenkins/scripts/start-container.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "" 4 | date 5 | 6 | use_cert=/opt/certs/jenkins_server_cert.pem 7 | use_key=/opt/certs/jenkins_server_key.pem 8 | 9 | if [[ "${PATH_TO_CERT}" == "" ]]; then 10 | if [[ -e ${PATH_TO_CERT} ]]; then 11 | use_cert=${PATH_TO_CERT} 12 | fi 13 | fi 14 | 15 | if [[ "${PATH_TO_KEY}" == "" ]]; then 16 | if [[ -e ${PATH_TO_KEY} ]]; then 17 | use_key=${PATH_TO_KEY} 18 | fi 19 | fi 20 | 21 | if [[ -e ${use_cert} ]] && [[ -e ${use_key} ]]; then 22 | echo "Starting Jenkins using certs on:" 23 | echo "" 24 | echo "https://jenkins.localdev.com:8443" 25 | echo "" 26 | echo "Login:" 27 | echo "" 28 | echo "User: ${ADMIN_JENKINS_USER}" 29 | echo "Password: ${ADMIN_JENKINS_PASSWORD}" 30 | echo "" 31 | /sbin/tini -- /usr/local/bin/jenkins.sh --httpsPort=8443 --httpsCertificate=${use_cert} --httpsPrivateKey=${use_key} 32 | else 33 | /sbin/tini -- /usr/local/bin/jenkins.sh 34 | fi 35 | 36 | touch /tmp/keeprunning 37 | tail -f /tmp/keeprunning 38 | -------------------------------------------------------------------------------- /reports/.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | description-file = README.rst 3 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import warnings 4 | import unittest 5 | 6 | try: 7 | from setuptools import setup 8 | except ImportError: 9 | from distutils.core import setup 10 | 11 | try: 12 | from distutils.command.build_py import build_py_2to3 as build_py 13 | except ImportError: 14 | from distutils.command.build_py import build_py 15 | 16 | """ 17 | https://packaging.python.org/guides/making-a-pypi-friendly-readme/ 18 | check the README.rst works on pypi as the 19 | long_description with: 20 | twine check dist/* 21 | """ 22 | long_description = open('README.rst').read() 23 | 24 | cur_path, cur_script = os.path.split(sys.argv[0]) 25 | os.chdir(os.path.abspath(cur_path)) 26 | 27 | install_requires = [ 28 | 'ansible>=2.4', 29 | 'bandit', 30 | 'coverage', 31 | 'docker-compose', 32 | 'flake8', 33 | 'future', 34 | 'mock', 35 | 'paramiko', 36 | 'pep8', 37 | 'pycurl', 38 | 'pylint', 39 | 'python-owasp-zap-v2.4', 40 | 'safety', 41 | 'unittest2' 42 | ] 43 | 44 | 45 | if sys.version_info < (2, 7): 46 | warnings.warn( 47 | 'Less than Python 2.7 is not supported.', 48 | DeprecationWarning) 49 | 50 | 51 | def owasp_jenkins_test_suite(): 52 | test_loader = unittest.TestLoader() 53 | test_suite = test_loader.discover('tests', pattern='test_*.py') 54 | return test_suite 55 | 56 | 57 | # Don't import owasp-jenkins module here, since deps may not be installed 58 | sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'owasp_jenkins')) 59 | 60 | setup( 61 | name='owasp-jenkins', 62 | cmdclass={'build_py': build_py}, 63 | version='1.0.2', 64 | description=( 65 | 'Automate your OWASP analysis within a ' 66 | 'Jenkins docker ' 67 | 'container that is preconfigured to use Ansible to ' 68 | 'scan and report on potential python security issues ' 69 | 'before they are deployed to production.'), 70 | long_description=long_description, 71 | author='Jay Johnson', 72 | author_email='jay.p.h.johnson@gmail.com', 73 | url='https://github.com/jay-johnson/owasp-jenkins', 74 | packages=[ 75 | 'owasp_jenkins', 76 | 'owasp_jenkins.log' 77 | ], 78 | package_data={}, 79 | install_requires=install_requires, 80 | test_suite='setup.owasp_jenkins_test_suite', 81 | tests_require=[ 82 | ], 83 | scripts=[ 84 | ], 85 | use_2to3=True, 86 | classifiers=[ 87 | 'Development Status :: 5 - Production/Stable', 88 | 'Intended Audience :: Developers', 89 | 'License :: OSI Approved :: Apache Software License', 90 | 'Operating System :: OS Independent', 91 | 'Programming Language :: Python :: 2.7', 92 | 'Programming Language :: Python :: 3.5', 93 | 'Programming Language :: Python :: 3.6', 94 | 'Programming Language :: Python :: Implementation :: PyPy', 95 | 'Topic :: Software Development :: Libraries :: Python Modules', 96 | ]) 97 | -------------------------------------------------------------------------------- /ssh.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | docker exec -it owasp-jenkins /bin/bash -c "export TERM=xterm; exec bash" 4 | -------------------------------------------------------------------------------- /start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # this assumes docker is running and docker-compose is installed 4 | 5 | compose_file="compose-owasp.yml" 6 | 7 | echo "Starting OWASP-Ready Jenkins with compose_file=${compose_file}" 8 | docker-compose -f $compose_file up 9 | 10 | exit 0 11 | -------------------------------------------------------------------------------- /stop.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # this assumes docker is running and docker-compose is installed 4 | 5 | compose_file="compose-owasp.yml" 6 | 7 | echo "Stopping OWASP Jenkins with compose_file=${compose_file}" 8 | docker-compose -f ${compose_file} stop 9 | 10 | # This will delete your jobs... please be careful 11 | # if [[ "$?" == "0" ]]; then 12 | # docker rm owasp-jenkins >> /dev/null 2>&1 13 | # fi 14 | 15 | exit 0 16 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jay-johnson/owasp-jenkins/4a78c3e4d04c9559ac46f558c22cd8489ad2a628/tests/__init__.py -------------------------------------------------------------------------------- /tests/base_test.py: -------------------------------------------------------------------------------- 1 | import os 2 | import logging 3 | import unittest 4 | 5 | log = logging.getLogger("base_test") 6 | 7 | 8 | class BaseTestCase(unittest.TestCase): 9 | 10 | debug = False 11 | 12 | def setUp(self): 13 | if self.debug: 14 | print("setUp") 15 | # end of setUp 16 | 17 | def tearDown(self): 18 | if self.debug: 19 | print("tearDown") 20 | # end of tearDown 21 | 22 | def fail_if_test_file_exists(self, 23 | test_file=None): 24 | assert(not os.path.exists(test_file)) 25 | # end of fail_if_test_file_exists 26 | 27 | # end of BaseTestCase 28 | -------------------------------------------------------------------------------- /tests/manual_logstash_test.py: -------------------------------------------------------------------------------- 1 | import os 2 | import logging 3 | from owasp_jenkins.log.setup_logging import setup_logging 4 | from owasp_jenkins.log.build_logstash_formatter import build_logstash_formatter 5 | 6 | setup_logging(logging.DEBUG) 7 | log = logging.getLogger("testing-logstash-setup") 8 | log.info("this was a test without the logstash handler enabled") 9 | build_logstash_formatter(log) 10 | log.info(("this message should show " 11 | "up in kibana - used logstash={}:{}") 12 | .format(os.getenv("LOGSTASH_HOST", "localhost"), 13 | os.getenv("LOGSTASH_PORT", "5000").strip().lstrip())) 14 | -------------------------------------------------------------------------------- /tests/test_functional.py: -------------------------------------------------------------------------------- 1 | from tests.base_test import BaseTestCase 2 | 3 | 4 | class FunctionalTest(BaseTestCase): 5 | 6 | def test_unittest_works(self): 7 | self.assertEqual(1, 1) 8 | # end of test_unittest_works 9 | 10 | # end of FunctionalTest 11 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = 3 | {2.7,3.4,3.5,3.6}-unit 4 | 5 | flake8 6 | flakeplus 7 | configcheck 8 | pydocstyle 9 | 10 | basepython = 11 | 2.7: python2.7 12 | 3.4: python3.4 13 | 3.5: python3.5 14 | 3.6: python3.6 15 | flake8,flakeplus,configcheck,pydocstyle: python3.5 16 | 17 | [testenv:pydocstyle] 18 | commands = 19 | pydocstyle {toxinidir}/tools 20 | 21 | [flake8] 22 | max-line-length = 160 23 | ignore = E126 24 | exclude = .tox/* 25 | 26 | [testenv:lint] 27 | deps = flake8 28 | commands = flake8 29 | --------------------------------------------------------------------------------