├── .DS_Store ├── .gitignore ├── LICENSE ├── README.md ├── com.polyhedral.security.testing.core.feature ├── .gitignore ├── build.properties ├── feature.xml └── pom.xml ├── com.polyhedral.security.testing.core ├── .gitignore ├── META-INF │ └── MANIFEST.MF ├── build.properties ├── contexts.xml ├── plugin.xml ├── pom.xml └── src │ └── com │ └── polyhedral │ └── security │ └── testing │ └── core │ ├── Activator.java │ └── preferences │ └── RootPreferencePage.java ├── com.polyhedral.security.testing.parent ├── .gitignore ├── ProjectBuildVersionRules.txt └── pom.xml ├── com.polyhedral.security.testing.site ├── .gitignore ├── category.xml ├── pom.xml └── site.xml ├── com.polyhedral.security.testing.zedattackproxy.feature ├── .gitignore ├── build.properties ├── feature.xml └── pom.xml ├── com.polyhedral.security.testing.zedattackproxy ├── .gitignore ├── META-INF │ └── MANIFEST.MF ├── build.properties ├── contexts.xml ├── icons │ ├── ZAP_logo.png │ ├── disabled │ │ ├── cancel_scan.gif │ │ ├── run_scan.gif │ │ ├── start.gif │ │ └── stop.gif │ └── enabled │ │ ├── cancel_scan.gif │ │ ├── run_scan.gif │ │ ├── start.gif │ │ └── stop.gif ├── lib │ ├── commons-lang3-3.4.jar │ ├── encoder-1.2.jar │ └── zap-api-v2-5.jar ├── plugin.xml ├── pom.xml └── src │ └── com │ └── polyhedral │ └── security │ └── testing │ └── zedattackproxy │ ├── Activator.java │ ├── actions │ ├── CancelZAPScanAction.java │ ├── RunZAPScanAction.java │ ├── ScanProgress.java │ ├── StartZAPAction.java │ ├── StopZAPAction.java │ ├── ZAPAction.java │ ├── jobs │ │ ├── CreatePopupMessageJob.java │ │ ├── SignalZAPEventJob.java │ │ ├── cancel │ │ │ ├── CancelZAPScanJob.java │ │ │ └── RunCancelZAPScanJob.java │ │ ├── runscan │ │ │ ├── ClearZAPJob.java │ │ │ ├── RunZAPScanJob.java │ │ │ ├── ScanStatus.java │ │ │ ├── ScanTarget.java │ │ │ ├── ZAPAscanJob.java │ │ │ ├── ZAPPolicyInfo.java │ │ │ ├── ZAPScanHelper.java │ │ │ ├── ZAPScanProgressJob.java │ │ │ ├── ZAPSetZAPLevelsJob.java │ │ │ └── ZAPSpiderJob.java │ │ ├── start │ │ │ ├── RunStartZAPJob.java │ │ │ └── StartZAPJob.java │ │ └── stop │ │ │ ├── RunZAPStopJob.java │ │ │ └── StopZAPJob.java │ └── menu │ │ ├── AbstractMenuToggle.java │ │ ├── ascan │ │ ├── AllowAttackOnStartToggle.java │ │ ├── ConfigureZapCsrfSettingsJob.java │ │ ├── HandleAntiCSRFTokensToggle.java │ │ ├── InjectPluginIdInHeaderToggle.java │ │ ├── RescanInAttackModeToggle.java │ │ └── ZAPConfigureCSRFSettingsDialog.java │ │ └── spider │ │ ├── ParseCommentsToggle.java │ │ ├── ParseGitToggle.java │ │ ├── ParseRobotsTxtToggle.java │ │ ├── ParseSitemapXmlToggle.java │ │ ├── ParseSvnEntriesToggle.java │ │ ├── PostFormToggle.java │ │ ├── ProcessFormToggle.java │ │ └── SendRefererHeaderToggle.java │ ├── events │ ├── IZAPEventHandler.java │ ├── IZAPEventListener.java │ ├── ZAPEventHandler.java │ └── ZAPEventType.java │ ├── preferences │ └── ZAPPreferencePage.java │ ├── utils │ └── ZAPHelper.java │ └── views │ ├── ZAPAlertThreshold.java │ ├── ZAPAttackStrength.java │ ├── ZAPPolicyEditor.java │ └── ZAPView.java └── images ├── .DS_Store ├── StartZAPIcon.png ├── ZAPConfiguration.png ├── ZAPScanProgress.png ├── ZAPScanResults.png ├── ZAPScanSettings-StartScanButton.png ├── ZAPScanSettings-StopZAPButton.png └── ZAPScanSettings.png /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/64ade5f56e7e9dce3e126f58194dc02ae461a437/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Package Files # 4 | *.war 5 | *.ear 6 | 7 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 8 | hs_err_pid* 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SecurityTesting # 2 | 3 | SecurityTesting is an open source IDE plugin designed to allow developers to run security testing tools from within their IDE. The following IDEs and tools are currently supported: 4 | 5 | ####IDE 6 | 7 | * Eclipse (Luna and Mars) 8 | 9 | ####Security Testing Tools 10 | 11 | * OWASP Zed Attack Proxy (v 2.4.x) 12 | 13 | # Installation # 14 | 15 | All of the SecurityTesting plugins are based on [Apache Maven](https://maven.apache.org) and require the [Eclipse Plugin Development Environment](http://www.eclipse.org/pde/) (PDE) features to be installed in your Eclipse IDE. 16 | 17 | The build process is relatively straightforward: 18 | 19 | 1. Download a copy of the source code from the GitHub repository. 20 | 2. Import all of the projects into Eclipse using the "import existing Maven project" feature. 21 | 3. Use the "maven install" goal on the imported projects in the following order: 22 | * com.polyhedral.security.testing.core 23 | * com.polyhedral.security.testing.core.feature 24 | * com.polyhedral.security.testing.zedattackproxy 25 | * com.polyhedral.security.testing.zedattackproxy.feature 26 | * com.polyhedral.security.testing.site 27 | 4. Use the “Install New Software…” feature in Eclipse to install the update site ZIP file generated in the **com.polyhedral.security.testing.site** build. 28 | 29 | # Zed Attack Proxy (ZAP) Configuration # 30 | Once the plugin has been installed, you will need to configure it with the location of your ZAP installation. To configure the ZAP plugin, go to: 31 | ``` 32 | Eclipse Preferences -> Security Testing -> Zed Attack Proxy. 33 | ``` 34 | 35 | ![ZAP Configuration in Eclipse](https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/master/images/ZAPConfiguration.png) 36 | 37 | The following information needs to be provided to configure the ZAP plugin and allow you to start a headless version of ZAP from the plugin: 38 | 39 | * **ZAP JAR Location -** This is the fully qualified path to the ZAP JAR file (e.g. /path/to/my/ZAP/install/zap-2.4.x.jar). 40 | * **ZAP Session Directory -** This is the fully qualified path to the directory where you want your ZAP instance to store its session data. Please Note: This directory needs to be write-enabled for your user account. 41 | * **ZAP Session Name -** This is the name of the session file that will be written to the **ZAP Session Directory**. Changing this name will create a new ZAP session file. 42 | * **ZAP Proxy Port -** The port on your computer where the ZAP instance will be running. This port needs to be available, or ZAP will fail to initialize on startup. 43 | * **ZAP API Key -** A randomized alphanumeric character string used by the ZAP API to authenticate valid requests. Without the API Key, a user cannot make calls to the ZAP API. 44 | 45 | **Please Note:** You can use the ZAP plugin to connect to an existing ZAP instance that is running on your PC. If you wish to connect to ZAP in this fashion, provide the existing **ZAP Proxy Port** and **ZAP API Key** stored in the ZAP GUI's configuration. 46 | 47 | Once you have entered your ZAP plugin configuration, save the changes and exit the Eclipse Preferences screen. 48 | 49 | # ZAP Startup # 50 | 51 | Once you have your ZAP configuration in place, you can start ZAP in headless mode using the plugin. First, you need to open the ZAP Eclipse View. It is located under: 52 | ``` 53 | Window -> Show View -> Other... -> Security Testing -> ZAP Scanner 54 | ``` 55 | You will see a blank ZAP Scanner view panel open, with the **Start ZAP Server** button (a green triangle icon) activated, as seen in the image below. If you have not provided all of the required ZAP configuration, then all of the activity buttons will be disabled. 56 | 57 | ![ZAP Scanner Ready for Startup](https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/master/images/StartZAPIcon.png) 58 | 59 | Click on the **Start ZAP Server** button and the Eclipse Console will begin logging activity as a headless instance of the ZAP scanner is started. Once ZAP has fully initialized, the ZAP Scanner view panel will populate with the scan parameter view, as seen in the image below. 60 | 61 | ![ZAP Scanner Parameter View](https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/master/images/ZAPScanSettings.png) 62 | 63 | The ZAP Scanner parameter view allows you to provide the following information for performing a ZAP scan against a web application: 64 | 65 | * **Scan Target URL -** This is the root URL of the web application you want ZAP to scan and test. 66 | * **Scan Result File -** This is the base name for the results files that will be generated by the scan results. Two files will be generated after every scan, and the **Scan Result File** is used to allow multiple scan results to be stored at a given time. Please Note: When starting a new scan, if a result file already exists that matches the **Scan Result File** name, the plugin will prompt you to confirm whether you want to overwrite the existing file with the new scan results. 67 | * **Report Format -** The format of the ZAP active scan results. Every scan will generate two files. A text file containing the results of the spider, and either an XML or HTML file with the results of the active scan based on which **Report Format** option is selected. 68 | * **Policy/Attack Strength/Alert Threshold -** ZAP is configured with multiple scan policies which will all be run during the active scan. For each scan policy, you can choose the strength of the attack for that policy and the threshold severity for when the scan should report a finding. The configuration options are as follows: 69 | * **Attack Strength -** DEFAULT, LOW, MEDIUM, HIGH, and INSANE 70 | * **Alert Threshold -** OFF, DEFAULT, LOW, MEDIUM, and HIGH 71 | 72 | # ZAP Execution # 73 | Once you have provided all of the parameters in the ZAP Scanner parameter view, you are now ready to start your scan. At the top of the ZAP Scanner parameter view, you will see the **Run ZAP Spider/Ascan** button (a yellow flashlight icon), as seen in the image below. Click on the **Run ZAP Spider/Ascan** button to start the scan. 74 | 75 | ![Start ZAP Scan Button](https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/master/images/ZAPScanSettings-StartScanButton.png) 76 | 77 | Once the scan has started, the ZAP Scanner view will switch to a progress tracker, as seen in the image below. If for some reason you decide that you need to cancel the currently running scan, you can click on the **Cancel ZAP Spider/Ascan** button (the red X icon) to stop the current scan and return to the ZAP Scanner parameter view. 78 | 79 | ![ZAP Scan Progress Tracker and Cancel Button](https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/master/images/ZAPScanProgress.png) 80 | 81 | After the scan has completed, you will be returned to the ZAP Scanner parameter view. Additionally, the results of your scan will be dumped into files in an Eclipse project called **SecurityTesting** under the **ZAPScanResults** folder, as seen in the image below. These files contain the spider and scan results from all of your ZAP plugin runs, so make sure to find the files that start with the correct **Scan Result File** name. 82 | 83 | ![ZAP Scan Results Project](https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/master/images/ZAPScanResults.png) 84 | 85 | # ZAP Shutdown # 86 | When the plugin starts the headless ZAP server instance, it is created as an independent process. As such, it will not automatically be shutdown when you close Eclipse. In order to prevent your ZAP server process from continuing to run until you shut down your computer, you can click on the **Stop ZAP Server** button (the red square icon) from the ZAP Scanner parameter view. This will shut down the headless ZAP server instance and return the ZAP Server view to the original blank startup view. 87 | 88 | ![ZAP Server Shutdown Button](https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/master/images/ZAPScanSettings-StopZAPButton.png) 89 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.core.feature/.gitignore: -------------------------------------------------------------------------------- 1 | /.settings/ 2 | /.project 3 | /target/ 4 | /bin/ 5 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.core.feature/build.properties: -------------------------------------------------------------------------------- 1 | bin.includes = feature.xml 2 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.core.feature/feature.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | Core feature to access the Security Testing tools plugin suite. 10 | 11 | 12 | 13 | Copyright (C) 2015 Polyhedral Technologies LLC 14 | 15 | Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 16 | 17 | 18 | 19 | This program is free software; you can redistribute it and/or modify it under the terms of the Apache License, Version 2.0. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Apache License, Version 2.0 for more details. 20 | 21 | 22 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.core.feature/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.polyhedral.security.testing 8 | com.polyhedral.security.testing.parent 9 | 0.3.5.RELEASE 10 | ../com.polyhedral.security.testing.parent/pom.xml 11 | 12 | com.polyhedral.security.testing.core.feature 13 | eclipse-feature 14 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.core/.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | /.settings/ 3 | /.project 4 | /target/ 5 | /.classpath 6 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.core/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Bundle-ManifestVersion: 2 3 | Bundle-Name: SecurityTestingPlugin-Core 4 | Bundle-SymbolicName: com.polyhedral.security.testing.core;singleton:=true 5 | Bundle-Version: 0.3.5.RELEASE 6 | Bundle-Activator: com.polyhedral.security.testing.core.Activator 7 | Bundle-Vendor: Polyhedral Technologies LLC 8 | Require-Bundle: org.eclipse.ui, 9 | org.eclipse.core.runtime 10 | Bundle-RequiredExecutionEnvironment: JavaSE-1.7 11 | Bundle-ActivationPolicy: lazy 12 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.core/build.properties: -------------------------------------------------------------------------------- 1 | source.. = src/ 2 | output.. = target/classes/ 3 | bin.includes = plugin.xml,\ 4 | META-INF/,\ 5 | .,\ 6 | contexts.xml 7 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.core/contexts.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.core/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 9 | 10 | 11 | 13 | 15 | 16 | 17 | 18 | 20 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.polyhedral.security.testing 8 | com.polyhedral.security.testing.parent 9 | 0.3.5.RELEASE 10 | ../com.polyhedral.security.testing.parent/pom.xml 11 | 12 | com.polyhedral.security.testing.core 13 | eclipse-plugin 14 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.core/src/com/polyhedral/security/testing/core/Activator.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.core; 2 | 3 | import org.eclipse.jface.resource.ImageDescriptor; 4 | import org.eclipse.ui.plugin.AbstractUIPlugin; 5 | import org.osgi.framework.BundleContext; 6 | 7 | /** 8 | * The activator class controls the plug-in life cycle 9 | */ 10 | public class Activator extends AbstractUIPlugin { 11 | 12 | // The plug-in ID 13 | public static final String PLUGIN_ID = "com.polyhedral.security.testing.core"; //$NON-NLS-1$ 14 | 15 | // The shared instance 16 | private static Activator plugin; 17 | 18 | /** 19 | * The constructor 20 | */ 21 | public Activator() { 22 | } 23 | 24 | /* 25 | * (non-Javadoc) 26 | * 27 | * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework. 28 | * BundleContext) 29 | */ 30 | public void start(BundleContext context) throws Exception { 31 | super.start(context); 32 | plugin = this; 33 | } 34 | 35 | /* 36 | * (non-Javadoc) 37 | * 38 | * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework. 39 | * BundleContext) 40 | */ 41 | public void stop(BundleContext context) throws Exception { 42 | plugin = null; 43 | super.stop(context); 44 | } 45 | 46 | /** 47 | * Returns the shared instance 48 | * 49 | * @return the shared instance 50 | */ 51 | public static Activator getDefault() { 52 | return plugin; 53 | } 54 | 55 | /** 56 | * Returns an image descriptor for the image file at the given plug-in 57 | * relative path 58 | * 59 | * @param path 60 | * the path 61 | * @return the image descriptor 62 | */ 63 | public static ImageDescriptor getImageDescriptor(String path) { 64 | return imageDescriptorFromPlugin(PLUGIN_ID, path); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.core/src/com/polyhedral/security/testing/core/preferences/RootPreferencePage.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.core.preferences; 2 | 3 | import org.eclipse.jface.preference.FieldEditorPreferencePage; 4 | import org.eclipse.ui.IWorkbench; 5 | import org.eclipse.ui.IWorkbenchPreferencePage; 6 | 7 | /** 8 | * Root preference page for Security Testing preferences. This page does not 9 | * contain any content, but will be used as the parent page for all other 10 | * Security Testing preference pages. 11 | */ 12 | public class RootPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage { 13 | 14 | @Override 15 | public void init(IWorkbench arg0) { 16 | setDescription("Expand the tree to provide configuration for the supported security testing tools."); 17 | } 18 | 19 | @Override 20 | protected void createFieldEditors() { 21 | // no field editors, this is a blank screen 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.parent/.gitignore: -------------------------------------------------------------------------------- 1 | /.settings/ 2 | /.project 3 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.parent/ProjectBuildVersionRules.txt: -------------------------------------------------------------------------------- 1 | Because OSGi and Maven have differing rules about which version is "larger" when using a qualifier (such as 2 | SNAPSHOT) for performing development builds, the Security Testing project is going to take the following 3 | version convention: 4 | 5 | - Development builds will use -SNAPSHOT for Maven-related artifacts and X.X.X.qualifier for OSGi artifacts. 6 | - Release builds will replace -SNAPSHOT with .RELEASE and X.X.X.RELEASE (no qualifier) for OSGi artifacts. 7 | 8 | The following configuration items need to be updated with the correct version information when switching 9 | from development to release build versioning: 10 | 11 | All Eclipse Projects 12 | - pom.xml -> tag (can exist in multiple places if version differs from parent) 13 | 14 | Eclipse Plugin Projects 15 | - MANIFEST.MF -> Bundle-Version tag 16 | 17 | Eclipse Feature Projects 18 | - feature.xml -> version tag (can exist in multiple places) 19 | 20 | Eclipse Update Site Projects 21 | - category.xml -> url tag (can exist in multiple places) 22 | -> version tag (can exist in multiple places) 23 | - site.xml -> url tag (can exist in multiple places) 24 | -> version tag (can exist in multiple places) -------------------------------------------------------------------------------- /com.polyhedral.security.testing.parent/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | com.polyhedral.security.testing 7 | com.polyhedral.security.testing.parent 8 | 0.3.5.RELEASE 9 | pom 10 | Security Testing Tools - IDE Integration 11 | 12 | 13 | 3.0 14 | 15 | 16 | 17 | 0.23.1 18 | 19 | 20 | UTF-8 21 | UTF-8 22 | 23 | 24 | 25 | 26 | ../com.polyhedral.security.testing.core 27 | ../com.polyhedral.security.testing.core.feature 28 | 29 | 30 | ../com.polyhedral.security.testing.zedattackproxy 31 | ../com.polyhedral.security.testing.zedattackproxy.feature 32 | 33 | 34 | ../com.polyhedral.security.testing.site 35 | 36 | 37 | 38 | 39 | 40 | mars 41 | http://download.eclipse.org/releases/mars/ 42 | p2 43 | 44 | 45 | 46 | 47 | 48 | 49 | org.eclipse.tycho 50 | tycho-maven-plugin 51 | ${tycho-version} 52 | true 53 | 54 | 55 | org.eclipse.tycho 56 | tycho-compiler-plugin 57 | ${tycho-version} 58 | 59 | 1.7 60 | 1.7 61 | 62 | 63 | 64 | org.eclipse.tycho 65 | target-platform-configuration 66 | ${tycho-version} 67 | 68 | 69 | 70 | linux 71 | gtk 72 | x86 73 | 74 | 75 | linux 76 | gtk 77 | x86_64 78 | 79 | 80 | win32 81 | win32 82 | x86 83 | 84 | 85 | win32 86 | win32 87 | x86_64 88 | 89 | 90 | macosx 91 | cocoa 92 | x86_64 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.site/.gitignore: -------------------------------------------------------------------------------- 1 | /features/ 2 | /plugins/ 3 | /artifacts.jar 4 | /content.jar 5 | /.settings/ 6 | /.project 7 | /target/ 8 | /bin/ 9 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.site/category.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Security testing tools for Eclipse. 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Security Testing 15 | 16 | 17 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.site/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.polyhedral.security.testing 8 | com.polyhedral.security.testing.parent 9 | 0.3.5.RELEASE 10 | ../com.polyhedral.security.testing.parent/pom.xml 11 | 12 | com.polyhedral.security.testing.site 13 | eclipse-repository 14 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.site/site.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy.feature/.gitignore: -------------------------------------------------------------------------------- 1 | /.settings/ 2 | /.project 3 | /target/ 4 | /bin/ 5 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy.feature/build.properties: -------------------------------------------------------------------------------- 1 | bin.includes = feature.xml 2 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy.feature/feature.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | A plugin to access the ZAP API features and run a Spider and Ascan against any target URL, with options to configure many standard Spider and Ascan features. 10 | 11 | 12 | 13 | Copyright (C) 2015 Polyhedral Technologies LLC 14 | 15 | Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 16 | 17 | 18 | 19 | Disclaimer: This program is a wrapper for the Zed Attack Proxy product produced and distributed by OWASP. You should only use this software to test the security of your own web application or those you are authorized to do so. The authors of this product take no responsibility for any problems in relation to running OWASP ZAP against any applications or machines. 20 | 21 | This program is free software; you can redistribute it and/or modify it under the terms of the Apache License, Version 2.0. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Apache License, Version 2.0 for more details. 22 | 23 | OWASP ZAP is a fork of the open source Paros Proxy product developed by Chinotec Technologies Company. The Paros Proxy is Copyright (C) 2003-2005 Chiotec Technologies Company and is licensed under the Clarified Artistic License as published by the Free Software Foundation. 24 | 25 | This product includes software developed by the Apache Software Foundation licensed under Apache License 2.0. HSQLDB is licensed under BSD license. JDIC is licensed by Sun Microsystems, Inc. under the LGPL license. OWASP ZAP also contains BeanShell, which is licensed under LGPL. The Copyrights of these softwares belong to their respective owners. 26 | 27 | 28 | 29 | 30 | 31 | 32 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy.feature/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.polyhedral.security.testing 8 | com.polyhedral.security.testing.parent 9 | 0.3.5.RELEASE 10 | ../com.polyhedral.security.testing.parent/pom.xml 11 | 12 | com.polyhedral.security.testing.zedattackproxy.feature 13 | eclipse-feature 14 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | /.settings/ 3 | /.project 4 | /target/ 5 | /.classpath 6 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Bundle-ManifestVersion: 2 3 | Bundle-Name: SecurityTestingPlugin-ZedAttackProxy 4 | Bundle-SymbolicName: com.polyhedral.security.testing.zedattackproxy;singleton:=true 5 | Bundle-Version: 0.3.5.RELEASE 6 | Bundle-Activator: com.polyhedral.security.testing.zedattackproxy.Activator 7 | Bundle-Vendor: Polyhedral Technologies LLC 8 | Require-Bundle: org.eclipse.ui, 9 | org.eclipse.core.runtime, 10 | org.eclipse.jdt.core, 11 | org.eclipse.debug.core, 12 | org.eclipse.jdt.launching, 13 | org.eclipse.ui.console, 14 | org.eclipse.text, 15 | com.polyhedral.security.testing.core 16 | Bundle-RequiredExecutionEnvironment: JavaSE-1.7 17 | Bundle-ActivationPolicy: lazy 18 | Bundle-ClassPath: ., 19 | lib/zap-api-v2-5.jar, 20 | lib/encoder-1.2.jar, 21 | lib/commons-lang3-3.4.jar 22 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/build.properties: -------------------------------------------------------------------------------- 1 | source.. = src/ 2 | output.. = target/classes/ 3 | bin.includes = plugin.xml,\ 4 | META-INF/,\ 5 | .,\ 6 | icons/,\ 7 | contexts.xml,\ 8 | lib/zap-api-v2-5.jar,\ 9 | lib/encoder-1.2.jar,\ 10 | lib/commons-lang3-3.4.jar 11 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/contexts.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/icons/ZAP_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/64ade5f56e7e9dce3e126f58194dc02ae461a437/com.polyhedral.security.testing.zedattackproxy/icons/ZAP_logo.png -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/icons/disabled/cancel_scan.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/64ade5f56e7e9dce3e126f58194dc02ae461a437/com.polyhedral.security.testing.zedattackproxy/icons/disabled/cancel_scan.gif -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/icons/disabled/run_scan.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/64ade5f56e7e9dce3e126f58194dc02ae461a437/com.polyhedral.security.testing.zedattackproxy/icons/disabled/run_scan.gif -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/icons/disabled/start.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/64ade5f56e7e9dce3e126f58194dc02ae461a437/com.polyhedral.security.testing.zedattackproxy/icons/disabled/start.gif -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/icons/disabled/stop.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/64ade5f56e7e9dce3e126f58194dc02ae461a437/com.polyhedral.security.testing.zedattackproxy/icons/disabled/stop.gif -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/icons/enabled/cancel_scan.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/64ade5f56e7e9dce3e126f58194dc02ae461a437/com.polyhedral.security.testing.zedattackproxy/icons/enabled/cancel_scan.gif -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/icons/enabled/run_scan.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/64ade5f56e7e9dce3e126f58194dc02ae461a437/com.polyhedral.security.testing.zedattackproxy/icons/enabled/run_scan.gif -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/icons/enabled/start.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/64ade5f56e7e9dce3e126f58194dc02ae461a437/com.polyhedral.security.testing.zedattackproxy/icons/enabled/start.gif -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/icons/enabled/stop.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/64ade5f56e7e9dce3e126f58194dc02ae461a437/com.polyhedral.security.testing.zedattackproxy/icons/enabled/stop.gif -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/lib/commons-lang3-3.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/64ade5f56e7e9dce3e126f58194dc02ae461a437/com.polyhedral.security.testing.zedattackproxy/lib/commons-lang3-3.4.jar -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/lib/encoder-1.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/64ade5f56e7e9dce3e126f58194dc02ae461a437/com.polyhedral.security.testing.zedattackproxy/lib/encoder-1.2.jar -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/lib/zap-api-v2-5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/64ade5f56e7e9dce3e126f58194dc02ae461a437/com.polyhedral.security.testing.zedattackproxy/lib/zap-api-v2-5.jar -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 12 | 13 | 14 | 16 | 18 | 19 | 20 | 21 | 23 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.polyhedral.security.testing 8 | com.polyhedral.security.testing.parent 9 | 0.3.5.RELEASE 10 | ../com.polyhedral.security.testing.parent/pom.xml 11 | 12 | com.polyhedral.security.testing.zedattackproxy 13 | eclipse-plugin 14 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/Activator.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy; 2 | 3 | import org.eclipse.jface.resource.ImageDescriptor; 4 | import org.eclipse.ui.plugin.AbstractUIPlugin; 5 | import org.osgi.framework.BundleContext; 6 | 7 | /** 8 | * The activator class controls the plug-in life cycle 9 | */ 10 | public class Activator extends AbstractUIPlugin { 11 | 12 | // The plug-in ID 13 | public static final String PLUGIN_ID = "com.polyhedral.security.testing.zedattackproxy"; //$NON-NLS-1$ 14 | 15 | // The shared instance 16 | private static Activator plugin; 17 | 18 | /** 19 | * The constructor 20 | */ 21 | public Activator() { 22 | } 23 | 24 | /* 25 | * (non-Javadoc) 26 | * 27 | * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework. 28 | * BundleContext) 29 | */ 30 | public void start(BundleContext context) throws Exception { 31 | super.start(context); 32 | plugin = this; 33 | } 34 | 35 | /* 36 | * (non-Javadoc) 37 | * 38 | * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework. 39 | * BundleContext) 40 | */ 41 | public void stop(BundleContext context) throws Exception { 42 | plugin = null; 43 | super.stop(context); 44 | } 45 | 46 | /** 47 | * Returns the shared instance 48 | * 49 | * @return the shared instance 50 | */ 51 | public static Activator getDefault() { 52 | return plugin; 53 | } 54 | 55 | /** 56 | * Returns an image descriptor for the image file at the given plug-in 57 | * relative path 58 | * 59 | * @param path 60 | * the path 61 | * @return the image descriptor 62 | */ 63 | public static ImageDescriptor getImageDescriptor(String path) { 64 | return imageDescriptorFromPlugin(PLUGIN_ID, path); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/CancelZAPScanAction.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions; 2 | 3 | import java.net.MalformedURLException; 4 | import java.net.URL; 5 | 6 | import org.eclipse.core.runtime.jobs.Job; 7 | import org.eclipse.jface.resource.ImageDescriptor; 8 | import org.eclipse.ui.PlatformUI; 9 | import org.eclipse.ui.console.ConsolePlugin; 10 | 11 | import com.polyhedral.security.testing.zedattackproxy.actions.jobs.cancel.RunCancelZAPScanJob; 12 | 13 | /** 14 | * Eclipse {@link Action} for canceling a running ZAP scan. 15 | */ 16 | public class CancelZAPScanAction extends ZAPAction { 17 | 18 | /** 19 | * Default constructor. Set the enabled/disabled icons for the action and 20 | * the tool tip text. 21 | */ 22 | public CancelZAPScanAction() { 23 | try { 24 | this.setImageDescriptor(ImageDescriptor.createFromURL(new URL( 25 | "platform:/plugin/com.polyhedral.security.testing.zedattackproxy/icons/enabled/cancel_scan.gif"))); 26 | this.setDisabledImageDescriptor(ImageDescriptor.createFromURL(new URL( 27 | "platform:/plugin/com.polyhedral.security.testing.zedattackproxy/icons/disabled/cancel_scan.gif"))); 28 | this.setToolTipText("Cancel ZAP Spider/Ascan"); 29 | } catch (MalformedURLException e) { 30 | ConsolePlugin.log(e); 31 | } 32 | } 33 | 34 | /** 35 | * {@link Job} to be performed when this action is clicked on. 36 | */ 37 | @Override 38 | public void run() { 39 | Job tempJob = new RunCancelZAPScanJob("Cancelling ZAP Scan...", PlatformUI.getWorkbench().getDisplay(), 40 | getZAPEventHandler()); 41 | tempJob.setPriority(Job.LONG); 42 | tempJob.schedule(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/RunZAPScanAction.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions; 2 | 3 | import java.net.URL; 4 | 5 | import org.eclipse.core.runtime.jobs.Job; 6 | import org.eclipse.jface.resource.ImageDescriptor; 7 | import org.eclipse.ui.PlatformUI; 8 | import org.eclipse.ui.console.ConsolePlugin; 9 | 10 | import com.polyhedral.security.testing.zedattackproxy.actions.jobs.runscan.RunZAPScanJob; 11 | import com.polyhedral.security.testing.zedattackproxy.actions.jobs.runscan.ScanTarget; 12 | import com.polyhedral.security.testing.zedattackproxy.views.ZAPView; 13 | 14 | /** 15 | * Eclipse {@link Action} for starting a new scan in ZAP. 16 | */ 17 | public class RunZAPScanAction extends ZAPAction { 18 | 19 | private ZAPView zapView; 20 | private RunZAPScanJob runZapScanJob; 21 | 22 | /** 23 | * Default constructor. Set the enabled/disabled icons for the action and 24 | * the tool tip text. 25 | */ 26 | public RunZAPScanAction() { 27 | try { 28 | this.setImageDescriptor(ImageDescriptor.createFromURL(new URL( 29 | "platform:/plugin/com.polyhedral.security.testing.zedattackproxy/icons/enabled/run_scan.gif"))); 30 | this.setDisabledImageDescriptor(ImageDescriptor.createFromURL(new URL( 31 | "platform:/plugin/com.polyhedral.security.testing.zedattackproxy/icons/disabled/run_scan.gif"))); 32 | this.setToolTipText("Run ZAP Spider/Ascan"); 33 | } catch (Exception e) { 34 | ConsolePlugin.log(e); 35 | } 36 | } 37 | 38 | /** 39 | * Set the ZAP view so that it can be interacted with later. 40 | * 41 | * @param zapView 42 | * The ZAP view to be set. 43 | */ 44 | public void setZapView(ZAPView zapView) { 45 | this.zapView = zapView; 46 | } 47 | 48 | /** 49 | * {@link Job} to be performed when this action is clicked on. 50 | */ 51 | @Override 52 | public void run() { 53 | runZapScanJob = new RunZAPScanJob("Run Zed Attack Proxy Scan...", PlatformUI.getWorkbench().getDisplay(), 54 | new ScanTarget(zapView.getFileNameText(), zapView.getUrlText(), zapView.getReportFormat(), 55 | zapView.getZapPolicyList()), 56 | getZAPEventHandler()); 57 | runZapScanJob.setPriority(Job.LONG); 58 | runZapScanJob.schedule(); 59 | } 60 | 61 | /** 62 | * Indicator that the current scan was stopped by the cancel scan action. 63 | * Call to the scan job and cancel its operation. 64 | */ 65 | public void cancelScan() { 66 | if (runZapScanJob != null) { 67 | runZapScanJob.cancelScan(); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/ScanProgress.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions; 2 | 3 | /** 4 | * Progress information for a running ZAP spider/ascan. 5 | */ 6 | public class ScanProgress { 7 | private String ascanId; 8 | private String spiderId; 9 | 10 | public String getAscanId() { 11 | return ascanId; 12 | } 13 | 14 | public String getSpiderId() { 15 | return spiderId; 16 | } 17 | 18 | public void setAscanId(String ascanId) { 19 | this.ascanId = ascanId; 20 | } 21 | 22 | public void setSpiderId(String spiderId) { 23 | this.spiderId = spiderId; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/StartZAPAction.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions; 2 | 3 | import java.net.URL; 4 | 5 | import org.eclipse.core.runtime.jobs.Job; 6 | import org.eclipse.jface.resource.ImageDescriptor; 7 | import org.eclipse.ui.PlatformUI; 8 | import org.eclipse.ui.console.ConsolePlugin; 9 | 10 | import com.polyhedral.security.testing.zedattackproxy.actions.jobs.start.RunStartZAPJob; 11 | 12 | /** 13 | * Eclipse {@link Action} for starting the ZAP server. 14 | */ 15 | public class StartZAPAction extends ZAPAction { 16 | 17 | /** 18 | * Default constructor. Set the enabled/disabled icons for the action and 19 | * the tool tip text. 20 | */ 21 | public StartZAPAction() { 22 | try { 23 | this.setImageDescriptor(ImageDescriptor.createFromURL(new URL( 24 | "platform:/plugin/com.polyhedral.security.testing.zedattackproxy/icons/enabled/start.gif"))); 25 | this.setDisabledImageDescriptor(ImageDescriptor.createFromURL(new URL( 26 | "platform:/plugin/com.polyhedral.security.testing.zedattackproxy/icons/disabled/start.gif"))); 27 | this.setToolTipText("Start ZAP Server"); 28 | } catch (Exception e) { 29 | ConsolePlugin.log(e); 30 | } 31 | } 32 | 33 | /** 34 | * {@link Job} to be performed when this action is clicked on. 35 | */ 36 | @Override 37 | public void run() { 38 | Job runStartZAPJob = new RunStartZAPJob("Starting Zed Attack Proxy...", PlatformUI.getWorkbench().getDisplay(), 39 | getZAPEventHandler()); 40 | runStartZAPJob.setPriority(Job.LONG); 41 | runStartZAPJob.schedule(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/StopZAPAction.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions; 2 | 3 | import java.net.URL; 4 | 5 | import org.eclipse.core.runtime.jobs.Job; 6 | import org.eclipse.jface.resource.ImageDescriptor; 7 | import org.eclipse.ui.PlatformUI; 8 | import org.eclipse.ui.console.ConsolePlugin; 9 | 10 | import com.polyhedral.security.testing.zedattackproxy.actions.jobs.stop.RunZAPStopJob; 11 | 12 | /** 13 | * Eclipse {@link Action} for stopping the ZAP server. 14 | */ 15 | public class StopZAPAction extends ZAPAction { 16 | 17 | /** 18 | * Default constructor. Set the enabled/disabled icons for the action and 19 | * the tool tip text. 20 | */ 21 | public StopZAPAction() { 22 | try { 23 | this.setImageDescriptor(ImageDescriptor.createFromURL( 24 | new URL("platform:/plugin/com.polyhedral.security.testing.zedattackproxy/icons/enabled/stop.gif"))); 25 | this.setDisabledImageDescriptor(ImageDescriptor.createFromURL(new URL( 26 | "platform:/plugin/com.polyhedral.security.testing.zedattackproxy/icons/disabled/stop.gif"))); 27 | this.setToolTipText("Stop ZAP Server"); 28 | } catch (Exception e) { 29 | ConsolePlugin.log(e); 30 | } 31 | } 32 | 33 | /** 34 | * {@link Job} to be performed when this action is clicked on. 35 | */ 36 | @Override 37 | public void run() { 38 | Job runZapStopJob = new RunZAPStopJob("Stopping Zed Attack Proxy...", PlatformUI.getWorkbench().getDisplay(), 39 | getZAPEventHandler()); 40 | runZapStopJob.setPriority(Job.LONG); 41 | runZapStopJob.schedule(); 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/ZAPAction.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions; 2 | 3 | import org.eclipse.jface.action.Action; 4 | 5 | import com.polyhedral.security.testing.zedattackproxy.events.IZAPEventHandler; 6 | import com.polyhedral.security.testing.zedattackproxy.events.IZAPEventListener; 7 | import com.polyhedral.security.testing.zedattackproxy.events.ZAPEventHandler; 8 | 9 | /** 10 | * Base class for all ZAP actions. Includes support for the 11 | * {@link IZAPEventHandler} interface. 12 | */ 13 | public abstract class ZAPAction extends Action implements IZAPEventHandler { 14 | 15 | private ZAPEventHandler zapEventHandler = new ZAPEventHandler(); 16 | 17 | /** 18 | * Add a new ZAP event listener. 19 | */ 20 | @Override 21 | public void addZAPEventListener(IZAPEventListener listener) { 22 | zapEventHandler.addZAPEventListener(listener); 23 | } 24 | 25 | /** 26 | * Remove a ZAP event listener. 27 | */ 28 | @Override 29 | public void removeZAPEventListener(IZAPEventListener listener) { 30 | zapEventHandler.removeZAPEventListener(listener); 31 | } 32 | 33 | /** 34 | * Get the ZAP event handler to be passed on to ZAP actions for additional 35 | * processing. 36 | * 37 | * @return The ZAP event handler. 38 | */ 39 | protected ZAPEventHandler getZAPEventHandler() { 40 | return this.zapEventHandler; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/jobs/CreatePopupMessageJob.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.jobs; 2 | 3 | import org.eclipse.core.runtime.IProgressMonitor; 4 | import org.eclipse.core.runtime.IStatus; 5 | import org.eclipse.core.runtime.Status; 6 | import org.eclipse.jface.dialogs.MessageDialog; 7 | import org.eclipse.swt.SWT; 8 | import org.eclipse.ui.PlatformUI; 9 | import org.eclipse.ui.progress.UIJob; 10 | 11 | /** 12 | * Eclipse {@link UIJob} for creating a popup message to communicate information 13 | * to the user. 14 | */ 15 | public class CreatePopupMessageJob extends UIJob { 16 | 17 | private int popupType; 18 | private String message; 19 | 20 | /** 21 | * Default constructor. 22 | * 23 | * @param popupType 24 | * The type of popup to be created. Some options include 25 | * confirmation, warning, and error popups. 26 | * @param message 27 | * The message of the popup window. 28 | */ 29 | public CreatePopupMessageJob(int popupType, String message) { 30 | super(""); 31 | this.popupType = popupType; 32 | this.message = message; 33 | } 34 | 35 | /** 36 | * Execution of the popup window job using the Eclipse {@link MessageDialog} 37 | * feature. 38 | */ 39 | @Override 40 | public IStatus runInUIThread(IProgressMonitor monitor) { 41 | if (MessageDialog.open(popupType, PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), 42 | "ZAP Scanner", message, SWT.NONE)) { 43 | return Status.OK_STATUS; 44 | } else { 45 | return Status.CANCEL_STATUS; 46 | } 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/jobs/SignalZAPEventJob.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.jobs; 2 | 3 | import org.eclipse.core.runtime.IProgressMonitor; 4 | import org.eclipse.core.runtime.IStatus; 5 | import org.eclipse.core.runtime.Status; 6 | import org.eclipse.swt.widgets.Display; 7 | import org.eclipse.ui.progress.UIJob; 8 | 9 | import com.polyhedral.security.testing.zedattackproxy.events.ZAPEventHandler; 10 | import com.polyhedral.security.testing.zedattackproxy.events.ZAPEventType; 11 | 12 | /** 13 | * Eclipse {@link UIJob} used to signal a ZAP event has happened in the plugin. 14 | * This event includes possible updates to the ZAP view action buttons and ZAP 15 | * view content. 16 | */ 17 | public class SignalZAPEventJob extends UIJob { 18 | 19 | private ZAPEventType event; 20 | private ZAPEventHandler eventHandler; 21 | 22 | /** 23 | * Default constructor. 24 | * 25 | * @param jobDisplay 26 | * The {@link Display} where the event will update content. 27 | * @param name 28 | * The name to be displayed in the Eclipse progress view while 29 | * this is executing. 30 | * @param event 31 | * The signal event that is taking place. 32 | * @param eventHandler 33 | * The event handler that will manage the signal event. 34 | */ 35 | public SignalZAPEventJob(Display jobDisplay, String name, ZAPEventType event, ZAPEventHandler eventHandler) { 36 | super(jobDisplay, name); 37 | this.event = event; 38 | this.eventHandler = eventHandler; 39 | } 40 | 41 | /** 42 | * Execution of the signal ZAP event job. 43 | */ 44 | @Override 45 | public IStatus runInUIThread(IProgressMonitor monitor) { 46 | eventHandler.fireZAPEvent(event); 47 | return Status.OK_STATUS; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/jobs/cancel/CancelZAPScanJob.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.jobs.cancel; 2 | 3 | import org.eclipse.core.runtime.IProgressMonitor; 4 | import org.eclipse.core.runtime.IStatus; 5 | import org.eclipse.core.runtime.Status; 6 | import org.eclipse.core.runtime.jobs.Job; 7 | import org.eclipse.ui.console.ConsolePlugin; 8 | import org.zaproxy.clientapi.core.ClientApi; 9 | import org.zaproxy.clientapi.core.ClientApiException; 10 | 11 | import com.polyhedral.security.testing.zedattackproxy.utils.ZAPHelper; 12 | 13 | /** 14 | * Eclipse {@link Job} for calling ZAp to cancel a running ZAP scan. 15 | */ 16 | public class CancelZAPScanJob extends Job { 17 | 18 | /** 19 | * Default constructor. 20 | * 21 | * @param name 22 | * The name to be displayed in the Eclipse progress view while 23 | * this is executing. 24 | */ 25 | public CancelZAPScanJob(String name) { 26 | super(name); 27 | } 28 | 29 | /** 30 | * Execution of the call to ZAP to stop the current scan. 31 | */ 32 | @Override 33 | protected IStatus run(IProgressMonitor monitor) { 34 | try { 35 | ClientApi zapAPI = ZAPHelper.getInstance().getZAPClient(); 36 | 37 | /* 38 | * TODO [On Hold] There is a defect in ZAP 2.4.1 where calling 39 | * stopAllScans on the spider process locks up ZAP if there is an 40 | * active spider. Disable this feature until this is resolved. 41 | */ 42 | // zapAPI.spider.stopAllScans(ZAPHelper.getInstance().getZapApiKey()); 43 | 44 | zapAPI.ascan.stopAllScans(ZAPHelper.getInstance().getZapApiKey()); 45 | Thread.sleep(5000); // give the scans time to stop 46 | } catch (ClientApiException | InterruptedException e) { 47 | ConsolePlugin.log(e); 48 | } 49 | 50 | return Status.OK_STATUS; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/jobs/cancel/RunCancelZAPScanJob.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.jobs.cancel; 2 | 3 | import org.eclipse.core.runtime.IProgressMonitor; 4 | import org.eclipse.core.runtime.IStatus; 5 | import org.eclipse.core.runtime.Status; 6 | import org.eclipse.core.runtime.jobs.Job; 7 | import org.eclipse.swt.widgets.Display; 8 | import org.eclipse.ui.console.ConsolePlugin; 9 | 10 | import com.polyhedral.security.testing.zedattackproxy.actions.CancelZAPScanAction; 11 | import com.polyhedral.security.testing.zedattackproxy.actions.jobs.SignalZAPEventJob; 12 | import com.polyhedral.security.testing.zedattackproxy.events.ZAPEventHandler; 13 | import com.polyhedral.security.testing.zedattackproxy.events.ZAPEventType; 14 | 15 | /** 16 | * Top-level Eclipse {@link Job} called by {@link CancelZAPScanAction}. 17 | */ 18 | public class RunCancelZAPScanJob extends Job { 19 | 20 | private Display display; 21 | private ZAPEventHandler eventHandler; 22 | 23 | /** 24 | * Default constructor. 25 | * 26 | * @param name 27 | * The name to be displayed in the Eclipse progress view while 28 | * this is executing. 29 | * @param display 30 | * The {@link Display} where this will trigger signal events. 31 | * @param eventHandler 32 | * The event handler needed for signal events. 33 | */ 34 | public RunCancelZAPScanJob(String name, Display display, ZAPEventHandler eventHandler) { 35 | super(name); 36 | this.display = display; 37 | this.eventHandler = eventHandler; 38 | } 39 | 40 | /** 41 | * Execution of the cancel ZAP scan job. 42 | */ 43 | @Override 44 | protected IStatus run(IProgressMonitor monitor) { 45 | // Signal that the cancel ZAP scan action is starting. 46 | Job signalCancelJob = new SignalZAPEventJob(display, "Signal Scan Cancel", ZAPEventType.SCAN_CANCEL_STARTED, 47 | eventHandler); 48 | signalCancelJob.setPriority(Job.INTERACTIVE); 49 | signalCancelJob.schedule(); 50 | 51 | // Cancel the current ZAP scan. 52 | Job cancelZapScanJob = new CancelZAPScanJob("Cancelling ZAP Scan..."); 53 | cancelZapScanJob.setPriority(Job.LONG); 54 | cancelZapScanJob.schedule(); 55 | while (cancelZapScanJob.getResult() == null) { 56 | try { 57 | Thread.sleep(1000); 58 | } catch (InterruptedException e) { 59 | ConsolePlugin.log(e); 60 | } 61 | } 62 | 63 | // Signal that the cancel ZAP scan action is complete. 64 | Job signalCancelCompleteJob = new SignalZAPEventJob(display, "Signal Scan Cancel Complete", 65 | ZAPEventType.SCAN_CANCEL_COMPLETE, eventHandler); 66 | signalCancelCompleteJob.setPriority(Job.INTERACTIVE); 67 | signalCancelCompleteJob.schedule(); 68 | 69 | return Status.OK_STATUS; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/jobs/runscan/ClearZAPJob.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.jobs.runscan; 2 | 3 | import org.eclipse.core.runtime.IProgressMonitor; 4 | import org.eclipse.core.runtime.IStatus; 5 | import org.eclipse.core.runtime.Status; 6 | import org.eclipse.core.runtime.jobs.Job; 7 | import org.eclipse.ui.console.ConsolePlugin; 8 | import org.zaproxy.clientapi.core.ClientApi; 9 | import org.zaproxy.clientapi.core.ClientApiException; 10 | 11 | import com.polyhedral.security.testing.zedattackproxy.utils.ZAPHelper; 12 | 13 | /** 14 | * Eclipse {@link Job} for performing a cleanup after a ZAP scan. 15 | */ 16 | public class ClearZAPJob extends Job { 17 | 18 | /** 19 | * Default constructor. 20 | * 21 | * @param name 22 | * The name to be displayed in the Eclipse progress view while 23 | * this is executing. 24 | */ 25 | public ClearZAPJob(String name) { 26 | super(name); 27 | } 28 | 29 | /** 30 | * Execution of the call to ZAP to clean up after a ZAP scan. 31 | */ 32 | @Override 33 | protected IStatus run(IProgressMonitor monitor) { 34 | try { 35 | ClientApi zapAPI = ZAPHelper.getInstance().getZAPClient(); 36 | zapAPI.spider.removeAllScans(ZAPHelper.getInstance().getZapApiKey()); 37 | zapAPI.ascan.removeAllScans(ZAPHelper.getInstance().getZapApiKey()); 38 | zapAPI.core.deleteAllAlerts(ZAPHelper.getInstance().getZapApiKey()); 39 | 40 | } catch (ClientApiException e) { 41 | ConsolePlugin.log(e); 42 | } 43 | 44 | return Status.OK_STATUS; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/jobs/runscan/RunZAPScanJob.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.jobs.runscan; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | import org.eclipse.core.runtime.CoreException; 5 | import org.eclipse.core.runtime.IProgressMonitor; 6 | import org.eclipse.core.runtime.IStatus; 7 | import org.eclipse.core.runtime.Status; 8 | import org.eclipse.core.runtime.jobs.Job; 9 | import org.eclipse.jface.dialogs.MessageDialog; 10 | import org.eclipse.swt.widgets.Display; 11 | import org.eclipse.ui.console.ConsolePlugin; 12 | 13 | import com.polyhedral.security.testing.zedattackproxy.actions.CancelZAPScanAction; 14 | import com.polyhedral.security.testing.zedattackproxy.actions.RunZAPScanAction; 15 | import com.polyhedral.security.testing.zedattackproxy.actions.ScanProgress; 16 | import com.polyhedral.security.testing.zedattackproxy.actions.jobs.CreatePopupMessageJob; 17 | import com.polyhedral.security.testing.zedattackproxy.actions.jobs.SignalZAPEventJob; 18 | import com.polyhedral.security.testing.zedattackproxy.events.ZAPEventHandler; 19 | import com.polyhedral.security.testing.zedattackproxy.events.ZAPEventType; 20 | 21 | /** 22 | * Top-level Eclipse {@link Job} called by {@link RunZAPScanAction}. 23 | */ 24 | public class RunZAPScanJob extends Job { 25 | 26 | private Display display; 27 | private ScanTarget target; 28 | private ZAPEventHandler eventHandler; 29 | 30 | private Job spiderJob; 31 | private Job ascanJob; 32 | private ScanStatus scanStatus; 33 | 34 | /** 35 | * Default constructor. 36 | * 37 | * @param name 38 | * The name to be displayed in the Eclipse progress view while 39 | * this is executing. 40 | * @param display 41 | * The {@link Display} where this will trigger signal events. 42 | * @param target 43 | * The {@link ScanTarget} that is being processed in the ZAP 44 | * ascan. 45 | * @param eventHandler 46 | * The event handler for signal events. 47 | */ 48 | public RunZAPScanJob(String name, Display display, ScanTarget target, ZAPEventHandler eventHandler) { 49 | super(name); 50 | this.display = display; 51 | this.target = target; 52 | this.eventHandler = eventHandler; 53 | 54 | scanStatus = new ScanStatus(); 55 | } 56 | 57 | /** 58 | * Execution of the run ZAP scan job. 59 | */ 60 | @Override 61 | protected IStatus run(IProgressMonitor monitor) { 62 | 63 | ScanProgress scanProgress = new ScanProgress(); 64 | 65 | // Make sure that all of the necessary scan parameters have been 66 | // entered. 67 | if (StringUtils.isBlank(target.getTargetUrl()) || StringUtils.isBlank(target.getFileName()) 68 | || StringUtils.isBlank(target.getReportFormat())) { 69 | CreatePopupMessageJob incompleteParamsWarningJob = new CreatePopupMessageJob(MessageDialog.WARNING, 70 | "The Scan Target URL, Scan Result File, and Report Format fields are required to run a scan."); 71 | incompleteParamsWarningJob.setPriority(Job.INTERACTIVE); 72 | incompleteParamsWarningJob.schedule(); 73 | return Status.CANCEL_STATUS; 74 | } 75 | 76 | // Give the user a warning if the scan will overwrite an existing scan 77 | // file. 78 | try { 79 | if (ZAPScanHelper.scanFilesExist(target.getFileName())) { 80 | CreatePopupMessageJob fileOverwriteWarning = new CreatePopupMessageJob(MessageDialog.CONFIRM, 81 | "The specified Scan Result File matches an existing scan file in the ZAPScanResults folder. Executing the scan may overwrite existing scan results data. Do you wish to proceed?"); 82 | fileOverwriteWarning.setPriority(Job.INTERACTIVE); 83 | fileOverwriteWarning.schedule(); 84 | while (fileOverwriteWarning.getResult() == null) { 85 | try { 86 | Thread.sleep(100); 87 | } catch (InterruptedException e) { 88 | ConsolePlugin.log(e); 89 | } 90 | } 91 | 92 | if (fileOverwriteWarning.getResult() == Status.CANCEL_STATUS) { 93 | return Status.CANCEL_STATUS; 94 | } 95 | } 96 | } catch (CoreException e1) { 97 | ConsolePlugin.log(e1); 98 | } 99 | 100 | // Signal that the spider has started. 101 | Job signalZAPSpiderJob = new SignalZAPEventJob(display, "Signal ZAP Spider Started...", 102 | ZAPEventType.SCAN_SPIDER_STARTED, eventHandler); 103 | signalZAPSpiderJob.setPriority(Job.INTERACTIVE); 104 | signalZAPSpiderJob.schedule(); 105 | 106 | // Set the attack levels. 107 | Job attackLevelJob = new ZAPSetZAPLevelsJob("Setting ZAP Attack Levels..", target.getZapPolicyList()); 108 | attackLevelJob.setPriority(LONG); 109 | attackLevelJob.schedule(); 110 | 111 | // Perform a spider of the target URL. 112 | spiderJob = new ZAPSpiderJob("Running Zed Attack Proxy Spider...", target, display, scanProgress, eventHandler, 113 | scanStatus); 114 | spiderJob.setPriority(LONG); 115 | spiderJob.schedule(); 116 | while (spiderJob.getResult() == null) { 117 | try { 118 | Thread.sleep(1000); 119 | } catch (InterruptedException e) { 120 | ConsolePlugin.log(e); 121 | } 122 | } 123 | 124 | if (scanStatus.isScanCancelled()) { 125 | return Status.CANCEL_STATUS; 126 | } 127 | 128 | // Signal that the spider has started. 129 | Job signalZAPAscanJob = new SignalZAPEventJob(display, "Signal ZAP Ascan Started...", 130 | ZAPEventType.SCAN_ASCAN_STARTED, eventHandler); 131 | signalZAPAscanJob.setPriority(Job.INTERACTIVE); 132 | signalZAPAscanJob.schedule(); 133 | 134 | // Perform an ascan on the target URL. 135 | ascanJob = new ZAPAscanJob("Running Zed Attack Proxy Ascan...", target, display, scanProgress, eventHandler, 136 | scanStatus); 137 | ascanJob.setPriority(LONG); 138 | ascanJob.schedule(); 139 | while (ascanJob.getResult() == null) { 140 | try { 141 | Thread.sleep(1000); 142 | } catch (InterruptedException e) { 143 | ConsolePlugin.log(e); 144 | } 145 | } 146 | 147 | if (scanStatus.isScanCancelled()) { 148 | return Status.CANCEL_STATUS; 149 | } 150 | 151 | // Clear out scan data after run is complete. 152 | Job clearZapJob = new ClearZAPJob("Clearing Zed Attack Proxy Run Data..."); 153 | clearZapJob.setPriority(LONG); 154 | clearZapJob.schedule(); 155 | while (clearZapJob.getResult() == null) { 156 | try { 157 | Thread.sleep(1000); 158 | } catch (InterruptedException e) { 159 | ConsolePlugin.log(e); 160 | } 161 | } 162 | 163 | // Signal that the scan is complete. 164 | Job signalZAPScanCompleteJob = new SignalZAPEventJob(display, "Signal ZAP Scan Complete", 165 | ZAPEventType.SCAN_COMPLETE, eventHandler); 166 | signalZAPScanCompleteJob.setPriority(Job.INTERACTIVE); 167 | signalZAPScanCompleteJob.schedule(); 168 | 169 | return Status.OK_STATUS; 170 | } 171 | 172 | /** 173 | * Indicator that a {@link CancelZAPScanAction} has been performed. This 174 | * signals the run ZAP job that it needs to stop processing. 175 | */ 176 | public void cancelScan() { 177 | scanStatus.cancelScan(); 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/jobs/runscan/ScanStatus.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.jobs.runscan; 2 | 3 | /** 4 | * The status of the current ZAP scan. 5 | */ 6 | public class ScanStatus { 7 | 8 | private boolean scanIsCancelled = false; 9 | 10 | public boolean isScanCancelled() { 11 | return scanIsCancelled; 12 | } 13 | 14 | public void cancelScan() { 15 | scanIsCancelled = true; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/jobs/runscan/ScanTarget.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.jobs.runscan; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import com.polyhedral.security.testing.zedattackproxy.views.ZAPPolicyEditor; 7 | 8 | /** 9 | * ZAP scan target information. 10 | */ 11 | public class ScanTarget { 12 | private String fileName; 13 | private String targetUrl; 14 | private String reportFormat; 15 | private List zapPolicyList; 16 | 17 | public ScanTarget(String fileName, String targetUrl, String reportFormat, List zapPolicyList) { 18 | this.fileName = fileName; 19 | this.targetUrl = targetUrl; 20 | this.reportFormat = reportFormat; 21 | this.zapPolicyList = new ArrayList(); 22 | for (ZAPPolicyEditor zapPolicy : zapPolicyList) { 23 | this.zapPolicyList.add(new ZAPPolicyInfo(zapPolicy.getPolicyId(), zapPolicy.getSelectedAttackStrength(), 24 | zapPolicy.getSelectedAlertThreshold())); 25 | } 26 | } 27 | 28 | public String getFileName() { 29 | return this.fileName; 30 | } 31 | 32 | public String getTargetUrl() { 33 | return this.targetUrl; 34 | } 35 | 36 | public String getReportFormat() { 37 | return this.reportFormat; 38 | } 39 | 40 | public List getZapPolicyList() { 41 | return this.zapPolicyList; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/jobs/runscan/ZAPAscanJob.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.jobs.runscan; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import org.eclipse.core.runtime.CoreException; 9 | import org.eclipse.core.runtime.IProgressMonitor; 10 | import org.eclipse.core.runtime.IStatus; 11 | import org.eclipse.core.runtime.Status; 12 | import org.eclipse.core.runtime.jobs.Job; 13 | import org.eclipse.swt.widgets.Display; 14 | import org.eclipse.ui.console.ConsolePlugin; 15 | import org.zaproxy.clientapi.core.ApiResponse; 16 | import org.zaproxy.clientapi.core.ApiResponseElement; 17 | import org.zaproxy.clientapi.core.ApiResponseList; 18 | import org.zaproxy.clientapi.core.ApiResponseSet; 19 | import org.zaproxy.clientapi.core.ClientApi; 20 | import org.zaproxy.clientapi.core.ClientApiException; 21 | 22 | import com.polyhedral.security.testing.zedattackproxy.actions.ScanProgress; 23 | import com.polyhedral.security.testing.zedattackproxy.events.ZAPEventHandler; 24 | import com.polyhedral.security.testing.zedattackproxy.utils.ZAPHelper; 25 | 26 | /** 27 | * Eclipse {@link Job} for calling ZAP to perform an ascan. 28 | */ 29 | public class ZAPAscanJob extends Job { 30 | 31 | public static final String HIGH_RISK = "HIGH"; 32 | public static final String MEDIUM_RISK = "MEDIUM"; 33 | public static final String LOW_RISK = "LOW"; 34 | public static final String OTHER_RISK = "OTHER"; 35 | 36 | private ScanTarget target; 37 | private Display display; 38 | private ScanProgress scanProgress; 39 | private ZAPEventHandler eventHandler; 40 | private ScanStatus scanStatus; 41 | 42 | /** 43 | * Default constructor. 44 | * 45 | * @param name 46 | * The name to be displayed in the Eclipse progress view while 47 | * this is executing. 48 | * @param target 49 | * The target information for the ascan. 50 | * @param display 51 | * The {@link Display} where this will trigger signal events. 52 | * @param scanProgress 53 | * The progress tracker of the current ascan. 54 | * @param eventHandler 55 | * The event handler needed for signal events. 56 | * @param scanStatus 57 | * The status for the current scan. Indicates if the scan has 58 | * been cancelled before it completes execution. 59 | */ 60 | public ZAPAscanJob(String name, ScanTarget target, Display display, ScanProgress scanProgress, 61 | ZAPEventHandler eventHandler, ScanStatus scanStatus) { 62 | super(name); 63 | this.target = target; 64 | this.display = display; 65 | this.scanProgress = scanProgress; 66 | this.eventHandler = eventHandler; 67 | this.scanStatus = scanStatus; 68 | } 69 | 70 | /** 71 | * Execution of the ZAP ascan job. 72 | */ 73 | @Override 74 | protected IStatus run(IProgressMonitor monitor) { 75 | IStatus runStatus = Status.OK_STATUS; 76 | 77 | try { 78 | // Perform Ascan of URL. 79 | ClientApi zapAPI = ZAPHelper.getInstance().getZAPClient(); 80 | 81 | ApiResponse ascanResponse = zapAPI.ascan.scan(ZAPHelper.getInstance().getZapApiKey(), target.getTargetUrl(), 82 | "True", "False", "", "", ""); 83 | String ascanScanID = ((ApiResponseElement) ascanResponse).getValue(); 84 | scanProgress.setAscanId(ascanScanID); 85 | while (true) { 86 | // While the ascan is progressing, send progress updates to the 87 | // ZAP view. 88 | int progress = Integer.parseInt(((ApiResponseElement) zapAPI.ascan.status(ascanScanID)).getValue()); 89 | if (scanStatus.isScanCancelled() || progress >= 100) { 90 | break; 91 | } else { 92 | Job scanProgressJob = new ZAPScanProgressJob(display, "Spider Progress", scanProgress, 93 | eventHandler); 94 | scanProgressJob.setPriority(Job.INTERACTIVE); 95 | scanProgressJob.schedule(); 96 | 97 | Thread.sleep(500); 98 | } 99 | } 100 | 101 | Thread.sleep(5000); // give Ascan scanner time to complete 102 | // logging 103 | 104 | // Store Ascan results in project file. 105 | if (!scanStatus.isScanCancelled()) { 106 | ZAPScanHelper.generateAscanReport(target.getFileName(), target.getReportFormat(), 107 | sortAscanResults((ApiResponseList) zapAPI.core.alerts(target.getTargetUrl(), "", ""))); 108 | } 109 | 110 | } catch (ClientApiException | InterruptedException | CoreException e) { 111 | ConsolePlugin.log(e); 112 | runStatus = Status.CANCEL_STATUS; 113 | } 114 | 115 | return runStatus; 116 | } 117 | 118 | /** 119 | * Sort ascan results into maps based on the priority of findings. 120 | * 121 | * @param ascanResults 122 | * The ZAP ascan results. 123 | * @return A map of ascan results sorted by priority. 124 | */ 125 | private Map> sortAscanResults(ApiResponseList ascanResults) { 126 | Map> riskMap = new HashMap<>(); 127 | riskMap.put(HIGH_RISK, new ArrayList()); 128 | riskMap.put(MEDIUM_RISK, new ArrayList()); 129 | riskMap.put(LOW_RISK, new ArrayList()); 130 | riskMap.put(OTHER_RISK, new ArrayList()); 131 | 132 | // Sort the report findings based on risk. 133 | for (ApiResponse responseItem : ascanResults.getItems()) { 134 | ApiResponseSet responseSet = (ApiResponseSet) responseItem; 135 | switch (responseSet.getAttribute("risk")) { 136 | case "High": 137 | riskMap.get(HIGH_RISK).add(responseSet); 138 | break; 139 | case "Medium": 140 | riskMap.get(MEDIUM_RISK).add(responseSet); 141 | break; 142 | case "Low": 143 | riskMap.get(LOW_RISK).add(responseSet); 144 | break; 145 | default: 146 | riskMap.get(OTHER_RISK).add(responseSet); 147 | break; 148 | } 149 | } 150 | 151 | return riskMap; 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/jobs/runscan/ZAPPolicyInfo.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.jobs.runscan; 2 | 3 | /** 4 | * Storage of ZAP policy information. 5 | */ 6 | public class ZAPPolicyInfo { 7 | private String id; 8 | private String attackStrength; 9 | private String alertThreshold; 10 | 11 | public ZAPPolicyInfo(String id, String attackStrength, String alertThreshold) { 12 | this.id = id; 13 | this.attackStrength = attackStrength; 14 | this.alertThreshold = alertThreshold; 15 | } 16 | 17 | public String getId() { 18 | return this.id; 19 | } 20 | 21 | public String getAttackStrength() { 22 | return this.attackStrength; 23 | } 24 | 25 | public String getAlertThreshold() { 26 | return this.alertThreshold; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/jobs/runscan/ZAPScanHelper.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.jobs.runscan; 2 | 3 | import java.io.ByteArrayInputStream; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | import org.eclipse.core.resources.IFile; 8 | import org.eclipse.core.resources.IFolder; 9 | import org.eclipse.core.resources.IProject; 10 | import org.eclipse.core.resources.IResource; 11 | import org.eclipse.core.resources.IWorkspace; 12 | import org.eclipse.core.resources.IWorkspaceRoot; 13 | import org.eclipse.core.resources.ResourcesPlugin; 14 | import org.eclipse.core.runtime.CoreException; 15 | import org.owasp.encoder.Encode; 16 | import org.zaproxy.clientapi.core.ApiResponse; 17 | import org.zaproxy.clientapi.core.ApiResponseElement; 18 | import org.zaproxy.clientapi.core.ApiResponseList; 19 | import org.zaproxy.clientapi.core.ApiResponseSet; 20 | 21 | /** 22 | * Helper class for a ZAP scan. Provides interaction with Eclipse for creating 23 | * an output project and log files for ZAP scans. 24 | */ 25 | public class ZAPScanHelper { 26 | 27 | /** 28 | * Determine if any files exist in the ZAP scan log folder for the specified 29 | * file name. 30 | * 31 | * @param fileName 32 | * The file name to check for existence. 33 | * @return True of any files exist, false otherwise. 34 | * @throws CoreException 35 | */ 36 | public static boolean scanFilesExist(String fileName) throws CoreException { 37 | IFolder zapFolder = openZAPScanResultsFolder(false); 38 | if (zapFolder != null) { 39 | return zapFolder.getFile(getSpiderFileName(fileName)).exists() 40 | || zapFolder.getFile(getAscanHtmlFileName(fileName)).exists() 41 | || zapFolder.getFile(getAscanXmlFileName(fileName)).exists(); 42 | } 43 | 44 | return false; 45 | } 46 | 47 | /** 48 | * Generate a report file for the results of a ZAP spider. 49 | * 50 | * @param fileName 51 | * The file to write the report to. 52 | * @param targetUrl 53 | * The URL that was used to start the spider. 54 | * @param spiderResponse 55 | * The results of the spider from ZAP. 56 | * @throws CoreException 57 | */ 58 | public static void generateSpiderReport(String fileName, String targetUrl, ApiResponseList spiderResponse) 59 | throws CoreException { 60 | // Get the file to write the report to. 61 | IFile file = getSpiderFile(fileName); 62 | if (file.exists()) { 63 | file.delete(false, false, null); 64 | } 65 | 66 | // Generate the log file. 67 | file.create(new ByteArrayInputStream(generateSpiderReport(targetUrl, spiderResponse)), IResource.NONE, null); 68 | 69 | // Refresh the ZAP scan folder to eliminate some Eclipse synchronization 70 | // issues. 71 | openZAPScanResultsFolder(true).refreshLocal(IFolder.DEPTH_ZERO, null); 72 | } 73 | 74 | /** 75 | * Generate a report for the results of a ZAP ascan. 76 | * 77 | * @param fileName 78 | * The file to write the report to. 79 | * @param reportFormat 80 | * The format of the report. Currently XML and HTML are 81 | * supported. 82 | * @param riskMap 83 | * The results of the ascan from ZAP, sorted based on risk level. 84 | * @throws CoreException 85 | */ 86 | public static void generateAscanReport(String fileName, String reportFormat, 87 | Map> riskMap) throws CoreException { 88 | if ("HTML".equals(reportFormat)) { 89 | // Get the HTML file to write the report to. 90 | IFile file = getAscanHtmlFile(fileName); 91 | if (file.exists()) { 92 | file.delete(false, false, null); 93 | } 94 | 95 | // Generate the HTML file content. 96 | file.create(new ByteArrayInputStream(new String("\n").getBytes()), IResource.NONE, null); 97 | 98 | generateHtmlEntries(file, riskMap.get(ZAPAscanJob.HIGH_RISK)); 99 | generateHtmlEntries(file, riskMap.get(ZAPAscanJob.MEDIUM_RISK)); 100 | generateHtmlEntries(file, riskMap.get(ZAPAscanJob.LOW_RISK)); 101 | generateHtmlEntries(file, riskMap.get(ZAPAscanJob.OTHER_RISK)); 102 | 103 | file.appendContents(new ByteArrayInputStream(new String("").getBytes()), IFile.KEEP_HISTORY, 104 | null); 105 | } else if ("XML".equals(reportFormat)) { 106 | // get the XML file to write the report to. 107 | IFile file = getAscanXmlFile(fileName); 108 | if (file.exists()) { 109 | file.delete(false, false, null); 110 | } 111 | 112 | // Generate the XML file content. 113 | file.create(new ByteArrayInputStream(new String("\n\n").getBytes()), 114 | IResource.NONE, null); 115 | 116 | if (riskMap.get(ZAPAscanJob.HIGH_RISK).size() > 0) { 117 | file.appendContents(new ByteArrayInputStream(new String("\n").getBytes()), IResource.NONE, 118 | null); 119 | generateXmlEntries(file, riskMap.get(ZAPAscanJob.HIGH_RISK)); 120 | file.appendContents(new ByteArrayInputStream(new String("\n").getBytes()), IResource.NONE, 121 | null); 122 | } 123 | if (riskMap.get(ZAPAscanJob.MEDIUM_RISK).size() > 0) { 124 | file.appendContents(new ByteArrayInputStream(new String("\n").getBytes()), IResource.NONE, 125 | null); 126 | generateXmlEntries(file, riskMap.get(ZAPAscanJob.MEDIUM_RISK)); 127 | file.appendContents(new ByteArrayInputStream(new String("\n").getBytes()), IResource.NONE, 128 | null); 129 | } 130 | if (riskMap.get(ZAPAscanJob.LOW_RISK).size() > 0) { 131 | file.appendContents(new ByteArrayInputStream(new String("\n").getBytes()), IResource.NONE, 132 | null); 133 | generateXmlEntries(file, riskMap.get(ZAPAscanJob.LOW_RISK)); 134 | file.appendContents(new ByteArrayInputStream(new String("\n").getBytes()), IResource.NONE, 135 | null); 136 | } 137 | if (riskMap.get(ZAPAscanJob.OTHER_RISK).size() > 0) { 138 | file.appendContents(new ByteArrayInputStream(new String("\n").getBytes()), IResource.NONE, null); 139 | generateXmlEntries(file, riskMap.get(ZAPAscanJob.OTHER_RISK)); 140 | file.appendContents(new ByteArrayInputStream(new String("\n").getBytes()), IResource.NONE, 141 | null); 142 | } 143 | 144 | file.appendContents(new ByteArrayInputStream(new String("").getBytes()), IFile.KEEP_HISTORY, 145 | null); 146 | } 147 | 148 | // Refresh the ZAP scan folder to eliminate some Eclipse synchronization 149 | // issues. 150 | openZAPScanResultsFolder(true).refreshLocal(IFolder.DEPTH_ZERO, null); 151 | } 152 | 153 | /** 154 | * Get the spider file. 155 | * 156 | * @param fileName 157 | * @return 158 | * @throws CoreException 159 | */ 160 | private static IFile getSpiderFile(String fileName) throws CoreException { 161 | return openZAPScanResultsFolder(true).getFile(getSpiderFileName(fileName)); 162 | } 163 | 164 | /** 165 | * Get the full name of the spider file. 166 | * 167 | * @param fileName 168 | * @return 169 | */ 170 | private static String getSpiderFileName(String fileName) { 171 | return fileName + "-SpiderResults.txt"; 172 | } 173 | 174 | /** 175 | * Get the ascan HTML file. 176 | * 177 | * @param fileName 178 | * @return 179 | * @throws CoreException 180 | */ 181 | private static IFile getAscanHtmlFile(String fileName) throws CoreException { 182 | return openZAPScanResultsFolder(true).getFile(getAscanHtmlFileName(fileName)); 183 | } 184 | 185 | /** 186 | * Get the full name of the ascan HTML file. 187 | * 188 | * @param fileName 189 | * @return 190 | */ 191 | private static String getAscanHtmlFileName(String fileName) { 192 | return fileName + "-AscanResults.html"; 193 | } 194 | 195 | /** 196 | * Get the ascan XML file. 197 | * 198 | * @param fileName 199 | * @return 200 | * @throws CoreException 201 | */ 202 | private static IFile getAscanXmlFile(String fileName) throws CoreException { 203 | return openZAPScanResultsFolder(true).getFile(getAscanXmlFileName(fileName)); 204 | } 205 | 206 | /** 207 | * Get the full name of the ascan XML file. 208 | * 209 | * @param fileName 210 | * @return 211 | */ 212 | private static String getAscanXmlFileName(String fileName) { 213 | return fileName + "-AscanResults.xml"; 214 | } 215 | 216 | /** 217 | * Generate the contents of the spider report. 218 | * 219 | * @param targetUrl 220 | * @param spiderResponse 221 | * @return 222 | */ 223 | private static byte[] generateSpiderReport(String targetUrl, ApiResponseList spiderResponse) { 224 | StringBuilder report = new StringBuilder(); 225 | 226 | report.append("Target URL: ").append(targetUrl).append("\n\n"); 227 | 228 | // Display urls in scope. 229 | ApiResponseList inScope = (ApiResponseList) spiderResponse.getItems().get(0); 230 | report.append("URLs In Scope\n"); 231 | 232 | // Loop through in scope products. 233 | for (ApiResponse scopeEntry : inScope.getItems()) { 234 | ApiResponseSet responseSet = (ApiResponseSet) scopeEntry; 235 | report.append("\tURL: ").append(responseSet.getAttribute("url")).append("\n"); 236 | report.append("\tRequest Info:\n"); 237 | report.append("\t\tMethod: ").append(responseSet.getAttribute("method")).append("\n"); 238 | report.append("\t\tStatus: ").append(responseSet.getAttribute("statusReason")).append("\n\n"); 239 | } 240 | 241 | // Display urls out of scope. 242 | ApiResponseList outOfScope = (ApiResponseList) spiderResponse.getItems().get(1); 243 | report.append("URLs Out of Scope\n"); 244 | 245 | // Loop through out of scope products. 246 | for (ApiResponse outOfScopeEntry : outOfScope.getItems()) { 247 | ApiResponseElement responseElement = (ApiResponseElement) outOfScopeEntry; 248 | report.append("\tURL: ").append(responseElement.getValue()).append("\n"); 249 | } 250 | 251 | return report.toString().getBytes(); 252 | } 253 | 254 | /** 255 | * Open the Security Testing project where all scan results are stored. 256 | * 257 | * @param forceCreation 258 | * @return 259 | * @throws CoreException 260 | */ 261 | private static IProject openSecurityTestingProject(boolean forceCreation) throws CoreException { 262 | IWorkspace workspace = ResourcesPlugin.getWorkspace(); 263 | IWorkspaceRoot root = workspace.getRoot(); 264 | IProject project = root.getProject("SecurityTesting"); 265 | if (!project.exists()) { 266 | if (forceCreation) { 267 | project.create(null); 268 | } else { 269 | return null; 270 | } 271 | } 272 | 273 | if (!project.isOpen()) { 274 | project.open(null); 275 | } 276 | 277 | return project; 278 | } 279 | 280 | /** 281 | * Open the ZAP scan results folder in the Security Testing project. 282 | * 283 | * @param forceCreation 284 | * @return 285 | * @throws CoreException 286 | */ 287 | private static IFolder openZAPScanResultsFolder(boolean forceCreation) throws CoreException { 288 | IProject project = openSecurityTestingProject(forceCreation); 289 | if (project != null) { 290 | IFolder zapFolder = project.getFolder("ZAPScanResults"); 291 | if (!zapFolder.exists()) { 292 | zapFolder.create(false, false, null); 293 | } 294 | 295 | return zapFolder; 296 | } 297 | 298 | return null; 299 | } 300 | 301 | /** 302 | * Generate the HTML entries for an ascan report. As this report data may be 303 | * opened in a browser, the report data is being HTML encoded for safety. 304 | * 305 | * @param reportFile 306 | * @param alertsResponseList 307 | * @throws CoreException 308 | */ 309 | private static void generateHtmlEntries(IFile reportFile, List alertsResponseList) 310 | throws CoreException { 311 | StringBuilder responseData = new StringBuilder(); 312 | int counter = 0; 313 | for (ApiResponseSet responseSet : alertsResponseList) { 314 | responseData.append("\n"); 315 | responseData.append("\n"); 317 | responseData.append("\n"); 319 | responseData.append("\n"); 321 | responseData.append("\n"); 323 | responseData.append("\n"); 325 | responseData.append("\n"); 327 | responseData.append("\n"); 329 | responseData.append("
URL:").append(Encode.forHtml(responseSet.getAttribute("url"))) 316 | .append("
Risk:").append(Encode.forHtml(responseSet.getAttribute("risk"))) 318 | .append("
Confidence:") 320 | .append(Encode.forHtml(responseSet.getAttribute("confidence"))).append("
Alert:").append(Encode.forHtml(responseSet.getAttribute("alert"))) 322 | .append("
Attack:").append(Encode.forHtml(responseSet.getAttribute("attack"))) 324 | .append("
Description:") 326 | .append(Encode.forHtml(responseSet.getAttribute("description"))).append("
Solution:") 328 | .append(Encode.forHtml(responseSet.getAttribute("solution"))).append("


\n"); 330 | 331 | if (counter == 100) { 332 | reportFile.appendContents(new ByteArrayInputStream(responseData.toString().getBytes()), 333 | IFile.KEEP_HISTORY, null); 334 | responseData = new StringBuilder(); 335 | counter = 0; 336 | } else { 337 | counter++; 338 | } 339 | } 340 | 341 | reportFile.appendContents(new ByteArrayInputStream(responseData.toString().getBytes()), IFile.KEEP_HISTORY, 342 | null); 343 | } 344 | 345 | /** 346 | * Generate the XML entries for an ascan report. As this report data may be 347 | * parsed by an XML reader, the report data is being XML encoded for safety. 348 | * 349 | * @param reportFile 350 | * @param alertsResponseList 351 | * @throws CoreException 352 | */ 353 | private static void generateXmlEntries(IFile reportFile, List alertsResponseList) 354 | throws CoreException { 355 | StringBuilder responseData = new StringBuilder(); 356 | int counter = 0; 357 | for (ApiResponseSet responseSet : alertsResponseList) { 358 | responseData.append("\n"); 359 | responseData.append("").append(Encode.forXml(responseSet.getAttribute("alert"))) 360 | .append("\n"); 361 | responseData.append("").append(Encode.forXml(responseSet.getAttribute("attack"))) 362 | .append("\n"); 363 | responseData.append("").append(Encode.forXml(responseSet.getAttribute("confidence"))) 364 | .append("\n"); 365 | responseData.append("").append(Encode.forXml(responseSet.getAttribute("url"))).append("\n"); 366 | responseData.append("").append(Encode.forXml(responseSet.getAttribute("description"))) 367 | .append("\n"); 368 | responseData.append("").append(Encode.forXml(responseSet.getAttribute("solution"))) 369 | .append("\n"); 370 | responseData.append("\n"); 371 | 372 | if (counter == 100) { 373 | reportFile.appendContents(new ByteArrayInputStream(responseData.toString().getBytes()), 374 | IFile.KEEP_HISTORY, null); 375 | responseData = new StringBuilder(); 376 | counter = 0; 377 | } else { 378 | counter++; 379 | } 380 | } 381 | reportFile.appendContents(new ByteArrayInputStream(responseData.toString().getBytes()), IFile.KEEP_HISTORY, 382 | null); 383 | } 384 | 385 | } 386 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/jobs/runscan/ZAPScanProgressJob.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.jobs.runscan; 2 | 3 | import org.eclipse.core.runtime.IProgressMonitor; 4 | import org.eclipse.core.runtime.IStatus; 5 | import org.eclipse.core.runtime.Status; 6 | import org.eclipse.swt.widgets.Display; 7 | import org.eclipse.ui.progress.UIJob; 8 | 9 | import com.polyhedral.security.testing.zedattackproxy.actions.ScanProgress; 10 | import com.polyhedral.security.testing.zedattackproxy.events.ZAPEventHandler; 11 | import com.polyhedral.security.testing.zedattackproxy.events.ZAPEventType; 12 | 13 | /** 14 | * Eclipse {@link UIJob} for displaying the progress of a ZAP ascan in the ZAP 15 | * view. 16 | */ 17 | public class ZAPScanProgressJob extends UIJob { 18 | 19 | private ScanProgress scanProgress; 20 | private ZAPEventHandler eventHandler; 21 | 22 | /** 23 | * Default constructor. 24 | * 25 | * @param jobDisplay 26 | * The {@link Display} for the UI action. 27 | * @param name 28 | * The name to be displayed in the Eclipse progress view while 29 | * this is executing. 30 | * @param scanProgress 31 | * The progress information to be reported. 32 | * @param eventHandler 33 | * The event handler to handle a progress indicator. 34 | */ 35 | public ZAPScanProgressJob(Display jobDisplay, String name, ScanProgress scanProgress, 36 | ZAPEventHandler eventHandler) { 37 | super(jobDisplay, name); 38 | this.scanProgress = scanProgress; 39 | this.eventHandler = eventHandler; 40 | } 41 | 42 | /** 43 | * Execution of the ZAP ascan progress job. 44 | */ 45 | @Override 46 | public IStatus runInUIThread(IProgressMonitor monitor) { 47 | eventHandler.fireZAPEvent(ZAPEventType.SCAN_PROGRESS, scanProgress); 48 | return Status.OK_STATUS; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/jobs/runscan/ZAPSetZAPLevelsJob.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.jobs.runscan; 2 | 3 | import java.util.List; 4 | 5 | import org.eclipse.core.runtime.IProgressMonitor; 6 | import org.eclipse.core.runtime.IStatus; 7 | import org.eclipse.core.runtime.Status; 8 | import org.eclipse.core.runtime.jobs.Job; 9 | import org.eclipse.ui.console.ConsolePlugin; 10 | import org.zaproxy.clientapi.core.ClientApi; 11 | import org.zaproxy.clientapi.core.ClientApiException; 12 | 13 | import com.polyhedral.security.testing.zedattackproxy.utils.ZAPHelper; 14 | 15 | /** 16 | * Eclipse {@link Job} for setting the levels for the ZAP scan policies. 17 | */ 18 | public class ZAPSetZAPLevelsJob extends Job { 19 | 20 | private List zapPolicyList; 21 | 22 | /** 23 | * Default constructor. 24 | * 25 | * @param name 26 | * The name to be displayed in the Eclipse progress view while 27 | * this is executing. 28 | * @param zapPolicyList 29 | */ 30 | public ZAPSetZAPLevelsJob(String name, List zapPolicyList) { 31 | super(name); 32 | this.zapPolicyList = zapPolicyList; 33 | } 34 | 35 | /** 36 | * Excution of the update for the ZAP scan policies based on the user input 37 | * from the ZAP view. 38 | */ 39 | @Override 40 | protected IStatus run(IProgressMonitor monitor) { 41 | 42 | try { 43 | ClientApi zapAPI = ZAPHelper.getInstance().getZAPClient(); 44 | for (ZAPPolicyInfo policyItem : zapPolicyList) { 45 | zapAPI.ascan.setPolicyAttackStrength(ZAPHelper.getInstance().getZapApiKey(), policyItem.getId(), 46 | policyItem.getAttackStrength(), ""); 47 | zapAPI.ascan.setPolicyAlertThreshold(ZAPHelper.getInstance().getZapApiKey(), policyItem.getId(), 48 | policyItem.getAlertThreshold(), ""); 49 | } 50 | 51 | } catch (ClientApiException e) { 52 | ConsolePlugin.log(e); 53 | } 54 | 55 | return Status.OK_STATUS; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/jobs/runscan/ZAPSpiderJob.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.jobs.runscan; 2 | 3 | import org.eclipse.core.runtime.CoreException; 4 | import org.eclipse.core.runtime.IProgressMonitor; 5 | import org.eclipse.core.runtime.IStatus; 6 | import org.eclipse.core.runtime.Status; 7 | import org.eclipse.core.runtime.jobs.Job; 8 | import org.eclipse.swt.widgets.Display; 9 | import org.eclipse.ui.console.ConsolePlugin; 10 | import org.zaproxy.clientapi.core.ApiResponse; 11 | import org.zaproxy.clientapi.core.ApiResponseElement; 12 | import org.zaproxy.clientapi.core.ApiResponseList; 13 | import org.zaproxy.clientapi.core.ClientApi; 14 | import org.zaproxy.clientapi.core.ClientApiException; 15 | 16 | import com.polyhedral.security.testing.zedattackproxy.actions.ScanProgress; 17 | import com.polyhedral.security.testing.zedattackproxy.events.ZAPEventHandler; 18 | import com.polyhedral.security.testing.zedattackproxy.utils.ZAPHelper; 19 | 20 | /** 21 | * Eclipse {@link Job} for calling ZAP to perform a spider. 22 | */ 23 | public class ZAPSpiderJob extends Job { 24 | 25 | private ScanTarget target; 26 | private Display display; 27 | private ScanProgress scanProgress; 28 | private ZAPEventHandler eventHandler; 29 | private ScanStatus scanStatus; 30 | 31 | /** 32 | * Default constructor. 33 | * 34 | * @param name 35 | * The name to be displayed in the Eclipse progress view while 36 | * this is executing. 37 | * @param target 38 | * the target information for the spider. 39 | * @param display 40 | * The {@link Display} where this will trigger signal events. 41 | * @param scanProgress 42 | * The progress tracker of the current spider. 43 | * @param eventHandler 44 | * The event handler needed for signal events. 45 | * @param scanStatus 46 | * the status for the current scan. Indicates if the scan has 47 | * been cancelled before it completes execution. 48 | */ 49 | public ZAPSpiderJob(String name, ScanTarget target, Display display, ScanProgress scanProgress, 50 | ZAPEventHandler eventHandler, ScanStatus scanStatus) { 51 | super(name); 52 | this.target = target; 53 | this.display = display; 54 | this.scanProgress = scanProgress; 55 | this.eventHandler = eventHandler; 56 | this.scanStatus = scanStatus; 57 | } 58 | 59 | /** 60 | * Execution of the ZAP spider job. 61 | */ 62 | @Override 63 | protected IStatus run(IProgressMonitor monitor) { 64 | IStatus runStatus = Status.OK_STATUS; 65 | 66 | try { 67 | // Perform spider of URL. 68 | ClientApi zapAPI = ZAPHelper.getInstance().getZAPClient(); 69 | 70 | ApiResponse spiderResponse = zapAPI.spider.scan(ZAPHelper.getInstance().getZapApiKey(), 71 | target.getTargetUrl(), "100"); 72 | 73 | String spiderScanID = ((ApiResponseElement) spiderResponse).getValue(); 74 | scanProgress.setSpiderId(spiderScanID); 75 | while (true) { 76 | // While the spider is progressing, send progress updates to the 77 | // ZAP view. 78 | Job scanProgressJob = new ZAPScanProgressJob(display, "Spider Progress", scanProgress, eventHandler); 79 | scanProgressJob.setPriority(Job.INTERACTIVE); 80 | scanProgressJob.schedule(); 81 | 82 | int progress = Integer.parseInt(((ApiResponseElement) zapAPI.spider.status(spiderScanID)).getValue()); 83 | if (scanStatus.isScanCancelled() || progress >= 100) { 84 | break; 85 | } else { 86 | Thread.sleep(500); 87 | } 88 | } 89 | 90 | Thread.sleep(5000); // give Spider scanner time to complete 91 | // logging 92 | 93 | // Store Spider results in a file. 94 | if (!scanStatus.isScanCancelled()) { 95 | ZAPScanHelper.generateSpiderReport(target.getFileName(), target.getTargetUrl(), 96 | (ApiResponseList) zapAPI.spider.fullResults(spiderScanID)); 97 | } 98 | 99 | } catch (ClientApiException | InterruptedException | CoreException e) { 100 | ConsolePlugin.log(e); 101 | runStatus = Status.CANCEL_STATUS; 102 | } 103 | 104 | return runStatus; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/jobs/start/RunStartZAPJob.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.jobs.start; 2 | 3 | import org.eclipse.core.runtime.IProgressMonitor; 4 | import org.eclipse.core.runtime.IStatus; 5 | import org.eclipse.core.runtime.Status; 6 | import org.eclipse.core.runtime.jobs.Job; 7 | import org.eclipse.swt.widgets.Display; 8 | import org.eclipse.ui.console.ConsolePlugin; 9 | 10 | import com.polyhedral.security.testing.zedattackproxy.actions.StartZAPAction; 11 | import com.polyhedral.security.testing.zedattackproxy.actions.jobs.SignalZAPEventJob; 12 | import com.polyhedral.security.testing.zedattackproxy.events.ZAPEventHandler; 13 | import com.polyhedral.security.testing.zedattackproxy.events.ZAPEventType; 14 | 15 | /** 16 | * Top-level Eclipse {@link Job} called by {@link StartZAPAction}. 17 | */ 18 | public class RunStartZAPJob extends Job { 19 | 20 | private Display display; 21 | private ZAPEventHandler eventHandler; 22 | 23 | /** 24 | * Default constructor. 25 | * 26 | * @param name 27 | * The name to be displayed in the Eclipse progress view while 28 | * this is executing. 29 | * @param display 30 | * the {@link Display} where this will trigger signal events. 31 | * @param eventHandler 32 | * The event handler needed for signal events. 33 | */ 34 | public RunStartZAPJob(String name, Display display, ZAPEventHandler eventHandler) { 35 | super(name); 36 | this.display = display; 37 | this.eventHandler = eventHandler; 38 | } 39 | 40 | /** 41 | * Execution of the start ZAP job. 42 | */ 43 | @Override 44 | protected IStatus run(IProgressMonitor monitor) { 45 | // Signal that the ZAP start action is starting. 46 | Job signalZAPStartJob = new SignalZAPEventJob(display, "Signal ZAP Start...", ZAPEventType.SERVER_STARTED, 47 | eventHandler); 48 | signalZAPStartJob.setPriority(Job.INTERACTIVE); 49 | signalZAPStartJob.schedule(); 50 | 51 | // Run the start ZAP job. 52 | Job startZAPJob = new StartZAPJob("Running ZAP Start Job..."); 53 | startZAPJob.setPriority(Job.LONG); 54 | startZAPJob.schedule(); 55 | while (startZAPJob.getResult() == null) { 56 | try { 57 | Thread.sleep(1000); 58 | } catch (InterruptedException e) { 59 | ConsolePlugin.log(e); 60 | } 61 | } 62 | 63 | // Signal that the ZAp start action is complete. 64 | Job signalZAPStartCompleteJob = new SignalZAPEventJob(display, "ZAP Start Complete", 65 | ZAPEventType.SERVER_STARTUP_COMPLETE, eventHandler); 66 | signalZAPStartCompleteJob.setPriority(Job.INTERACTIVE); 67 | signalZAPStartCompleteJob.schedule(); 68 | 69 | return Status.OK_STATUS; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/jobs/start/StartZAPJob.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.jobs.start; 2 | 3 | import java.io.BufferedInputStream; 4 | import java.io.BufferedReader; 5 | import java.io.File; 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | import java.io.InputStreamReader; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | import org.eclipse.core.runtime.IProgressMonitor; 13 | import org.eclipse.core.runtime.IStatus; 14 | import org.eclipse.core.runtime.Status; 15 | import org.eclipse.core.runtime.jobs.Job; 16 | import org.eclipse.jface.dialogs.MessageDialog; 17 | import org.eclipse.ui.console.ConsolePlugin; 18 | 19 | import com.polyhedral.security.testing.zedattackproxy.actions.jobs.CreatePopupMessageJob; 20 | import com.polyhedral.security.testing.zedattackproxy.utils.ZAPHelper; 21 | 22 | /** 23 | * Eclipse {@link Job} for calling ZAP to start a new ZAP instance. 24 | */ 25 | public class StartZAPJob extends Job { 26 | 27 | /** 28 | * Default constructor. 29 | * 30 | * @param name 31 | * The name to be displayed in the Eclipse progress view while 32 | * this is executing. 33 | */ 34 | public StartZAPJob(String name) { 35 | super(name); 36 | } 37 | 38 | /** 39 | * Execution of the call to ZAP to start the server. 40 | */ 41 | @Override 42 | protected IStatus run(IProgressMonitor monitor) { 43 | if (!ZAPHelper.getInstance().isZapRunning()) { 44 | 45 | // Build the UI command needed to start ZAP. 46 | List commands = new ArrayList<>(); 47 | addZapJavaExec(commands); 48 | addZapHeadless(commands); 49 | addZapProxyPort(commands); 50 | addZapSession(commands); 51 | addZapApiKey(commands); 52 | 53 | try { 54 | // Create a new process for executing ZAP. 55 | ProcessBuilder pb = new ProcessBuilder(commands.toArray(new String[commands.size()])); 56 | pb.directory(new File(ZAPHelper.getInstance().getZapJarLocation()).getParentFile()); 57 | Process proc = pb.start(); 58 | pipeToConsole(proc.getInputStream()); 59 | 60 | while (!ZAPHelper.getInstance().isZapRunning()) { 61 | Thread.sleep(1000); // give server time to start 62 | } 63 | 64 | } catch (Exception e) { 65 | ConsolePlugin.log(e); 66 | } 67 | } else { 68 | CreatePopupMessageJob job = new CreatePopupMessageJob(MessageDialog.ERROR, 69 | "The ZAP Server is already running."); 70 | job.setPriority(Job.INTERACTIVE); 71 | job.schedule(); 72 | } 73 | 74 | return Status.OK_STATUS; 75 | } 76 | 77 | /** 78 | * Set the Java executable and ZAP jar file. 79 | * 80 | * @param commands 81 | * The list to add this command to for the {@link ProcessBuilder} 82 | * . 83 | */ 84 | private void addZapJavaExec(List commands) { 85 | commands.add(ZAPHelper.getInstance().getJavaExecutable()); 86 | commands.add(ZAPHelper.JAVA_JAR_FLAG); 87 | commands.add(ZAPHelper.getInstance().getZapJarLocation()); 88 | } 89 | 90 | /** 91 | * Set the flag to mark ZAP to start in headless mode. 92 | * 93 | * @param commands 94 | * The list to add this command to for the {@link ProcessBuilder} 95 | * . 96 | */ 97 | private void addZapHeadless(List commands) { 98 | commands.add(ZAPHelper.ZAP_FLAG_DAEMON); 99 | } 100 | 101 | /** 102 | * Set the port to run ZAP on. 103 | * 104 | * @param commands 105 | * The list to add this command to for the {@link ProcessBuilder} 106 | * . 107 | */ 108 | private void addZapProxyPort(List commands) { 109 | commands.add(ZAPHelper.ZAP_FLAG_PORT); 110 | commands.add(Integer.toString(ZAPHelper.getInstance().getZapProxyPort())); 111 | } 112 | 113 | /** 114 | * Set the location where the ZAP session file will be stored. 115 | * 116 | * @param commands 117 | * The list to add this command to for the {@link ProcessBuilder} 118 | * . 119 | */ 120 | private void addZapSession(List commands) { 121 | commands.add(ZAPHelper.getInstance().getZapSessionFlag()); 122 | commands.add(ZAPHelper.getInstance().getFullSessionPath()); 123 | } 124 | 125 | /** 126 | * Set the ZAP API key. 127 | * 128 | * @param commands 129 | * The list to add this command to for the {@link ProcessBuilder} 130 | * . 131 | */ 132 | private void addZapApiKey(List commands) { 133 | commands.add(ZAPHelper.ZAP_FLAG_CONFIG); 134 | commands.add(ZAPHelper.ZAP_CONFIG_API_KEY + "=" + ZAPHelper.getInstance().getZapApiKey()); 135 | } 136 | 137 | /** 138 | * Create a reader for grabbing all process output data from the ZAP 139 | * executable and log it to the ZAP Console view. 140 | * 141 | * @param stream 142 | * The input stream of the process log. 143 | */ 144 | private void pipeToConsole(final InputStream stream) { 145 | new Thread(new Runnable() { 146 | 147 | @Override 148 | public void run() { 149 | BufferedInputStream bis = new BufferedInputStream(stream); 150 | InputStreamReader inread = new InputStreamReader(bis); 151 | BufferedReader bufferedReader = new BufferedReader(inread); 152 | String line; 153 | try { 154 | while ((line = bufferedReader.readLine()) != null) { 155 | ZAPHelper.getInstance().logConsoleMessage(line); 156 | } 157 | } catch (IOException e) { 158 | ConsolePlugin.log(e); 159 | } 160 | } 161 | }).start(); 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/jobs/stop/RunZAPStopJob.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.jobs.stop; 2 | 3 | import org.eclipse.core.runtime.IProgressMonitor; 4 | import org.eclipse.core.runtime.IStatus; 5 | import org.eclipse.core.runtime.Status; 6 | import org.eclipse.core.runtime.jobs.Job; 7 | import org.eclipse.swt.widgets.Display; 8 | import org.eclipse.ui.console.ConsolePlugin; 9 | 10 | import com.polyhedral.security.testing.zedattackproxy.actions.StopZAPAction; 11 | import com.polyhedral.security.testing.zedattackproxy.actions.jobs.SignalZAPEventJob; 12 | import com.polyhedral.security.testing.zedattackproxy.events.ZAPEventHandler; 13 | import com.polyhedral.security.testing.zedattackproxy.events.ZAPEventType; 14 | 15 | /** 16 | * Top-level Eclipse {@link Job} called by {@link StopZAPAction}. 17 | */ 18 | public class RunZAPStopJob extends Job { 19 | 20 | private Display display; 21 | private ZAPEventHandler eventHandler; 22 | 23 | /** 24 | * Default constructor. 25 | * 26 | * @param name 27 | * The name to be displayed in the Eclipse progress view while 28 | * this is executing. 29 | * @param display 30 | * The {@link Display} where this will trigger signal events. 31 | * @param eventHandler 32 | * The event handler needed for signal events. 33 | */ 34 | public RunZAPStopJob(String name, Display display, ZAPEventHandler eventHandler) { 35 | super(name); 36 | this.display = display; 37 | this.eventHandler = eventHandler; 38 | } 39 | 40 | /** 41 | * Execution of the stop ZAP job. 42 | */ 43 | @Override 44 | protected IStatus run(IProgressMonitor monitor) { 45 | // Signal that the ZAP stop action is starting. 46 | Job signalZAPStopJob = new SignalZAPEventJob(display, "Signal ZAP Stop...", ZAPEventType.SERVER_STOP_REQUESTED, 47 | eventHandler); 48 | signalZAPStopJob.setPriority(Job.INTERACTIVE); 49 | signalZAPStopJob.schedule(); 50 | 51 | // Run the stop ZAP job. 52 | Job stopZAPJob = new StopZAPJob("Running ZAP Stop Job..."); 53 | stopZAPJob.setPriority(Job.LONG); 54 | stopZAPJob.schedule(); 55 | while (stopZAPJob.getResult() == null) { 56 | try { 57 | Thread.sleep(1000); 58 | } catch (InterruptedException e) { 59 | ConsolePlugin.log(e); 60 | } 61 | } 62 | 63 | // Signal that the ZAP stop action is complete. 64 | Job signalZAPStopCompleteJob = new SignalZAPEventJob(display, "ZAP Stop Complete", ZAPEventType.SERVER_STOPPED, 65 | eventHandler); 66 | signalZAPStopCompleteJob.setPriority(Job.INTERACTIVE); 67 | signalZAPStopCompleteJob.schedule(); 68 | 69 | return Status.OK_STATUS; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/jobs/stop/StopZAPJob.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.jobs.stop; 2 | 3 | import org.eclipse.core.runtime.IProgressMonitor; 4 | import org.eclipse.core.runtime.IStatus; 5 | import org.eclipse.core.runtime.Status; 6 | import org.eclipse.core.runtime.jobs.Job; 7 | import org.eclipse.jface.dialogs.MessageDialog; 8 | import org.eclipse.ui.console.ConsolePlugin; 9 | 10 | import com.polyhedral.security.testing.zedattackproxy.actions.jobs.CreatePopupMessageJob; 11 | import com.polyhedral.security.testing.zedattackproxy.utils.ZAPHelper; 12 | 13 | /** 14 | * Eclipse {@link Job} for calling ZAP to stop a running ZAP instance. 15 | */ 16 | public class StopZAPJob extends Job { 17 | 18 | /** 19 | * Default constructor. 20 | * 21 | * @param name 22 | * The name to be displayed in the Eclipse progress view while 23 | * this is executing. 24 | */ 25 | public StopZAPJob(String name) { 26 | super(name); 27 | } 28 | 29 | /** 30 | * Execution of the call to ZAP to stop the running server. 31 | */ 32 | @Override 33 | protected IStatus run(IProgressMonitor monitor) { 34 | if (ZAPHelper.getInstance().isZapRunning()) { 35 | try { 36 | ZAPHelper.getInstance().getZAPClient().core.shutdown(ZAPHelper.getInstance().getZapApiKey()); 37 | while (ZAPHelper.getInstance().isZapRunning()) { 38 | Thread.sleep(1000); // give server time to stop 39 | } 40 | } catch (Exception e) { 41 | ConsolePlugin.log(e); 42 | } 43 | } else { 44 | CreatePopupMessageJob job = new CreatePopupMessageJob(MessageDialog.ERROR, 45 | "The ZAP Server is not running."); 46 | job.setPriority(Job.INTERACTIVE); 47 | job.schedule(); 48 | } 49 | 50 | return Status.OK_STATUS; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/menu/AbstractMenuToggle.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.menu; 2 | 3 | import org.eclipse.core.runtime.IProgressMonitor; 4 | import org.eclipse.core.runtime.IStatus; 5 | import org.eclipse.core.runtime.Status; 6 | import org.eclipse.core.runtime.jobs.Job; 7 | import org.eclipse.jface.action.Action; 8 | import org.eclipse.jface.action.MenuManager; 9 | 10 | /** 11 | * Abstract {@link MenuManager} implementation that creates toggle on/off 12 | * options for a menu option. 13 | */ 14 | public abstract class AbstractMenuToggle extends MenuManager { 15 | 16 | private Action toggleOn; 17 | private Action toggleOff; 18 | 19 | /** 20 | * Default constructor. 21 | * 22 | * @param menuText 23 | * The text for the menu item. 24 | */ 25 | public AbstractMenuToggle(String menuText) { 26 | this(menuText, "On", "Off"); 27 | } 28 | 29 | /** 30 | * Constructor that accounts for non-standard toggle values. 31 | * 32 | * @param menuText 33 | * The text for the menu item. 34 | * @param toggleOnText 35 | * The text of the "on" toggle option. 36 | * @param toggleOffText 37 | * The text of the "off" toggle option. 38 | */ 39 | public AbstractMenuToggle(String menuText, String toggleOnText, String toggleOffText) { 40 | super(menuText); 41 | 42 | toggleOn = new Action() { 43 | @Override 44 | public void run() { 45 | Job toggleOnJob = new ToggleOnJob("Set Toggle On"); 46 | toggleOnJob.setPriority(Job.INTERACTIVE); 47 | toggleOnJob.schedule(); 48 | 49 | setToggleActionState(true); 50 | } 51 | }; 52 | toggleOn.setText(toggleOnText); 53 | add(toggleOn); 54 | 55 | toggleOff = new Action() { 56 | @Override 57 | public void run() { 58 | Job toggleOffJob = new ToggleOffJob("Set Toggle Off"); 59 | toggleOffJob.setPriority(Job.INTERACTIVE); 60 | toggleOffJob.schedule(); 61 | 62 | setToggleActionState(false); 63 | } 64 | }; 65 | toggleOff.setText(toggleOffText); 66 | add(toggleOff); 67 | 68 | setToggleActionState(initToggleState()); 69 | } 70 | 71 | /** 72 | * Set the toggle action to its current state. 73 | * 74 | * @param toggleOnSelected 75 | * A boolean determining if the On or Off toggle should be 76 | * selected. 77 | */ 78 | private void setToggleActionState(boolean toggleOnSelected) { 79 | toggleOn.setChecked(toggleOnSelected); 80 | toggleOff.setChecked(!toggleOnSelected); 81 | } 82 | 83 | /** 84 | * Determination of the initial toggle state, to be implemented by the child 85 | * class. 86 | * 87 | * @return A boolean determining the initial toggle state. 88 | */ 89 | protected abstract boolean initToggleState(); 90 | 91 | /** 92 | * An action to be performed when the toggle on option is selected. 93 | */ 94 | protected abstract void executeToggleOn(); 95 | 96 | /** 97 | * An action to be performed when the toggle off option is selected. 98 | */ 99 | protected abstract void executeToggleOff(); 100 | 101 | /** 102 | * Eclipse {@link Job} triggered when the on option is selected. 103 | */ 104 | private class ToggleOnJob extends Job { 105 | 106 | public ToggleOnJob(String name) { 107 | super(name); 108 | } 109 | 110 | @Override 111 | protected IStatus run(IProgressMonitor monitor) { 112 | executeToggleOn(); 113 | return Status.OK_STATUS; 114 | } 115 | } 116 | 117 | /** 118 | * Eclipse {@link Job} triggered when the off option is selected. 119 | */ 120 | private class ToggleOffJob extends Job { 121 | 122 | public ToggleOffJob(String name) { 123 | super(name); 124 | } 125 | 126 | @Override 127 | protected IStatus run(IProgressMonitor monitor) { 128 | executeToggleOff(); 129 | return Status.OK_STATUS; 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/menu/ascan/AllowAttackOnStartToggle.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.menu.ascan; 2 | 3 | import org.eclipse.ui.console.ConsolePlugin; 4 | import org.zaproxy.clientapi.core.ApiResponseElement; 5 | import org.zaproxy.clientapi.core.ClientApiException; 6 | 7 | import com.polyhedral.security.testing.zedattackproxy.actions.menu.AbstractMenuToggle; 8 | import com.polyhedral.security.testing.zedattackproxy.utils.ZAPHelper; 9 | 10 | /** 11 | * Menu item for toggling the ZAP allow attack on start ascan option. 12 | */ 13 | public class AllowAttackOnStartToggle extends AbstractMenuToggle { 14 | 15 | public AllowAttackOnStartToggle() { 16 | super("Allow Attack On Start"); 17 | } 18 | 19 | @Override 20 | protected boolean initToggleState() { 21 | try { 22 | ApiResponseElement response = (ApiResponseElement) ZAPHelper.getInstance().getZAPClient().ascan 23 | .optionAllowAttackOnStart(); 24 | return "true".equalsIgnoreCase(response.getValue()); 25 | } catch (ClientApiException e) { 26 | ConsolePlugin.log(e); 27 | } 28 | 29 | return false; 30 | } 31 | 32 | @Override 33 | protected void executeToggleOn() { 34 | try { 35 | ZAPHelper.getInstance().getZAPClient().ascan 36 | .setOptionAllowAttackOnStart(ZAPHelper.getInstance().getZapApiKey(), true); 37 | } catch (ClientApiException e) { 38 | ConsolePlugin.log(e); 39 | } 40 | } 41 | 42 | @Override 43 | protected void executeToggleOff() { 44 | try { 45 | ZAPHelper.getInstance().getZAPClient().ascan 46 | .setOptionAllowAttackOnStart(ZAPHelper.getInstance().getZapApiKey(), false); 47 | } catch (ClientApiException e) { 48 | ConsolePlugin.log(e); 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/menu/ascan/ConfigureZapCsrfSettingsJob.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.menu.ascan; 2 | 3 | import org.eclipse.core.runtime.IProgressMonitor; 4 | import org.eclipse.core.runtime.IStatus; 5 | import org.eclipse.core.runtime.Status; 6 | import org.eclipse.jface.window.Window; 7 | import org.eclipse.swt.widgets.Display; 8 | import org.eclipse.ui.PlatformUI; 9 | import org.eclipse.ui.progress.UIJob; 10 | 11 | /** 12 | * Eclipse {@link UIJob} for creating a Eclipse dialog which allows a user to 13 | * modify the list of anti-CSRF tokens that are supported by ZAP. 14 | */ 15 | public class ConfigureZapCsrfSettingsJob extends UIJob { 16 | 17 | public ConfigureZapCsrfSettingsJob(Display jobDisplay, String name) { 18 | super(jobDisplay, name); 19 | } 20 | 21 | @Override 22 | public IStatus runInUIThread(IProgressMonitor monitor) { 23 | ZAPConfigureCSRFSettingsDialog dialog = new ZAPConfigureCSRFSettingsDialog( 24 | PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell()); 25 | if (dialog.open() == Window.OK) { 26 | return Status.OK_STATUS; 27 | } 28 | return Status.CANCEL_STATUS; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/menu/ascan/HandleAntiCSRFTokensToggle.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.menu.ascan; 2 | 3 | import org.eclipse.core.runtime.jobs.Job; 4 | import org.eclipse.jface.action.Action; 5 | import org.eclipse.jface.action.Separator; 6 | import org.eclipse.ui.PlatformUI; 7 | import org.eclipse.ui.console.ConsolePlugin; 8 | import org.zaproxy.clientapi.core.ApiResponseElement; 9 | import org.zaproxy.clientapi.core.ClientApiException; 10 | 11 | import com.polyhedral.security.testing.zedattackproxy.actions.menu.AbstractMenuToggle; 12 | import com.polyhedral.security.testing.zedattackproxy.utils.ZAPHelper; 13 | 14 | /** 15 | * Menu item for toggling the ZAP handle anti-CSRF tokens ascan option. 16 | */ 17 | public class HandleAntiCSRFTokensToggle extends AbstractMenuToggle { 18 | 19 | public HandleAntiCSRFTokensToggle() { 20 | super("Handle Anti-CSRF Tokens"); 21 | add(new Separator()); 22 | add(new Action("Configure...") { 23 | @Override 24 | public void run() { 25 | ConfigureZapCsrfSettingsJob configureCSRFSettingsJob = new ConfigureZapCsrfSettingsJob( 26 | PlatformUI.getWorkbench().getDisplay(), "Configure ZAP CSRF Settings"); 27 | configureCSRFSettingsJob.setPriority(Job.INTERACTIVE); 28 | configureCSRFSettingsJob.schedule(); 29 | } 30 | }); 31 | } 32 | 33 | @Override 34 | protected boolean initToggleState() { 35 | try { 36 | ApiResponseElement response = (ApiResponseElement) ZAPHelper.getInstance().getZAPClient().ascan 37 | .optionHandleAntiCSRFTokens(); 38 | return "true".equalsIgnoreCase(response.getValue()); 39 | } catch (ClientApiException e) { 40 | ConsolePlugin.log(e); 41 | } 42 | 43 | return false; 44 | } 45 | 46 | @Override 47 | protected void executeToggleOn() { 48 | try { 49 | ZAPHelper.getInstance().getZAPClient().ascan 50 | .setOptionHandleAntiCSRFTokens(ZAPHelper.getInstance().getZapApiKey(), true); 51 | } catch (ClientApiException e) { 52 | ConsolePlugin.log(e); 53 | } 54 | } 55 | 56 | @Override 57 | protected void executeToggleOff() { 58 | try { 59 | ZAPHelper.getInstance().getZAPClient().ascan 60 | .setOptionHandleAntiCSRFTokens(ZAPHelper.getInstance().getZapApiKey(), false); 61 | } catch (ClientApiException e) { 62 | ConsolePlugin.log(e); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/menu/ascan/InjectPluginIdInHeaderToggle.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.menu.ascan; 2 | 3 | import org.eclipse.ui.console.ConsolePlugin; 4 | import org.zaproxy.clientapi.core.ApiResponseElement; 5 | import org.zaproxy.clientapi.core.ClientApiException; 6 | 7 | import com.polyhedral.security.testing.zedattackproxy.actions.menu.AbstractMenuToggle; 8 | import com.polyhedral.security.testing.zedattackproxy.utils.ZAPHelper; 9 | 10 | /** 11 | * Menu item for toggling the ZAP inject plugin ID header ascan option. 12 | */ 13 | public class InjectPluginIdInHeaderToggle extends AbstractMenuToggle { 14 | 15 | public InjectPluginIdInHeaderToggle() { 16 | super("Inject Plugin ID In Header"); 17 | } 18 | 19 | @Override 20 | protected boolean initToggleState() { 21 | try { 22 | ApiResponseElement response = (ApiResponseElement) ZAPHelper.getInstance().getZAPClient().ascan 23 | .optionInjectPluginIdInHeader(); 24 | return "true".equalsIgnoreCase(response.getValue()); 25 | } catch (ClientApiException e) { 26 | ConsolePlugin.log(e); 27 | } 28 | 29 | return false; 30 | } 31 | 32 | @Override 33 | protected void executeToggleOn() { 34 | try { 35 | ZAPHelper.getInstance().getZAPClient().ascan 36 | .setOptionInjectPluginIdInHeader(ZAPHelper.getInstance().getZapApiKey(), true); 37 | } catch (ClientApiException e) { 38 | ConsolePlugin.log(e); 39 | } 40 | } 41 | 42 | @Override 43 | protected void executeToggleOff() { 44 | try { 45 | ZAPHelper.getInstance().getZAPClient().ascan 46 | .setOptionInjectPluginIdInHeader(ZAPHelper.getInstance().getZapApiKey(), false); 47 | } catch (ClientApiException e) { 48 | ConsolePlugin.log(e); 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/menu/ascan/RescanInAttackModeToggle.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.menu.ascan; 2 | 3 | import org.eclipse.ui.console.ConsolePlugin; 4 | import org.zaproxy.clientapi.core.ApiResponseElement; 5 | import org.zaproxy.clientapi.core.ClientApiException; 6 | 7 | import com.polyhedral.security.testing.zedattackproxy.actions.menu.AbstractMenuToggle; 8 | import com.polyhedral.security.testing.zedattackproxy.utils.ZAPHelper; 9 | 10 | /** 11 | * Menu item for toggling the ZAP rescan in attack mode ascan option. 12 | */ 13 | public class RescanInAttackModeToggle extends AbstractMenuToggle { 14 | 15 | public RescanInAttackModeToggle() { 16 | super("Rescan In Attack Mode"); 17 | } 18 | 19 | @Override 20 | protected boolean initToggleState() { 21 | try { 22 | ApiResponseElement response = (ApiResponseElement) ZAPHelper.getInstance().getZAPClient().ascan 23 | .optionRescanInAttackMode(); 24 | return "true".equalsIgnoreCase(response.getValue()); 25 | } catch (ClientApiException e) { 26 | ConsolePlugin.log(e); 27 | } 28 | 29 | return false; 30 | } 31 | 32 | @Override 33 | protected void executeToggleOn() { 34 | try { 35 | ZAPHelper.getInstance().getZAPClient().ascan 36 | .setOptionRescanInAttackMode(ZAPHelper.getInstance().getZapApiKey(), true); 37 | } catch (ClientApiException e) { 38 | ConsolePlugin.log(e); 39 | } 40 | } 41 | 42 | @Override 43 | protected void executeToggleOff() { 44 | try { 45 | ZAPHelper.getInstance().getZAPClient().ascan 46 | .setOptionRescanInAttackMode(ZAPHelper.getInstance().getZapApiKey(), false); 47 | } catch (ClientApiException e) { 48 | ConsolePlugin.log(e); 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/menu/ascan/ZAPConfigureCSRFSettingsDialog.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.menu.ascan; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | import org.eclipse.jface.dialogs.TitleAreaDialog; 5 | import org.eclipse.swt.SWT; 6 | import org.eclipse.swt.events.SelectionEvent; 7 | import org.eclipse.swt.events.SelectionListener; 8 | import org.eclipse.swt.layout.GridData; 9 | import org.eclipse.swt.layout.GridLayout; 10 | import org.eclipse.swt.widgets.Button; 11 | import org.eclipse.swt.widgets.Composite; 12 | import org.eclipse.swt.widgets.Control; 13 | import org.eclipse.swt.widgets.Label; 14 | import org.eclipse.swt.widgets.List; 15 | import org.eclipse.swt.widgets.Shell; 16 | import org.eclipse.swt.widgets.Text; 17 | import org.eclipse.ui.console.ConsolePlugin; 18 | import org.zaproxy.clientapi.core.ApiResponseElement; 19 | import org.zaproxy.clientapi.core.ClientApiException; 20 | 21 | import com.polyhedral.security.testing.zedattackproxy.utils.ZAPHelper; 22 | 23 | /** 24 | * A {@link TitleAreaDialog} prompting a user to edit the list of anti-CSRF 25 | * tokens that can be used during a ZAP scan. 26 | */ 27 | public class ZAPConfigureCSRFSettingsDialog extends TitleAreaDialog { 28 | 29 | List csrfTokens; 30 | Text addCsrfTokenText; 31 | 32 | /** 33 | * Standard constructor. 34 | * 35 | * @param parentShell 36 | */ 37 | public ZAPConfigureCSRFSettingsDialog(Shell parentShell) { 38 | super(parentShell); 39 | } 40 | 41 | /** 42 | * Set the title and message fields of the {@link TitleAreaDialog}. 43 | */ 44 | @Override 45 | public void create() { 46 | super.create(); 47 | setTitle("Configure ZAP Anti-CSRF Tokens"); 48 | setMessage("Configure token values that ZAP will use to detect anti-CSRF protections in a website."); 49 | } 50 | 51 | /** 52 | * Generate the content of the {@link TitleAreaDialog} body. 53 | */ 54 | @Override 55 | public Control createDialogArea(Composite parent) { 56 | Composite composite = new Composite(parent, SWT.NONE); 57 | GridLayout layout = new GridLayout(); 58 | layout.marginHeight = 0; 59 | layout.marginWidth = 0; 60 | layout.verticalSpacing = 0; 61 | layout.horizontalSpacing = 0; 62 | composite.setLayout(layout); 63 | composite.setLayoutData(new GridData(GridData.FILL_BOTH)); 64 | composite.setFont(parent.getFont()); 65 | 66 | // Build the separator line 67 | Label titleBarSeparator = new Label(composite, SWT.HORIZONTAL | SWT.SEPARATOR); 68 | titleBarSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 69 | 70 | Composite container = new Composite(composite, SWT.NONE); 71 | container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 72 | GridLayout containerLayout = new GridLayout(2, false); 73 | container.setLayout(containerLayout); 74 | 75 | // Load all of the existing ZAP anti-CSRF tokens. 76 | initCsrfTokenList(container); 77 | 78 | // Add the Remove button to remove an anti-CSRF token from the list. 79 | GridData dataRemoveButton = new GridData(); 80 | dataRemoveButton.widthHint = 75; 81 | dataRemoveButton.verticalAlignment = GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_VERTICAL; 82 | Button removeButton = new Button(container, SWT.PUSH); 83 | removeButton.setLayoutData(dataRemoveButton); 84 | removeButton.setText("Remove"); 85 | removeButton.addSelectionListener(new SelectionListener() { 86 | 87 | @Override 88 | public void widgetSelected(SelectionEvent e) { 89 | if (csrfTokens != null && csrfTokens.getSelectionCount() > 0) { 90 | try { 91 | ZAPHelper.getInstance().getZAPClient().acsrf.removeOptionToken( 92 | ZAPHelper.getInstance().getZapApiKey(), csrfTokens.getSelection()[0]); 93 | updateCsrfTokenList(); 94 | 95 | } catch (ClientApiException e1) { 96 | ConsolePlugin.log(e1); 97 | } 98 | } 99 | } 100 | 101 | @Override 102 | public void widgetDefaultSelected(SelectionEvent e) { 103 | // do nothing with default selection 104 | } 105 | }); 106 | 107 | // Add an input text field to add a new anti-CSRF token. 108 | GridData dataGrabHorizontalSpace = new GridData(); 109 | dataGrabHorizontalSpace.grabExcessHorizontalSpace = true; 110 | dataGrabHorizontalSpace.horizontalAlignment = GridData.FILL; 111 | addCsrfTokenText = new Text(container, SWT.BORDER); 112 | addCsrfTokenText.setLayoutData(dataGrabHorizontalSpace); 113 | 114 | // Add the Add button to add an anti-CSRF token to the list. 115 | GridData dataAddButton = new GridData(); 116 | dataAddButton.widthHint = 75; 117 | Button addButton = new Button(container, SWT.PUSH); 118 | addButton.setLayoutData(dataAddButton); 119 | addButton.setText("Add"); 120 | addButton.addSelectionListener(new SelectionListener() { 121 | 122 | @Override 123 | public void widgetSelected(SelectionEvent e) { 124 | if (StringUtils.isNotBlank(addCsrfTokenText.getText())) { 125 | try { 126 | ZAPHelper.getInstance().getZAPClient().acsrf 127 | .addOptionToken(ZAPHelper.getInstance().getZapApiKey(), addCsrfTokenText.getText()); 128 | addCsrfTokenText.setText(""); 129 | updateCsrfTokenList(); 130 | 131 | } catch (ClientApiException e1) { 132 | ConsolePlugin.log(e1); 133 | } 134 | } 135 | } 136 | 137 | @Override 138 | public void widgetDefaultSelected(SelectionEvent e) { 139 | // do nothing with default selection 140 | } 141 | }); 142 | 143 | return composite; 144 | } 145 | 146 | /** 147 | * Load the list of current anti-CSRF tokens supported by ZAP. 148 | * 149 | * @param container 150 | * The {@link Composite} container for the list. 151 | */ 152 | private void initCsrfTokenList(Composite container) { 153 | GridData dataGrabAllSpace = new GridData(); 154 | dataGrabAllSpace.grabExcessHorizontalSpace = true; 155 | dataGrabAllSpace.horizontalAlignment = GridData.FILL; 156 | dataGrabAllSpace.minimumHeight = 150; 157 | dataGrabAllSpace.heightHint = 150; 158 | 159 | csrfTokens = new List(container, SWT.BORDER | SWT.V_SCROLL); 160 | csrfTokens.setLayoutData(dataGrabAllSpace); 161 | 162 | updateCsrfTokenList(); 163 | } 164 | 165 | /** 166 | * When a new anti-CSRF token has been added or removed from the list or 167 | * when the view page is first being loaded, display the list. 168 | */ 169 | private void updateCsrfTokenList() { 170 | csrfTokens.removeAll(); 171 | 172 | try { 173 | ApiResponseElement response = (ApiResponseElement) ZAPHelper.getInstance().getZAPClient().acsrf 174 | .optionTokensNames(); 175 | // The ZAP API returns the CSRF tokens as a string with the format 176 | // "[token1, token2, token3, ... tokenN]" 177 | // so the extra characters need to be parsed out. 178 | String[] csrfTokenValues = response.getValue().replace("[", "").replace("]", "").replace(" ", "") 179 | .split(","); 180 | for (String csrfTokenEntry : csrfTokenValues) { 181 | csrfTokens.add(csrfTokenEntry); 182 | } 183 | 184 | } catch (ClientApiException e) { 185 | ConsolePlugin.log(e); 186 | } 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/menu/spider/ParseCommentsToggle.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.menu.spider; 2 | 3 | import org.eclipse.ui.console.ConsolePlugin; 4 | import org.zaproxy.clientapi.core.ApiResponseElement; 5 | import org.zaproxy.clientapi.core.ClientApiException; 6 | 7 | import com.polyhedral.security.testing.zedattackproxy.actions.menu.AbstractMenuToggle; 8 | import com.polyhedral.security.testing.zedattackproxy.utils.ZAPHelper; 9 | 10 | /** 11 | * Menu item for toggling the ZAP parse comments spider option. 12 | */ 13 | public class ParseCommentsToggle extends AbstractMenuToggle { 14 | 15 | public ParseCommentsToggle() { 16 | super("Parse Comments"); 17 | } 18 | 19 | @Override 20 | protected boolean initToggleState() { 21 | try { 22 | ApiResponseElement response = (ApiResponseElement) ZAPHelper.getInstance().getZAPClient().spider 23 | .optionParseComments(); 24 | return "true".equalsIgnoreCase(response.getValue()); 25 | } catch (ClientApiException e) { 26 | ConsolePlugin.log(e); 27 | } 28 | 29 | return false; 30 | } 31 | 32 | @Override 33 | protected void executeToggleOn() { 34 | try { 35 | ZAPHelper.getInstance().getZAPClient().spider.setOptionParseComments(ZAPHelper.getInstance().getZapApiKey(), 36 | true); 37 | } catch (ClientApiException e) { 38 | ConsolePlugin.log(e); 39 | } 40 | } 41 | 42 | @Override 43 | protected void executeToggleOff() { 44 | try { 45 | ZAPHelper.getInstance().getZAPClient().spider.setOptionParseComments(ZAPHelper.getInstance().getZapApiKey(), 46 | false); 47 | } catch (ClientApiException e) { 48 | ConsolePlugin.log(e); 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/menu/spider/ParseGitToggle.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.menu.spider; 2 | 3 | import org.eclipse.ui.console.ConsolePlugin; 4 | import org.zaproxy.clientapi.core.ApiResponseElement; 5 | import org.zaproxy.clientapi.core.ClientApiException; 6 | 7 | import com.polyhedral.security.testing.zedattackproxy.actions.menu.AbstractMenuToggle; 8 | import com.polyhedral.security.testing.zedattackproxy.utils.ZAPHelper; 9 | 10 | /** 11 | * Menu item for toggling the ZAP parse Git spider option. 12 | */ 13 | public class ParseGitToggle extends AbstractMenuToggle { 14 | 15 | public ParseGitToggle() { 16 | super("Parse Git"); 17 | } 18 | 19 | @Override 20 | protected boolean initToggleState() { 21 | try { 22 | ApiResponseElement response = (ApiResponseElement) ZAPHelper.getInstance().getZAPClient().spider 23 | .optionParseGit(); 24 | return "true".equalsIgnoreCase(response.getValue()); 25 | } catch (ClientApiException e) { 26 | ConsolePlugin.log(e); 27 | } 28 | 29 | return false; 30 | } 31 | 32 | @Override 33 | protected void executeToggleOn() { 34 | try { 35 | ZAPHelper.getInstance().getZAPClient().spider.setOptionParseGit(ZAPHelper.getInstance().getZapApiKey(), 36 | true); 37 | } catch (ClientApiException e) { 38 | ConsolePlugin.log(e); 39 | } 40 | } 41 | 42 | @Override 43 | protected void executeToggleOff() { 44 | try { 45 | ZAPHelper.getInstance().getZAPClient().spider.setOptionParseGit(ZAPHelper.getInstance().getZapApiKey(), 46 | false); 47 | } catch (ClientApiException e) { 48 | ConsolePlugin.log(e); 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/menu/spider/ParseRobotsTxtToggle.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.menu.spider; 2 | 3 | import org.eclipse.ui.console.ConsolePlugin; 4 | import org.zaproxy.clientapi.core.ApiResponseElement; 5 | import org.zaproxy.clientapi.core.ClientApiException; 6 | 7 | import com.polyhedral.security.testing.zedattackproxy.actions.menu.AbstractMenuToggle; 8 | import com.polyhedral.security.testing.zedattackproxy.utils.ZAPHelper; 9 | 10 | /** 11 | * Menu item for toggling the ZAP parse robots.txt spider option. 12 | */ 13 | public class ParseRobotsTxtToggle extends AbstractMenuToggle { 14 | 15 | public ParseRobotsTxtToggle() { 16 | super("Parse robots.txt"); 17 | } 18 | 19 | @Override 20 | protected boolean initToggleState() { 21 | try { 22 | ApiResponseElement response = (ApiResponseElement) ZAPHelper.getInstance().getZAPClient().spider 23 | .optionParseRobotsTxt(); 24 | return "true".equalsIgnoreCase(response.getValue()); 25 | } catch (ClientApiException e) { 26 | ConsolePlugin.log(e); 27 | } 28 | 29 | return false; 30 | } 31 | 32 | @Override 33 | protected void executeToggleOn() { 34 | try { 35 | ZAPHelper.getInstance().getZAPClient().spider 36 | .setOptionParseRobotsTxt(ZAPHelper.getInstance().getZapApiKey(), true); 37 | } catch (ClientApiException e) { 38 | ConsolePlugin.log(e); 39 | } 40 | } 41 | 42 | @Override 43 | protected void executeToggleOff() { 44 | try { 45 | ZAPHelper.getInstance().getZAPClient().spider 46 | .setOptionParseRobotsTxt(ZAPHelper.getInstance().getZapApiKey(), false); 47 | } catch (ClientApiException e) { 48 | ConsolePlugin.log(e); 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/menu/spider/ParseSitemapXmlToggle.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.menu.spider; 2 | 3 | import org.eclipse.ui.console.ConsolePlugin; 4 | import org.zaproxy.clientapi.core.ApiResponseElement; 5 | import org.zaproxy.clientapi.core.ClientApiException; 6 | 7 | import com.polyhedral.security.testing.zedattackproxy.actions.menu.AbstractMenuToggle; 8 | import com.polyhedral.security.testing.zedattackproxy.utils.ZAPHelper; 9 | 10 | /** 11 | * Menu item for toggling the ZAP parse sitemap.xml spider option. 12 | */ 13 | public class ParseSitemapXmlToggle extends AbstractMenuToggle { 14 | 15 | public ParseSitemapXmlToggle() { 16 | super("Parse Sitemap XML"); 17 | } 18 | 19 | @Override 20 | protected boolean initToggleState() { 21 | try { 22 | ApiResponseElement response = (ApiResponseElement) ZAPHelper.getInstance().getZAPClient().spider 23 | .optionParseSitemapXml(); 24 | return "true".equalsIgnoreCase(response.getValue()); 25 | } catch (ClientApiException e) { 26 | ConsolePlugin.log(e); 27 | } 28 | 29 | return false; 30 | } 31 | 32 | @Override 33 | protected void executeToggleOn() { 34 | try { 35 | ZAPHelper.getInstance().getZAPClient().spider 36 | .setOptionParseSitemapXml(ZAPHelper.getInstance().getZapApiKey(), true); 37 | } catch (ClientApiException e) { 38 | ConsolePlugin.log(e); 39 | } 40 | } 41 | 42 | @Override 43 | protected void executeToggleOff() { 44 | try { 45 | ZAPHelper.getInstance().getZAPClient().spider 46 | .setOptionParseSitemapXml(ZAPHelper.getInstance().getZapApiKey(), false); 47 | } catch (ClientApiException e) { 48 | ConsolePlugin.log(e); 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/menu/spider/ParseSvnEntriesToggle.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.menu.spider; 2 | 3 | import org.eclipse.ui.console.ConsolePlugin; 4 | import org.zaproxy.clientapi.core.ApiResponseElement; 5 | import org.zaproxy.clientapi.core.ClientApiException; 6 | 7 | import com.polyhedral.security.testing.zedattackproxy.actions.menu.AbstractMenuToggle; 8 | import com.polyhedral.security.testing.zedattackproxy.utils.ZAPHelper; 9 | 10 | /** 11 | * Menu item for toggling the ZAP parse SVN entries spider option. 12 | */ 13 | public class ParseSvnEntriesToggle extends AbstractMenuToggle { 14 | 15 | public ParseSvnEntriesToggle() { 16 | super("Parse SVN Entries"); 17 | } 18 | 19 | @Override 20 | protected boolean initToggleState() { 21 | try { 22 | ApiResponseElement response = (ApiResponseElement) ZAPHelper.getInstance().getZAPClient().spider 23 | .optionParseSVNEntries(); 24 | return "true".equalsIgnoreCase(response.getValue()); 25 | } catch (ClientApiException e) { 26 | ConsolePlugin.log(e); 27 | } 28 | 29 | return false; 30 | } 31 | 32 | @Override 33 | protected void executeToggleOn() { 34 | try { 35 | ZAPHelper.getInstance().getZAPClient().spider 36 | .setOptionParseSVNEntries(ZAPHelper.getInstance().getZapApiKey(), true); 37 | } catch (ClientApiException e) { 38 | ConsolePlugin.log(e); 39 | } 40 | } 41 | 42 | @Override 43 | protected void executeToggleOff() { 44 | try { 45 | ZAPHelper.getInstance().getZAPClient().spider 46 | .setOptionParseSVNEntries(ZAPHelper.getInstance().getZapApiKey(), false); 47 | } catch (ClientApiException e) { 48 | ConsolePlugin.log(e); 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/menu/spider/PostFormToggle.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.menu.spider; 2 | 3 | import org.eclipse.ui.console.ConsolePlugin; 4 | import org.zaproxy.clientapi.core.ApiResponseElement; 5 | import org.zaproxy.clientapi.core.ClientApiException; 6 | 7 | import com.polyhedral.security.testing.zedattackproxy.actions.menu.AbstractMenuToggle; 8 | import com.polyhedral.security.testing.zedattackproxy.utils.ZAPHelper; 9 | 10 | /** 11 | * Menu item for toggling the ZAP post form spider option. 12 | */ 13 | public class PostFormToggle extends AbstractMenuToggle { 14 | 15 | public PostFormToggle() { 16 | super("Post Form"); 17 | } 18 | 19 | @Override 20 | protected boolean initToggleState() { 21 | try { 22 | ApiResponseElement response = (ApiResponseElement) ZAPHelper.getInstance().getZAPClient().spider 23 | .optionPostForm(); 24 | return "true".equalsIgnoreCase(response.getValue()); 25 | } catch (ClientApiException e) { 26 | ConsolePlugin.log(e); 27 | } 28 | 29 | return false; 30 | } 31 | 32 | @Override 33 | protected void executeToggleOn() { 34 | try { 35 | ZAPHelper.getInstance().getZAPClient().spider.setOptionPostForm(ZAPHelper.getInstance().getZapApiKey(), 36 | true); 37 | } catch (ClientApiException e) { 38 | ConsolePlugin.log(e); 39 | } 40 | } 41 | 42 | @Override 43 | protected void executeToggleOff() { 44 | try { 45 | ZAPHelper.getInstance().getZAPClient().spider.setOptionPostForm(ZAPHelper.getInstance().getZapApiKey(), 46 | false); 47 | } catch (ClientApiException e) { 48 | ConsolePlugin.log(e); 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/menu/spider/ProcessFormToggle.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.menu.spider; 2 | 3 | import org.eclipse.ui.console.ConsolePlugin; 4 | import org.zaproxy.clientapi.core.ApiResponseElement; 5 | import org.zaproxy.clientapi.core.ClientApiException; 6 | 7 | import com.polyhedral.security.testing.zedattackproxy.actions.menu.AbstractMenuToggle; 8 | import com.polyhedral.security.testing.zedattackproxy.utils.ZAPHelper; 9 | 10 | /** 11 | * Menu item for toggling the ZAP process form spider option. 12 | */ 13 | public class ProcessFormToggle extends AbstractMenuToggle { 14 | 15 | public ProcessFormToggle() { 16 | super("Process Form"); 17 | } 18 | 19 | @Override 20 | protected boolean initToggleState() { 21 | try { 22 | ApiResponseElement response = (ApiResponseElement) ZAPHelper.getInstance().getZAPClient().spider 23 | .optionProcessForm(); 24 | return "true".equalsIgnoreCase(response.getValue()); 25 | } catch (ClientApiException e) { 26 | ConsolePlugin.log(e); 27 | } 28 | 29 | return false; 30 | } 31 | 32 | @Override 33 | protected void executeToggleOn() { 34 | try { 35 | ZAPHelper.getInstance().getZAPClient().spider.setOptionProcessForm(ZAPHelper.getInstance().getZapApiKey(), 36 | true); 37 | } catch (ClientApiException e) { 38 | ConsolePlugin.log(e); 39 | } 40 | } 41 | 42 | @Override 43 | protected void executeToggleOff() { 44 | try { 45 | ZAPHelper.getInstance().getZAPClient().spider.setOptionProcessForm(ZAPHelper.getInstance().getZapApiKey(), 46 | false); 47 | } catch (ClientApiException e) { 48 | ConsolePlugin.log(e); 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/actions/menu/spider/SendRefererHeaderToggle.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.actions.menu.spider; 2 | 3 | import org.eclipse.ui.console.ConsolePlugin; 4 | import org.zaproxy.clientapi.core.ApiResponseElement; 5 | import org.zaproxy.clientapi.core.ClientApiException; 6 | 7 | import com.polyhedral.security.testing.zedattackproxy.actions.menu.AbstractMenuToggle; 8 | import com.polyhedral.security.testing.zedattackproxy.utils.ZAPHelper; 9 | 10 | /** 11 | * Menu item for toggling the ZAP send referrer header spider option. 12 | */ 13 | public class SendRefererHeaderToggle extends AbstractMenuToggle { 14 | 15 | public SendRefererHeaderToggle() { 16 | super("Send Referer Header"); 17 | } 18 | 19 | @Override 20 | protected boolean initToggleState() { 21 | try { 22 | ApiResponseElement response = (ApiResponseElement) ZAPHelper.getInstance().getZAPClient().spider 23 | .optionSendRefererHeader(); 24 | return "true".equalsIgnoreCase(response.getValue()); 25 | } catch (ClientApiException e) { 26 | ConsolePlugin.log(e); 27 | } 28 | 29 | return false; 30 | } 31 | 32 | @Override 33 | protected void executeToggleOn() { 34 | try { 35 | ZAPHelper.getInstance().getZAPClient().spider 36 | .setOptionSendRefererHeader(ZAPHelper.getInstance().getZapApiKey(), true); 37 | } catch (ClientApiException e) { 38 | ConsolePlugin.log(e); 39 | } 40 | } 41 | 42 | @Override 43 | protected void executeToggleOff() { 44 | try { 45 | ZAPHelper.getInstance().getZAPClient().spider 46 | .setOptionSendRefererHeader(ZAPHelper.getInstance().getZapApiKey(), false); 47 | } catch (ClientApiException e) { 48 | ConsolePlugin.log(e); 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/events/IZAPEventHandler.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.events; 2 | 3 | /** 4 | * ZAP event handler interface. 5 | */ 6 | public interface IZAPEventHandler { 7 | public void addZAPEventListener(final IZAPEventListener listener); 8 | 9 | public void removeZAPEventListener(final IZAPEventListener listener); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/events/IZAPEventListener.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.events; 2 | 3 | import java.util.EventListener; 4 | 5 | import com.polyhedral.security.testing.zedattackproxy.actions.ScanProgress; 6 | 7 | /** 8 | * ZAP event listener interface. 9 | */ 10 | public interface IZAPEventListener extends EventListener { 11 | public void handleZAPEvent(ZAPEventType eventType, ScanProgress scanProgress); 12 | } 13 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/events/ZAPEventHandler.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.events; 2 | 3 | import org.eclipse.core.runtime.ListenerList; 4 | 5 | import com.polyhedral.security.testing.zedattackproxy.actions.ScanProgress; 6 | 7 | /** 8 | * ZAP event handler implementation. When a ZAP event is fired, this will notify 9 | * all of the appropriate listeners. 10 | */ 11 | public class ZAPEventHandler implements IZAPEventHandler { 12 | private ListenerList actionList = new ListenerList(); 13 | 14 | /** 15 | * Add a ZAP event listener. 16 | */ 17 | public void addZAPEventListener(final IZAPEventListener listener) { 18 | actionList.add(listener); 19 | } 20 | 21 | /** 22 | * Fire a new ZAP event. 23 | * 24 | * @param eventType 25 | * The {@link ZAPEventType} event that was triggered. 26 | */ 27 | public void fireZAPEvent(final ZAPEventType eventType) { 28 | final Object[] list = actionList.getListeners(); 29 | for (int i = 0; i < list.length; ++i) { 30 | ((IZAPEventListener) list[i]).handleZAPEvent(eventType, null); 31 | } 32 | } 33 | 34 | /** 35 | * Fire a new ZAP event. This event is part of a ZAP scan and includes 36 | * {@link ScanProgress} information. 37 | * 38 | * @param eventType 39 | * The {@link ZAPEventType} event that was triggered. 40 | * @param scanProgress 41 | * The {@link ScanProgress} details to be reported with the 42 | * event. 43 | */ 44 | public void fireZAPEvent(final ZAPEventType eventType, ScanProgress scanProgress) { 45 | final Object[] list = actionList.getListeners(); 46 | for (int i = 0; i < list.length; ++i) { 47 | ((IZAPEventListener) list[i]).handleZAPEvent(eventType, scanProgress); 48 | } 49 | } 50 | 51 | /** 52 | * Remove a ZAP event listener. 53 | */ 54 | public void removeZAPEventListener(final IZAPEventListener listener) { 55 | actionList.remove(listener); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/events/ZAPEventType.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.events; 2 | 3 | /** 4 | * Enum of the ZAP events that are triggered by the ZAP plugin. 5 | */ 6 | public enum ZAPEventType { 7 | SERVER_STARTED, 8 | SERVER_STARTUP_COMPLETE, 9 | SERVER_STOP_REQUESTED, 10 | SERVER_STOPPED, 11 | SCAN_SPIDER_STARTED, 12 | SCAN_ASCAN_STARTED, 13 | SCAN_PROGRESS, 14 | SCAN_COMPLETE, 15 | SCAN_CANCEL_STARTED, 16 | SCAN_CANCEL_COMPLETE, 17 | CONFIGURATION_CHANGED; 18 | } 19 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/preferences/ZAPPreferencePage.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.preferences; 2 | 3 | import org.eclipse.jface.preference.DirectoryFieldEditor; 4 | import org.eclipse.jface.preference.FieldEditorPreferencePage; 5 | import org.eclipse.jface.preference.FileFieldEditor; 6 | import org.eclipse.jface.preference.IntegerFieldEditor; 7 | import org.eclipse.jface.preference.StringFieldEditor; 8 | import org.eclipse.ui.IWorkbench; 9 | import org.eclipse.ui.IWorkbenchPreferencePage; 10 | 11 | import com.polyhedral.security.testing.zedattackproxy.Activator; 12 | import com.polyhedral.security.testing.zedattackproxy.utils.ZAPHelper; 13 | 14 | /** 15 | * Preferences page for the ZAP plugin. 16 | */ 17 | public class ZAPPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage { 18 | 19 | public static final String ZAP_JAR_LOCATION = "ZAP JAR Location"; 20 | public static final String ZAP_SESSION_DIRECTORY = "ZAP Session Directory"; 21 | public static final String ZAP_SESSION_NAME = "ZAP Session Name"; 22 | public static final String ZAP_PROXY_PORT = "ZAP Proxy Port"; 23 | public static final String ZAP_API_KEY = "ZAP API Key"; 24 | 25 | /** 26 | * Initialize the ZAP preferences page. 27 | */ 28 | @Override 29 | public void init(IWorkbench arg0) { 30 | setPreferenceStore(Activator.getDefault().getPreferenceStore()); 31 | setDescription("Configuration information for using the Zed Attack Proxy security testing tool."); 32 | } 33 | 34 | /** 35 | * Add the ZAP preferences to the preferences page. 36 | */ 37 | @Override 38 | protected void createFieldEditors() { 39 | FileFieldEditor zapJarLocation = new FileFieldEditor(ZAP_JAR_LOCATION, "ZAP JAR Location:", 40 | getFieldEditorParent()); 41 | zapJarLocation.setEmptyStringAllowed(false); 42 | addField(zapJarLocation); 43 | 44 | DirectoryFieldEditor zapSessionDirectory = new DirectoryFieldEditor(ZAP_SESSION_DIRECTORY, 45 | "ZAP Session Directory", getFieldEditorParent()); 46 | zapSessionDirectory.setEmptyStringAllowed(false); 47 | addField(zapSessionDirectory); 48 | 49 | StringFieldEditor zapSessionName = new StringFieldEditor(ZAP_SESSION_NAME, "ZAP Session Name", 50 | getFieldEditorParent()); 51 | zapSessionName.setEmptyStringAllowed(false); 52 | addField(zapSessionName); 53 | 54 | IntegerFieldEditor zapProxyPort = new IntegerFieldEditor(ZAP_PROXY_PORT, "ZAP Proxy Port:", 55 | getFieldEditorParent()); 56 | zapProxyPort.setValidRange(0, 99999); 57 | zapProxyPort.setEmptyStringAllowed(false); 58 | addField(zapProxyPort); 59 | 60 | StringFieldEditor zapApiKey = new StringFieldEditor(ZAP_API_KEY, "ZAP API Key", getFieldEditorParent()); 61 | zapApiKey.setEmptyStringAllowed(false); 62 | addField(zapApiKey); 63 | } 64 | 65 | /** 66 | * When the user is done editing the ZAP preferences and clicks the "OK" 67 | * button, verify that the prefernces are valid and fire a ZAP event to 68 | * trigger the ZAP view buttons to enable/disable as needed. 69 | */ 70 | @Override 71 | public boolean performOk() { 72 | boolean result = super.performOk(); 73 | ZAPHelper.getInstance().checkZapConfiguration(); 74 | return result; 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/utils/ZAPHelper.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.utils; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | 6 | import org.apache.commons.lang.StringUtils; 7 | import org.eclipse.core.runtime.Platform; 8 | import org.eclipse.jdt.launching.JavaRuntime; 9 | import org.eclipse.jface.preference.IPreferenceStore; 10 | import org.eclipse.ui.console.ConsolePlugin; 11 | import org.eclipse.ui.console.IConsole; 12 | import org.eclipse.ui.console.IConsoleManager; 13 | import org.eclipse.ui.console.MessageConsole; 14 | import org.eclipse.ui.console.MessageConsoleStream; 15 | import org.zaproxy.clientapi.core.ClientApi; 16 | import org.zaproxy.clientapi.core.ClientApiException; 17 | 18 | import com.polyhedral.security.testing.zedattackproxy.Activator; 19 | import com.polyhedral.security.testing.zedattackproxy.events.IZAPEventHandler; 20 | import com.polyhedral.security.testing.zedattackproxy.events.IZAPEventListener; 21 | import com.polyhedral.security.testing.zedattackproxy.events.ZAPEventHandler; 22 | import com.polyhedral.security.testing.zedattackproxy.events.ZAPEventType; 23 | import com.polyhedral.security.testing.zedattackproxy.preferences.ZAPPreferencePage; 24 | 25 | /** 26 | * Convenience class for the ZAP scanner. Contains configuration information 27 | * derived from the ZAP properties page, console logging capabilities, and ZAP 28 | * API access features. 29 | */ 30 | public class ZAPHelper implements IZAPEventHandler { 31 | private static final ZAPHelper instance = new ZAPHelper(); 32 | 33 | private static final IPreferenceStore preferenceStore = Activator.getDefault().getPreferenceStore(); 34 | private static final String ZAP_PLUGIN_CONSOLE = "ZAP Scanner Console"; 35 | 36 | private static final String WINDOWS_JAVA_EXECUTABLE = "\\bin\\java.exe"; 37 | private static final String NIX_JAVA_EXECUTABLE = "/bin/java"; 38 | private static final String ZAP_SESSION_EXTENSION = ".session"; 39 | 40 | public static final String JAVA_JAR_FLAG = "-jar"; 41 | public static final String ZAP_FLAG_DAEMON = "-daemon"; 42 | public static final String ZAP_FLAG_PORT = "-port"; 43 | public static final String ZAP_FLAG_SESSION = "-session"; 44 | public static final String ZAP_FLAG_NEWSESSION = "-newsession"; 45 | public static final String ZAP_SERVER_NAME = "localhost"; 46 | public static final String ZAP_FLAG_CONFIG = "-config"; 47 | public static final String ZAP_CONFIG_API_KEY = "api.key"; 48 | 49 | private ZAPEventHandler zapEventHandler; 50 | private MessageConsoleStream zapConsoleStream; 51 | private boolean zapConfigurationValid; 52 | 53 | /** 54 | * Constructor for the {@link ZAPHelper} singleton instance. 55 | */ 56 | private ZAPHelper() { 57 | zapEventHandler = new ZAPEventHandler(); 58 | 59 | loadConsoleStream(); 60 | zapConfigurationValid = false; 61 | } 62 | 63 | /** 64 | * @return The {@link ZAPHelper} singleton instance. 65 | */ 66 | public static ZAPHelper getInstance() { 67 | return instance; 68 | } 69 | 70 | /** 71 | * @return The location where ZAP executable JAR is located. 72 | */ 73 | public String getZapJarLocation() { 74 | return preferenceStore.getString(ZAPPreferencePage.ZAP_JAR_LOCATION); 75 | } 76 | 77 | /** 78 | * @return The path to the directory where the ZAP session files will be 79 | * stored. 80 | */ 81 | public String getZapSessionDirectory() { 82 | return preferenceStore.getString(ZAPPreferencePage.ZAP_SESSION_DIRECTORY); 83 | } 84 | 85 | /** 86 | * @return The file name for the ZAP session. 87 | */ 88 | public String getZapSessionName() { 89 | return preferenceStore.getString(ZAPPreferencePage.ZAP_SESSION_NAME); 90 | } 91 | 92 | /** 93 | * @return The port where the ZAP proxy will execute. 94 | */ 95 | public int getZapProxyPort() { 96 | return preferenceStore.getInt(ZAPPreferencePage.ZAP_PROXY_PORT); 97 | } 98 | 99 | /** 100 | * The ZAP API key for the ZAP server. Starting with version 2.4.1 of ZAP 101 | * the API key became a required field. 102 | * 103 | * @return The ZAP API key value. 104 | */ 105 | public String getZapApiKey() { 106 | return preferenceStore.getString(ZAPPreferencePage.ZAP_API_KEY); 107 | } 108 | 109 | /** 110 | * @return The full path value for the ZAP session. This is needed when 111 | * starting ZAP in headless mode. 112 | */ 113 | public String getFullSessionPath() { 114 | return getZapSessionDirectory() + File.separator + getZapSessionName(); 115 | } 116 | 117 | /** 118 | * When starting a ZAP instance in headless mode, it is necessary to 119 | * determine if the session file already exists. If one does not exist, it 120 | * needs to be created. If it already exists, it requires a different flag 121 | * for the startup command. Otherwise, ZAP will throw an error stating the 122 | * session file has a problem. 123 | * 124 | * @return A boolean value determining whether a ZAP session file already 125 | * exists. Returns true if a ZAP session file exists, false if it 126 | * does not exist. 127 | */ 128 | public boolean zapSessionExists() { 129 | return new File(getFullSessionPath() + ZAP_SESSION_EXTENSION).exists(); 130 | } 131 | 132 | /** 133 | * Get the path to the default Java JVM installation. This is needed when 134 | * starting ZAP in headless mode to know where to call Java from. 135 | * 136 | * @return The path to the Java JVM. 137 | */ 138 | public String getJavaExecutable() { 139 | return JavaRuntime.getDefaultVMInstall().getInstallLocation() 140 | + ((Platform.OS_WIN32.equals(Platform.getOS())) ? WINDOWS_JAVA_EXECUTABLE : NIX_JAVA_EXECUTABLE); 141 | } 142 | 143 | /** 144 | * @return The appropriate session flag for starting ZAP in headless mode, 145 | * depending on whether the session file already exists. 146 | */ 147 | public String getZapSessionFlag() { 148 | return zapSessionExists() ? ZAP_FLAG_SESSION : ZAP_FLAG_NEWSESSION; 149 | } 150 | 151 | /** 152 | * @return A ZAP {@link ClientApi} instance for calling ZAP through the API. 153 | */ 154 | public ClientApi getZAPClient() { 155 | return new ClientApi(ZAP_SERVER_NAME, getZapProxyPort()); 156 | } 157 | 158 | /** 159 | * Checks the ZAP Eclipse properties and determines if they have all been 160 | * set. This is called when the ZAP view initializes and any time a user 161 | * makes a change to the ZAP properties. 162 | */ 163 | public void checkZapConfiguration() { 164 | this.zapConfigurationValid = StringUtils.isNotBlank(getZapJarLocation()) 165 | && StringUtils.isNotBlank(getZapSessionDirectory()) && StringUtils.isNotBlank(getZapSessionName()) 166 | && StringUtils.isNotBlank(getZapApiKey()) && getZapProxyPort() > 0; 167 | zapEventHandler.fireZAPEvent(ZAPEventType.CONFIGURATION_CHANGED); 168 | } 169 | 170 | /** 171 | * @return A boolean for whether ZAP has been properly configured in 172 | * Eclipse. True if it has, false otherwise. 173 | */ 174 | public boolean isZapConfigurationValid() { 175 | return this.zapConfigurationValid; 176 | } 177 | 178 | /** 179 | * Check to see if the ZAP server is currently running. 180 | * 181 | * @return A boolean for the ZAP server status. Returns true if the ZAP 182 | * server is running, false otherwise. 183 | */ 184 | public boolean isZapRunning() { 185 | try { 186 | getZAPClient().core.version(); 187 | } catch (ClientApiException e) { 188 | return false; 189 | } 190 | 191 | return true; 192 | } 193 | 194 | /** 195 | * Load the Eclispe Console view and activate a new stream for the ZAP 196 | * plugin. This stream will be used to capture logging information for the 197 | * ZAP plugin. 198 | */ 199 | private void loadConsoleStream() { 200 | IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager(); 201 | IConsole[] existingConsoles = manager.getConsoles(); 202 | MessageConsole zapConsole = null; 203 | for (IConsole console : existingConsoles) { 204 | if (ZAP_PLUGIN_CONSOLE.equals(console.getName())) { 205 | zapConsole = (MessageConsole) console; 206 | } 207 | } 208 | 209 | if (zapConsole == null) { 210 | zapConsole = new MessageConsole(ZAP_PLUGIN_CONSOLE, null, null, true); 211 | zapConsole.activate(); 212 | manager.addConsoles(new IConsole[] { zapConsole }); 213 | } 214 | 215 | zapConsoleStream = zapConsole.newMessageStream(); 216 | zapConsoleStream.setActivateOnWrite(true); 217 | } 218 | 219 | /** 220 | * Log a {@link String} message to the ZAP Console view. 221 | * 222 | * @param message 223 | * The {@link String} message to add to the ZAP Console view. 224 | */ 225 | public void logConsoleMessage(String message) { 226 | try { 227 | zapConsoleStream.println(message); 228 | zapConsoleStream.flush(); 229 | } catch (IOException e) { 230 | // If the Console failed to write the message, dump the stack trace 231 | // since the Console apparently cannot accept writing at this time. 232 | ConsolePlugin.log(e); 233 | } 234 | } 235 | 236 | /** 237 | * Add a ZAP event listener. This is used to trigger ZAP events outside of a 238 | * standard event. 239 | */ 240 | @Override 241 | public void addZAPEventListener(IZAPEventListener listener) { 242 | zapEventHandler.addZAPEventListener(listener); 243 | } 244 | 245 | /** 246 | * Remove a ZAP event listener. 247 | */ 248 | @Override 249 | public void removeZAPEventListener(IZAPEventListener listener) { 250 | zapEventHandler.removeZAPEventListener(listener); 251 | } 252 | } 253 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/views/ZAPAlertThreshold.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.views; 2 | 3 | /** 4 | * Enum of the alert threshold options available in ZAP. 5 | */ 6 | public enum ZAPAlertThreshold { 7 | OFF("OFF", 0), 8 | DEFAULT("DEFAULT", 1), 9 | LOW("LOW", 2), 10 | MEDIUM("MEDIUM", 3), 11 | HIGH("HIGH", 4); 12 | 13 | private final String value; 14 | private final int rank; 15 | 16 | ZAPAlertThreshold(String value, int rank) { 17 | this.value = value; 18 | this.rank = rank; 19 | } 20 | 21 | public String getValue() { 22 | return this.value; 23 | } 24 | 25 | public int getRank() { 26 | return this.rank; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/views/ZAPAttackStrength.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.views; 2 | 3 | /** 4 | * Enum of the attack strength options available within ZAP. 5 | */ 6 | public enum ZAPAttackStrength { 7 | DEFAULT("DEFAULT", 0), 8 | LOW("LOW", 1), 9 | MEDIUM("MEDIUM", 2), 10 | HIGH("HIGH", 3), 11 | INSANE("INSANE", 4); 12 | 13 | private final String value; 14 | private final int rank; 15 | 16 | ZAPAttackStrength(String value, int rank) { 17 | this.value = value; 18 | this.rank = rank; 19 | } 20 | 21 | public String getValue() { 22 | return this.value; 23 | } 24 | 25 | public int getRank() { 26 | return this.rank; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/views/ZAPPolicyEditor.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.views; 2 | 3 | import org.apache.commons.lang.StringUtils; 4 | import org.eclipse.swt.SWT; 5 | import org.eclipse.swt.layout.GridData; 6 | import org.eclipse.swt.widgets.Combo; 7 | import org.eclipse.swt.widgets.Composite; 8 | import org.eclipse.swt.widgets.Label; 9 | import org.zaproxy.clientapi.core.ApiResponseSet; 10 | 11 | /** 12 | * Eclipse View fragment representing a single policy entry from ZAP. Includes 13 | * policy name as well as dropdowns to select the attack strength and alert 14 | * threshold. 15 | */ 16 | public class ZAPPolicyEditor { 17 | 18 | private Composite parent; 19 | private ApiResponseSet policyItem; 20 | private Combo attackStrengthCombo; 21 | private Combo alertThresholdCombo; 22 | 23 | /** 24 | * Generate the view fragment from the provided ZAP {@link ApiResponseSet}. 25 | * 26 | * @param parent 27 | * @param policyItem 28 | */ 29 | public ZAPPolicyEditor(Composite parent, ApiResponseSet policyItem) { 30 | this.parent = parent; 31 | this.policyItem = policyItem; 32 | 33 | generateUIContent(); 34 | } 35 | 36 | /** 37 | * Initialize the view fragment. 38 | */ 39 | private void generateUIContent() { 40 | 41 | // Set the policy name. 42 | Label policyLabel = new Label(parent, SWT.WRAP); 43 | GridData policyGrid = new GridData(SWT.FILL, SWT.FILL, false, true); 44 | policyGrid.widthHint = 75; 45 | policyLabel.setLayoutData(policyGrid); 46 | policyLabel.setText(policyItem.getAttribute("name")); 47 | 48 | // Set the attack strength. If one has not been specified in ZAP, select 49 | // DEFAULT. 50 | attackStrengthCombo = new Combo(parent, SWT.READ_ONLY); 51 | for (ZAPAttackStrength attackStrength : ZAPAttackStrength.values()) { 52 | attackStrengthCombo.add(attackStrength.getValue()); 53 | } 54 | String policyAttackStrength = policyItem.getAttribute("attackStrength"); 55 | if (StringUtils.isNotBlank(policyAttackStrength)) { 56 | attackStrengthCombo.select(ZAPAttackStrength.valueOf(policyAttackStrength).getRank()); 57 | } else { 58 | attackStrengthCombo.select(ZAPAttackStrength.DEFAULT.getRank()); 59 | } 60 | 61 | // Set the alert threshold. If one has not be specified in ZAP, select 62 | // DEFAULT. 63 | alertThresholdCombo = new Combo(parent, SWT.READ_ONLY); 64 | for (ZAPAlertThreshold alertThreshold : ZAPAlertThreshold.values()) { 65 | alertThresholdCombo.add(alertThreshold.getValue()); 66 | } 67 | String policyAlertThreshold = policyItem.getAttribute("alertThreshold"); 68 | if (StringUtils.isNotBlank(policyAlertThreshold)) { 69 | alertThresholdCombo.select(ZAPAlertThreshold.valueOf(policyAlertThreshold).getRank()); 70 | } else { 71 | alertThresholdCombo.select(ZAPAlertThreshold.DEFAULT.getRank()); 72 | } 73 | } 74 | 75 | /** 76 | * @return The ZAP policy ID {@link String}. 77 | */ 78 | public String getPolicyId() { 79 | return policyItem.getAttribute("id"); 80 | } 81 | 82 | /** 83 | * @return the currently selected attack strength {@link String}. 84 | */ 85 | public String getSelectedAttackStrength() { 86 | return attackStrengthCombo.getText(); 87 | } 88 | 89 | /** 90 | * @return The currently selected alert threshold {@link String}. 91 | */ 92 | public String getSelectedAlertThreshold() { 93 | return alertThresholdCombo.getText(); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /com.polyhedral.security.testing.zedattackproxy/src/com/polyhedral/security/testing/zedattackproxy/views/ZAPView.java: -------------------------------------------------------------------------------- 1 | package com.polyhedral.security.testing.zedattackproxy.views; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.eclipse.jface.action.Action; 7 | import org.eclipse.jface.action.IMenuManager; 8 | import org.eclipse.jface.action.IToolBarManager; 9 | import org.eclipse.jface.action.MenuManager; 10 | import org.eclipse.jface.action.Separator; 11 | import org.eclipse.swt.SWT; 12 | import org.eclipse.swt.custom.ScrolledComposite; 13 | import org.eclipse.swt.layout.GridData; 14 | import org.eclipse.swt.layout.GridLayout; 15 | import org.eclipse.swt.layout.RowLayout; 16 | import org.eclipse.swt.widgets.Button; 17 | import org.eclipse.swt.widgets.Composite; 18 | import org.eclipse.swt.widgets.Control; 19 | import org.eclipse.swt.widgets.Label; 20 | import org.eclipse.swt.widgets.Text; 21 | import org.eclipse.ui.console.ConsolePlugin; 22 | import org.eclipse.ui.part.ViewPart; 23 | import org.zaproxy.clientapi.core.ApiResponse; 24 | import org.zaproxy.clientapi.core.ApiResponseElement; 25 | import org.zaproxy.clientapi.core.ApiResponseList; 26 | import org.zaproxy.clientapi.core.ApiResponseSet; 27 | import org.zaproxy.clientapi.core.ClientApi; 28 | import org.zaproxy.clientapi.core.ClientApiException; 29 | 30 | import com.polyhedral.security.testing.zedattackproxy.actions.CancelZAPScanAction; 31 | import com.polyhedral.security.testing.zedattackproxy.actions.RunZAPScanAction; 32 | import com.polyhedral.security.testing.zedattackproxy.actions.ScanProgress; 33 | import com.polyhedral.security.testing.zedattackproxy.actions.StartZAPAction; 34 | import com.polyhedral.security.testing.zedattackproxy.actions.StopZAPAction; 35 | import com.polyhedral.security.testing.zedattackproxy.actions.ZAPAction; 36 | import com.polyhedral.security.testing.zedattackproxy.actions.menu.ascan.AllowAttackOnStartToggle; 37 | import com.polyhedral.security.testing.zedattackproxy.actions.menu.ascan.HandleAntiCSRFTokensToggle; 38 | import com.polyhedral.security.testing.zedattackproxy.actions.menu.ascan.InjectPluginIdInHeaderToggle; 39 | import com.polyhedral.security.testing.zedattackproxy.actions.menu.ascan.RescanInAttackModeToggle; 40 | import com.polyhedral.security.testing.zedattackproxy.actions.menu.spider.ParseCommentsToggle; 41 | import com.polyhedral.security.testing.zedattackproxy.actions.menu.spider.ParseGitToggle; 42 | import com.polyhedral.security.testing.zedattackproxy.actions.menu.spider.ParseRobotsTxtToggle; 43 | import com.polyhedral.security.testing.zedattackproxy.actions.menu.spider.ParseSitemapXmlToggle; 44 | import com.polyhedral.security.testing.zedattackproxy.actions.menu.spider.ParseSvnEntriesToggle; 45 | import com.polyhedral.security.testing.zedattackproxy.actions.menu.spider.PostFormToggle; 46 | import com.polyhedral.security.testing.zedattackproxy.actions.menu.spider.ProcessFormToggle; 47 | import com.polyhedral.security.testing.zedattackproxy.actions.menu.spider.SendRefererHeaderToggle; 48 | import com.polyhedral.security.testing.zedattackproxy.events.IZAPEventListener; 49 | import com.polyhedral.security.testing.zedattackproxy.events.ZAPEventType; 50 | import com.polyhedral.security.testing.zedattackproxy.utils.ZAPHelper; 51 | 52 | /** 53 | * The Zed Attack Proxy Eclipse view component. This view contains action 54 | * buttons for starting, stopping, and interacting with ZAP. It also includes 55 | * ZAP configuration options and scan configuration details. When a ZAP scan is 56 | * initiated, it will show the progress of the seledted scan. 57 | */ 58 | public class ZAPView extends ViewPart implements IZAPEventListener { 59 | 60 | private RunZAPScanAction runZAPScanAction; 61 | private ZAPAction startZapAction; 62 | private ZAPAction cancelZAPScanAction; 63 | private ZAPAction stopZapAction; 64 | 65 | private Composite parent; 66 | private ScrolledComposite pageScroll; 67 | private Text urlText; 68 | private Text fileNameText; 69 | private Composite reportFormat; 70 | private List zapPolicyList; 71 | 72 | private String tempUrlTextValue; 73 | private String tempFileNameTextValue; 74 | private String tempReportFormatValue; 75 | private ScanProgress scanProgress; 76 | 77 | /** 78 | * Initialize the ZAP view. 79 | */ 80 | @Override 81 | public void createPartControl(Composite parent) { 82 | this.parent = parent; 83 | 84 | // Initialize view controls and display content. 85 | createToolbar(); 86 | enableToolbarActions(); 87 | disableCancelButton(); 88 | 89 | // Enable view controls based on whether ZAP is currently running. 90 | if (ZAPHelper.getInstance().isZapRunning()) { 91 | drawZAPControls(); 92 | } else { 93 | removeZAPControls(); 94 | } 95 | } 96 | 97 | /** 98 | * @return The URL text {@link String} entered by the user. 99 | */ 100 | public String getUrlText() { 101 | return (urlText != null && !urlText.isDisposed()) ? urlText.getText() : ""; 102 | } 103 | 104 | /** 105 | * @return The file name text {@link String} entered by by the user. 106 | */ 107 | public String getFileNameText() { 108 | return (fileNameText != null && !fileNameText.isDisposed()) ? fileNameText.getText() : ""; 109 | } 110 | 111 | /** 112 | * @return the {@link List} of {@link ZAPPolicyEditor} instances currently 113 | * available. 114 | */ 115 | public List getZapPolicyList() { 116 | return (zapPolicyList != null) ? zapPolicyList : new ArrayList(); 117 | } 118 | 119 | /** 120 | * @return The report format {@link String} selected by the user. 121 | */ 122 | public String getReportFormat() { 123 | if (reportFormat != null) { 124 | for (Control formatOption : reportFormat.getChildren()) { 125 | Button buttonOption = (Button) formatOption; 126 | if (buttonOption.getSelection()) { 127 | return buttonOption.getText(); 128 | } 129 | } 130 | } 131 | 132 | return null; 133 | } 134 | 135 | /** 136 | * 137 | */ 138 | @Override 139 | public void setFocus() { 140 | } 141 | 142 | /** 143 | * Initialize the {@link ScrolledComposite} wrapper for the ZAP view. 144 | */ 145 | private void initPageScroll() { 146 | if (pageScroll != null && !pageScroll.isDisposed()) { 147 | pageScroll.dispose(); 148 | } 149 | pageScroll = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL); 150 | pageScroll.setBackground(pageScroll.getDisplay().getSystemColor(SWT.COLOR_WHITE)); 151 | pageScroll.setBackgroundMode(SWT.INHERIT_DEFAULT); 152 | pageScroll.setMinHeight(250); 153 | pageScroll.setMinWidth(250); 154 | } 155 | 156 | /** 157 | * Create the ZAP view toolbar. 158 | */ 159 | private void createToolbar() { 160 | IToolBarManager toolbarManager = getViewSite().getActionBars().getToolBarManager(); 161 | 162 | // Create the Run ZAP Scan action. 163 | runZAPScanAction = new RunZAPScanAction(); 164 | runZAPScanAction.addZAPEventListener(this); 165 | runZAPScanAction.setZapView(this); 166 | toolbarManager.add(runZAPScanAction); 167 | 168 | // Create the Start ZAP action. 169 | startZapAction = new StartZAPAction(); 170 | startZapAction.addZAPEventListener(this); 171 | toolbarManager.add(startZapAction); 172 | 173 | // create the Cancel ZAP Scan action. 174 | cancelZAPScanAction = new CancelZAPScanAction(); 175 | cancelZAPScanAction.addZAPEventListener(this); 176 | toolbarManager.add(cancelZAPScanAction); 177 | 178 | // Create the Stop ZAP action. 179 | stopZapAction = new StopZAPAction(); 180 | stopZapAction.addZAPEventListener(this); 181 | toolbarManager.add(stopZapAction); 182 | 183 | // The ZAP view acts as the processor for all ZAP events, so it needs to 184 | // be added to the ZAPHelper instance to listen for properties 185 | // configuration changes. 186 | ZAPHelper.getInstance().addZAPEventListener(this); 187 | 188 | // Perform an inital check of the ZAP properties configuration to help 189 | // set the toolbar buttons to the correct state. This needs to be called 190 | // explicitly because incorrectly configured properties will not fire an 191 | // event until the ZAP properties tab is opened. 192 | ZAPHelper.getInstance().checkZapConfiguration(); 193 | } 194 | 195 | /** 196 | * Create the ZAP view menu dropdown. This is only enabled when the plugin 197 | * is properly configured, the ZAP server is running, and a scan is not 198 | * currently processing. 199 | * 200 | * @param enableMenu 201 | * A boolean determining if the menu should be enabled or not. 202 | * The menu is enabled when set to true, disabled when set to 203 | * false. 204 | */ 205 | private void configureMenuManager(boolean enableMenu) { 206 | IMenuManager menuManager = getViewSite().getActionBars().getMenuManager(); 207 | menuManager.setVisible(true); 208 | if (enableMenu) { 209 | menuManager.removeAll(); 210 | 211 | MenuManager spiderMenu = new MenuManager("ZAP Spider Configuration"); 212 | spiderMenu.add(new ParseCommentsToggle()); 213 | spiderMenu.add(new ParseGitToggle()); 214 | spiderMenu.add(new ParseRobotsTxtToggle()); 215 | spiderMenu.add(new ParseSvnEntriesToggle()); 216 | spiderMenu.add(new ParseSitemapXmlToggle()); 217 | spiderMenu.add(new PostFormToggle()); 218 | spiderMenu.add(new ProcessFormToggle()); 219 | spiderMenu.add(new SendRefererHeaderToggle()); 220 | menuManager.add(spiderMenu); 221 | 222 | menuManager.add(new Separator()); 223 | 224 | MenuManager ascanMenu = new MenuManager("ZAP Ascan Configuration"); 225 | ascanMenu.add(new AllowAttackOnStartToggle()); 226 | ascanMenu.add(new HandleAntiCSRFTokensToggle()); 227 | ascanMenu.add(new InjectPluginIdInHeaderToggle()); 228 | ascanMenu.add(new RescanInAttackModeToggle()); 229 | menuManager.add(ascanMenu); 230 | 231 | } else { 232 | menuManager.removeAll(); 233 | Action noConfigurationAction = new Action("Configuration Unavailabile") { 234 | }; 235 | noConfigurationAction.setEnabled(false); 236 | menuManager.add(noConfigurationAction); 237 | } 238 | } 239 | 240 | /** 241 | * Enable/disable the toolbar action icons based on the current status of 242 | * the ZAP server. 243 | */ 244 | private void enableToolbarActions() { 245 | boolean zapConfigurationValid = ZAPHelper.getInstance().isZapConfigurationValid(); 246 | boolean zapRunning = ZAPHelper.getInstance().isZapRunning(); 247 | runZAPScanAction.setEnabled(zapConfigurationValid && zapRunning); 248 | startZapAction.setEnabled(zapConfigurationValid && !zapRunning); 249 | stopZapAction.setEnabled(zapConfigurationValid && zapRunning); 250 | configureMenuManager(zapConfigurationValid && zapRunning); 251 | } 252 | 253 | /** 254 | * Disable all toolbar action icons. This is generally done when an 255 | * interrupting function has been triggered, such as starting/stopping the 256 | * ZAP server or performing a scan. 257 | */ 258 | private void disableToolbarActions() { 259 | runZAPScanAction.setEnabled(false); 260 | startZapAction.setEnabled(false); 261 | stopZapAction.setEnabled(false); 262 | configureMenuManager(false); 263 | } 264 | 265 | /** 266 | * Enable/disable the cancel button based on the current status of the ZAP 267 | * server. This is performed separately from the rest of the toolbar actions 268 | * because it has a unique state when a scan is running. 269 | */ 270 | private void enableCancelButton() { 271 | cancelZAPScanAction.setEnabled(true); 272 | } 273 | 274 | /** 275 | * Disable the cancel button. This is performed separately from the rest of 276 | * the toolbar actions because it has a unique state when a scan is running. 277 | */ 278 | private void disableCancelButton() { 279 | cancelZAPScanAction.setEnabled(false); 280 | } 281 | 282 | /** 283 | * Update the ZAP view with the status of the ZAP scan. 284 | */ 285 | private void drawZAPProgress() { 286 | ClientApi zapAPI = ZAPHelper.getInstance().getZAPClient(); 287 | 288 | // Re-initialize the ZAP view to remove the previous status data. 289 | initPageScroll(); 290 | 291 | // Create the page layout. 292 | Composite pageComposite = new Composite(pageScroll, SWT.NONE); 293 | pageComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 294 | pageComposite.setLayout(new GridLayout(1, true)); 295 | pageScroll.setContent(pageComposite); 296 | 297 | Composite inputComposite = new Composite(pageComposite, SWT.NONE); 298 | inputComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 299 | inputComposite.setLayout(new GridLayout(1, false)); 300 | 301 | // Display the current root URL being scanned. 302 | new Label(inputComposite, SWT.NONE).setText("Scan Target URL:"); 303 | new Label(inputComposite, SWT.NONE).setText(tempUrlTextValue); 304 | new Label(inputComposite, SWT.NONE).setText(""); 305 | 306 | Composite scanComposite = new Composite(pageComposite, SWT.NONE); 307 | scanComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 308 | scanComposite.setLayout(new GridLayout(2, false)); 309 | 310 | // If the spider has started, display it's current status. Otherwise 311 | // show its progress as 0%. 312 | if (scanProgress.getSpiderId() != null) { 313 | try { 314 | Label spiderProgress = new Label(scanComposite, SWT.WRAP); 315 | spiderProgress.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true)); 316 | ((GridData) spiderProgress.getLayoutData()).widthHint = 150; 317 | spiderProgress.setText("Spider Progress:"); 318 | new Label(scanComposite, SWT.NONE).setText( 319 | ((ApiResponseElement) zapAPI.spider.status(scanProgress.getSpiderId())).getValue() + "%"); 320 | new Label(scanComposite, SWT.NONE).setText(""); 321 | new Label(scanComposite, SWT.NONE).setText(""); 322 | } catch (ClientApiException e) { 323 | ConsolePlugin.log(e); 324 | } 325 | } else { 326 | Label spiderProgress = new Label(scanComposite, SWT.WRAP); 327 | spiderProgress.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true)); 328 | ((GridData) spiderProgress.getLayoutData()).widthHint = 150; 329 | spiderProgress.setText("Spider Progress:"); 330 | new Label(scanComposite, SWT.NONE).setText("0%"); 331 | new Label(scanComposite, SWT.NONE).setText(""); 332 | new Label(scanComposite, SWT.NONE).setText(""); 333 | } 334 | 335 | // If the ascan has started, display it's current status with detailed 336 | // information about each ascan policy that is being triggered. If the 337 | // ascan has not started, show its progress as 0%. 338 | if (scanProgress.getAscanId() != null) { 339 | try { 340 | new Label(scanComposite, SWT.NONE).setText("Ascan Progress:"); 341 | new Label(scanComposite, SWT.NONE).setText( 342 | ((ApiResponseElement) zapAPI.ascan.status(scanProgress.getAscanId())).getValue() + "%"); 343 | 344 | ApiResponseList ascanProgress = (ApiResponseList) zapAPI.ascan.scanProgress(scanProgress.getAscanId()); 345 | ApiResponseList scanProgressList = (ApiResponseList) ascanProgress.getItems().get(1); 346 | for (ApiResponse scanItem : scanProgressList.getItems()) { 347 | ApiResponseList scanItemList = (ApiResponseList) scanItem; 348 | String name = ""; 349 | String status = ""; 350 | String timeCount = ""; 351 | 352 | // The ZAP API returns scan information as a list of 353 | // ApiResponseList items instead of as a Map. To get the 354 | // current scan information, the whole list has to be 355 | // iterated through to get the scan name, status, and time 356 | // count. 357 | for (ApiResponse scanElementItem : scanItemList.getItems()) { 358 | ApiResponseElement scanElement = (ApiResponseElement) scanElementItem; 359 | if (scanElement.getName().equals("name")) { 360 | name = scanElement.getValue(); 361 | } else if (scanElement.getName().equals("status")) { 362 | status = scanElement.getValue(); 363 | } else if (scanElement.getName().equals("timeInMs")) { 364 | timeCount = scanElement.getValue(); 365 | } 366 | } 367 | Label scanName = new Label(scanComposite, SWT.WRAP); 368 | scanName.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true)); 369 | ((GridData) scanName.getLayoutData()).widthHint = 200; 370 | scanName.setText(name); 371 | new Label(scanComposite, SWT.NONE).setText(status + " (" + timeCount + " ms)"); 372 | } 373 | } catch (ClientApiException e) { 374 | ConsolePlugin.log(e); 375 | } 376 | } else { 377 | new Label(scanComposite, SWT.NONE).setText("Ascan Progress:"); 378 | new Label(scanComposite, SWT.NONE).setText("0%"); 379 | } 380 | 381 | pageComposite.setSize(pageComposite.computeSize(350, SWT.DEFAULT)); 382 | 383 | refreshParent(); 384 | } 385 | 386 | /** 387 | * Draw the user input fields for running a ZAP scan. 388 | */ 389 | private void drawZAPControls() { 390 | // Re-initialize the ZAP view to remove any previous view components. 391 | initPageScroll(); 392 | 393 | // Create the page layout. 394 | Composite pageComposite = new Composite(pageScroll, SWT.NONE); 395 | pageComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 396 | pageComposite.setLayout(new GridLayout(1, true)); 397 | pageScroll.setContent(pageComposite); 398 | 399 | Composite inputComposite = new Composite(pageComposite, SWT.NONE); 400 | inputComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 401 | inputComposite.setLayout(new GridLayout(2, false)); 402 | 403 | // Input field for the URL to be scanned. 404 | new Label(inputComposite, SWT.NONE).setText("Scan Target URL:"); 405 | urlText = new Text(inputComposite, SWT.SINGLE | SWT.BORDER); 406 | urlText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 407 | urlText.setText((tempUrlTextValue != null) ? tempUrlTextValue : ""); 408 | 409 | // Input field for the file name where the scan will be saved. 410 | new Label(inputComposite, SWT.NONE).setText("Scan Result File:"); 411 | fileNameText = new Text(inputComposite, SWT.SINGLE | SWT.BORDER); 412 | fileNameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 413 | fileNameText.setText((tempFileNameTextValue != null) ? tempFileNameTextValue : ""); 414 | 415 | // Selected report format for the scan. Current options are XML and 416 | // HTML. 417 | new Label(inputComposite, SWT.NONE).setText("Report Format:"); 418 | reportFormat = new Composite(inputComposite, SWT.NULL); 419 | reportFormat.setLayout(new RowLayout()); 420 | Button xmlButton = new Button(reportFormat, SWT.RADIO); 421 | xmlButton.setText("XML"); 422 | if ("XML".equals(tempReportFormatValue)) { 423 | xmlButton.setSelection(true); 424 | } 425 | Button htmlButton = new Button(reportFormat, SWT.RADIO); 426 | htmlButton.setText("HTML"); 427 | if ("HTML".equals(tempReportFormatValue)) { 428 | htmlButton.setSelection(true); 429 | } 430 | 431 | Composite levelsComposite = new Composite(pageComposite, SWT.NONE); 432 | levelsComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 433 | levelsComposite.setLayout(new GridLayout(3, false)); 434 | 435 | // Display headers for the currently available ZAP scan policies. 436 | Label firstColumnHeader = new Label(levelsComposite, SWT.WRAP); 437 | firstColumnHeader.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true)); 438 | ((GridData) firstColumnHeader.getLayoutData()).widthHint = 80; 439 | firstColumnHeader.setText("Policy"); 440 | 441 | Label secondColumnHeader = new Label(levelsComposite, SWT.WRAP); 442 | secondColumnHeader.setLayoutData(new GridData(SWT.CENTER, SWT.NONE, false, true)); 443 | ((GridData) secondColumnHeader.getLayoutData()).widthHint = 135; 444 | secondColumnHeader.setText("Attack Strength"); 445 | 446 | Label thirdColumnHeader = new Label(levelsComposite, SWT.WRAP); 447 | thirdColumnHeader.setLayoutData(new GridData(SWT.CENTER, SWT.NONE, false, true)); 448 | ((GridData) thirdColumnHeader.getLayoutData()).widthHint = 135; 449 | thirdColumnHeader.setText("Alert Threshold"); 450 | 451 | try { 452 | // Iterate through all of the available ZAP scan policies, set their 453 | // current values, and allow the user to select new values for 454 | // attack strength and alert threshold (if desired). 455 | ApiResponseList zapPolicies = (ApiResponseList) ZAPHelper.getInstance().getZAPClient().ascan.policies("", 456 | ""); 457 | zapPolicyList = new ArrayList(); 458 | for (ApiResponse policyItem : zapPolicies.getItems()) { 459 | zapPolicyList.add(new ZAPPolicyEditor(levelsComposite, (ApiResponseSet) policyItem)); 460 | } 461 | 462 | } catch (ClientApiException e) { 463 | ConsolePlugin.log(e); 464 | } 465 | 466 | pageComposite.setSize(pageComposite.computeSize(350, SWT.DEFAULT)); 467 | 468 | refreshParent(); 469 | } 470 | 471 | /** 472 | * Remove ZAP controls. This is done at times where there is no ZAP server 473 | * to access so no information can be displayed in the ZAP view. 474 | */ 475 | private void removeZAPControls() { 476 | initPageScroll(); 477 | refreshParent(); 478 | } 479 | 480 | /** 481 | * Repaint the ZAP view. 482 | */ 483 | private void refreshParent() { 484 | parent.layout(); 485 | } 486 | 487 | /** 488 | * Implementation of the ZAP event handler. The ZAP view actions will signal 489 | * the view when specific events happen, and the ZAP view will repaint the 490 | * ZAP view according to the current state. 491 | */ 492 | @Override 493 | public void handleZAPEvent(ZAPEventType eventType, ScanProgress scanProgress) { 494 | this.scanProgress = scanProgress; 495 | 496 | // TODO [On Hold] Currently, ZAP locks up when stopping a spider 497 | // request, so cancel button is not enabled until 498 | // the ascan is triggered. After ZAP fixes the spider problem, the 499 | // cancel button should be enabled 500 | // when the spider starts. 501 | switch (eventType) { 502 | case SERVER_STARTED: 503 | disableToolbarActions(); 504 | break; 505 | case SERVER_STOP_REQUESTED: 506 | disableCancelButton(); 507 | disableToolbarActions(); 508 | break; 509 | case SCAN_PROGRESS: 510 | disableToolbarActions(); 511 | drawZAPProgress(); 512 | break; 513 | case SCAN_SPIDER_STARTED: 514 | disableToolbarActions(); 515 | tempUrlTextValue = urlText.getText(); 516 | tempFileNameTextValue = fileNameText.getText(); 517 | tempReportFormatValue = getReportFormat(); 518 | break; 519 | case SCAN_CANCEL_STARTED: 520 | runZAPScanAction.cancelScan(); 521 | disableCancelButton(); 522 | removeZAPControls(); 523 | break; 524 | case SCAN_ASCAN_STARTED: 525 | enableCancelButton(); 526 | break; 527 | case SCAN_COMPLETE: 528 | disableCancelButton(); 529 | drawZAPControls(); 530 | enableToolbarActions(); 531 | break; 532 | case SERVER_STARTUP_COMPLETE: 533 | drawZAPControls(); 534 | enableToolbarActions(); 535 | break; 536 | case SCAN_CANCEL_COMPLETE: 537 | drawZAPControls(); 538 | enableToolbarActions(); 539 | break; 540 | case SERVER_STOPPED: 541 | removeZAPControls(); 542 | enableToolbarActions(); 543 | break; 544 | default: 545 | enableToolbarActions(); 546 | break; 547 | } 548 | } 549 | } -------------------------------------------------------------------------------- /images/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/64ade5f56e7e9dce3e126f58194dc02ae461a437/images/.DS_Store -------------------------------------------------------------------------------- /images/StartZAPIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/64ade5f56e7e9dce3e126f58194dc02ae461a437/images/StartZAPIcon.png -------------------------------------------------------------------------------- /images/ZAPConfiguration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/64ade5f56e7e9dce3e126f58194dc02ae461a437/images/ZAPConfiguration.png -------------------------------------------------------------------------------- /images/ZAPScanProgress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/64ade5f56e7e9dce3e126f58194dc02ae461a437/images/ZAPScanProgress.png -------------------------------------------------------------------------------- /images/ZAPScanResults.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/64ade5f56e7e9dce3e126f58194dc02ae461a437/images/ZAPScanResults.png -------------------------------------------------------------------------------- /images/ZAPScanSettings-StartScanButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/64ade5f56e7e9dce3e126f58194dc02ae461a437/images/ZAPScanSettings-StartScanButton.png -------------------------------------------------------------------------------- /images/ZAPScanSettings-StopZAPButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/64ade5f56e7e9dce3e126f58194dc02ae461a437/images/ZAPScanSettings-StopZAPButton.png -------------------------------------------------------------------------------- /images/ZAPScanSettings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polyhedraltech/SecurityTesting/64ade5f56e7e9dce3e126f58194dc02ae461a437/images/ZAPScanSettings.png --------------------------------------------------------------------------------