diff --git a/Dockerfile b/Dockerfile index cae1981c..52e2df74 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,6 +22,8 @@ COPY --from=builder ./scb-scanprocesses/sslyze-process/target/sslyze-process-0.0 COPY --from=builder ./scb-scanprocesses/arachni-process/target/arachni-process-1.0-SNAPSHOT.jar /scb-engine/lib/ COPY --from=builder ./scb-scanprocesses/ssh-process/target/ssh-process-1.0-SNAPSHOT.jar /scb-engine/lib/ COPY --from=builder ./scb-scanprocesses/amass-process/target/amass-process-1.0-SNAPSHOT.jar /scb-engine/lib/ +COPY --from=builder ./scb-scanprocesses/wordpress-process/target/wordpress-process-1.0-SNAPSHOT.jar /scb-engine/lib/ + COPY --from=builder ./scb-persistenceproviders/elasticsearch-persistenceprovider/target/elasticsearch-persistenceprovider-0.0.1-SNAPSHOT-jar-with-dependencies.jar /scb-engine/lib/ COPY --from=builder ./scb-persistenceproviders/s3-persistenceprovider/target/s3-persistenceprovider-0.0.1-SNAPSHOT-jar-with-dependencies.jar /scb-engine/lib/ diff --git a/scb-engine/pom.xml b/scb-engine/pom.xml index 17bfc91c..a7c8bce5 100644 --- a/scb-engine/pom.xml +++ b/scb-engine/pom.xml @@ -201,6 +201,12 @@ 1.0-SNAPSHOT runtime + + io.securecodebox.scanprocesses + wordpress-process + 1.0-SNAPSHOT + runtime + io.securecodebox.persistenceproviders elasticsearch-persistenceprovider diff --git a/scb-scanprocesses/pom.xml b/scb-scanprocesses/pom.xml index 7ae6b24e..bedac331 100644 --- a/scb-scanprocesses/pom.xml +++ b/scb-scanprocesses/pom.xml @@ -25,6 +25,7 @@ arachni-process amass-process ssh-process + wordpress-process \ No newline at end of file diff --git a/scb-scanprocesses/wordpress-process/pom.xml b/scb-scanprocesses/wordpress-process/pom.xml new file mode 100644 index 00000000..0d04a9f4 --- /dev/null +++ b/scb-scanprocesses/wordpress-process/pom.xml @@ -0,0 +1,53 @@ + + 4.0.0 + + + io.securecodebox.scanprocesses + default-process-collection + 0.0.1-SNAPSHOT + + + io.securecodebox.scanprocesses + wordpress-process + 1.0-SNAPSHOT + + + + io.securecodebox.core + sdk + ${project.parent.version} + + + + + com.h2database + h2 + + + org.camunda.bpm.springboot + camunda-bpm-spring-boot-starter-test + test + + + org.camunda.bpm.extension.mockito + camunda-bpm-mockito + test + + + org.camunda.bpm.extension + camunda-bpm-assert-scenario + test + + + org.camunda.bpm.extension + camunda-bpm-process-test-coverage + test + + + org.camunda.bpm.extension + camunda-bpm-assert + + + + diff --git a/scb-scanprocesses/wordpress-process/src/main/java/io/securecodebox/scanprocess/ProcessInitConfiguration.java b/scb-scanprocesses/wordpress-process/src/main/java/io/securecodebox/scanprocess/ProcessInitConfiguration.java new file mode 100644 index 00000000..6912cde3 --- /dev/null +++ b/scb-scanprocesses/wordpress-process/src/main/java/io/securecodebox/scanprocess/ProcessInitConfiguration.java @@ -0,0 +1,36 @@ +/* + * + * SecureCodeBox (SCB) + * Copyright 2015-2018 iteratec GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * / + */ + +package io.securecodebox.scanprocess; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +/** + * The secureCodeBox by default only scans for components in the package io.securecodebox.scanprocess. + *

+ * This configuration ensures that your defined package package also gets scanned, please don't move or remove this configuration. + * + * @author RĂ¼diger Heins - iteratec GmbH + * @since 09.05.18 + */ +@ComponentScan("io.securecodebox.scanprocesses") +@Configuration +public class ProcessInitConfiguration { +} diff --git a/scb-scanprocesses/wordpress-process/src/main/resources/META-INF/processes.xml b/scb-scanprocesses/wordpress-process/src/main/resources/META-INF/processes.xml new file mode 100644 index 00000000..e69de29b diff --git a/scb-scanprocesses/wordpress-process/src/main/resources/bpmn/wordpress_process.bpmn b/scb-scanprocesses/wordpress-process/src/main/resources/bpmn/wordpress_process.bpmn new file mode 100644 index 00000000..bc86da49 --- /dev/null +++ b/scb-scanprocesses/wordpress-process/src/main/resources/bpmn/wordpress_process.bpmn @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + SequenceFlow_TargetConfigured + + + + SequenceFlow_SummaryCreated + + + + + + + + SequenceFlow_ManualFinish + SequenceFlow_ResultReviewed + + + SequenceFlow_ResultReviewed + SequenceFlow_ResultApproved + SequenceFlow_ResultRejected + + + + + + SequenceFlow_PortscanFinished + SequenceFlow_ManualFinish + SequenceFlow_AutomatedFinish + + + ${PROCESS_AUTOMATED == false} + + + ${PROCESS_AUTOMATED == true} + + + + SequenceFlow_TargetConfigured + SequenceFlow_PortscanFinished + + + + + SequenceFlow_ResultApproved + SequenceFlow_1i44eck + SequenceFlow_AutomatedFinish + SequenceFlow_SummaryCreated + + + + + + + + SequenceFlow_ResultRejected + SequenceFlow_1i44eck + + + + results in a generic format + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scb-scanprocesses/wordpress-process/src/main/resources/forms/wordpress/approve-results.html b/scb-scanprocesses/wordpress-process/src/main/resources/forms/wordpress/approve-results.html new file mode 100644 index 00000000..2efa97f8 --- /dev/null +++ b/scb-scanprocesses/wordpress-process/src/main/resources/forms/wordpress/approve-results.html @@ -0,0 +1,122 @@ + + +

+ + +
+

WordPress scan results for "{{ target.name }}"

+ +
+
+
{{ scannerId }}
+
+
+
+
{{ target.location }}
+
+
+
+
{{ context }}
+
+
+
+
+ + + + + + + + + + + + + + + + + +
Host:Name:DescriptionCategory:Severity:Reference:
{{ result.location }}{{ result.name }}{{ result.description }}{{ result.category }} +
+ + + {{ result.severity }} + + + + + {{ result.severity }} + + + + + {{ result.severity }} + + + + + {{ result.severity }} + +
+
{{ result.reference.id }}
+
+
+
+
+

Approve Result

+ +
+ +
+ + +
+
+
diff --git a/scb-scanprocesses/wordpress-process/src/main/resources/forms/wordpress/configure-target.html b/scb-scanprocesses/wordpress-process/src/main/resources/forms/wordpress/configure-target.html new file mode 100644 index 00000000..2a471911 --- /dev/null +++ b/scb-scanprocesses/wordpress-process/src/main/resources/forms/wordpress/configure-target.html @@ -0,0 +1,376 @@ + + +

Please configure the WordPress Scan

+ +
+ + + + + + + + +
+ +
+

WordPress scan Target

+ + +
+
+
+ + +
+
+ + +
+
+ +
+
+ + +
+ + +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+ +
+ +
+ +
+ + +
+
+
diff --git a/scb-scanprocesses/wordpress-process/src/test/java/io/securecodebox/scanprocess/test/WordpressProcessTest.java b/scb-scanprocesses/wordpress-process/src/test/java/io/securecodebox/scanprocess/test/WordpressProcessTest.java new file mode 100644 index 00000000..8f3b19cc --- /dev/null +++ b/scb-scanprocesses/wordpress-process/src/test/java/io/securecodebox/scanprocess/test/WordpressProcessTest.java @@ -0,0 +1,236 @@ +/* + * + * SecureCodeBox (SCB) + * Copyright 2015-2018 iteratec GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * / + */ + +package io.securecodebox.scanprocess.test; + +import io.securecodebox.constants.DefaultFields; +import io.securecodebox.scanprocess.delegate.SummaryGeneratorDelegate; +import org.camunda.bpm.engine.ExternalTaskService; +import org.camunda.bpm.engine.delegate.DelegateTask; +import org.camunda.bpm.engine.delegate.Expression; +import org.camunda.bpm.engine.delegate.TaskListener; +import org.camunda.bpm.engine.externaltask.LockedExternalTask; +import org.camunda.bpm.engine.runtime.ProcessInstance; +import org.camunda.bpm.engine.test.Deployment; +import org.camunda.bpm.engine.test.ProcessEngineRule; +import org.camunda.bpm.engine.test.mock.Mocks; +import org.camunda.bpm.extension.process_test_coverage.junit.rules.TestCoverageProcessEngineRuleBuilder; +import org.camunda.bpm.scenario.ProcessScenario; +import org.camunda.bpm.scenario.Scenario; +import org.camunda.bpm.scenario.delegate.ExternalTaskDelegate; +import org.camunda.bpm.scenario.delegate.TaskDelegate; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.camunda.bpm.engine.test.assertions.ProcessEngineTests.*; +import static org.camunda.bpm.extension.mockito.CamundaMockito.autoMock; +import static org.mockito.Mockito.when; + +/** + * This class tests the process execution of the Default-Process BPMN Model + * It verifies that each process task is called when it's supposed to be and + * delegation code is executed at the right time + *

+ * The tests run in an own Camunda engine which is defined by the camunda.cfg.xml in the resources directory + *

+ * The test cases use Camunda BPM's standard framework as well as the + * Camunda BPM Assert extension (), + * camunda-bpm-mockito () + * and the Camunda BPM Assert Scenario extension () + *

+ * Furthermore this class also uses the Camunda BPM Process Test Coverage extension + * (). + * After the test is run we can examine the test coverage in the directory target/process-test-coverage + */ + +@RunWith(SpringJUnit4ClassRunner.class) +@Deployment(resources = "bpmn/wordpress_process.bpmn") + +@Ignore("Ignored until problems with camunda testing frameworks are handled. Introduces via update to camunda 7.10") +public class WordpressProcessTest { + + //Define the Process Activity IDs + private static final String PROCESS_ID = "wordpress-process"; + private static final String DO_SCAN_TASK_ID = "ServiceTask_DoScan"; + private static final String APPROVE_RESULTS_TASK_ID = "UserTask_ApproveResults"; + + private final Map defaultVariables = new HashMap<>(); + + @Rule + @ClassRule + public static ProcessEngineRule processEngineRule = TestCoverageProcessEngineRuleBuilder.create().build(); + + @Mock + private ProcessScenario process; + + @Mock + protected SummaryGeneratorDelegate delegate; + + /** + * Executed before every test-case + * In this method default variables for the process and a default behaviour for the mocks + * in the process are defined+ + */ + @Before + public void init() { + + MockitoAnnotations.initMocks(this); + + //Creating a map of default variables for the process + defaultVariables.put(DefaultFields.PROCESS_AUTOMATED.name(), true); + defaultVariables.put(DefaultFields.PROCESS_CONTEXT.name(), "BodgeIT"); + + /* + Mocking everything in the BPMN Model + This includes ExecutionListeners, TaskListeners, JavaDelegates, etc. + Simply stated: Everything, that's executable code + + If you need to define custom behaviour for the Mocks you can do so by + registering Mocks with Camunda's method "Mocks.register(String key, Object value)". + Here the key describes a delegateExpression (as defined in BPMN model) and the value + describes the implementation of the code which should be executed + (Hint: You can put the real implementation as well as a fake one in there) + + Note: Most of the mocking methods seem to work only in combination with delegateExpressions + but not with class definitions as delegate implementation. + + If you have the path to your executable code (the class for delegate) as delegate implementation + then this guide is helpful: + https://blog.akquinet.de/2016/11/04/camunda-bpm-test-your-processes-based-on-plain-old-java-delegates/ + */ + autoMock("bpmn/wordpress_process.bpmn"); + + /* + Here we define a default behaviour for all the tasks in the BPMN model. + This behaviour can easily be overridden in test cases. + + The code inside the "thenReturn(...)" method specifies what should happen when process execution + waits at the given task + As a default behaviour we just complete the task and move on to the next one without changing anything + + Note that we have our own mock implementation in the last two when(...) statements. + This is because these tasks are external tasks which cannot be as easily completed as + ServiceTasks. They need an external worker to do so. + */ + when(process.waitsAtUserTask(Mockito.anyString())).thenReturn(TaskDelegate::complete); + when(process.waitsAtServiceTask(Mockito.anyString())).thenReturn(ExternalTaskDelegate::complete); + when(process.waitsAtServiceTask(DO_SCAN_TASK_ID)).thenReturn(task -> startExternalMockProcess("wordpress-process")); + } + + @Test + public void testAutomatedStartShouldPass() { + + ProcessInstance processInstance = runtimeService().startProcessInstanceByKey(PROCESS_ID, defaultVariables); + + assertThat(processInstance).isStarted(); + } + + @Test + public void testManualStartWithDefaultConfigurationShouldPass() { + ProcessInstance processInstance = runtimeService().startProcessInstanceByKey(PROCESS_ID, defaultVariables); + + assertThat(processInstance).isStarted(); + assertThat(processInstance).isWaitingAt(DO_SCAN_TASK_ID); + } + + @Test + public void testManualRunWithApprovedTestResults() { + + Map variables = new HashMap<>(defaultVariables); + changeVariable(variables, DefaultFields.PROCESS_AUTOMATED.name(), false); + + when(process.waitsAtUserTask(APPROVE_RESULTS_TASK_ID)).thenReturn(task -> { + variables.put(DefaultFields.PROCESS_RESULT_APPROVED.name(), "approved"); + task.complete(variables); + }); + + /* + Here we register a custom mock. + The BPMN model TaskListener takes an injected field variable which cannot be mocked. + Therefore we create our own TaskListener with a dummy implementation and which also + holds the variable, that should be injected. + Then we register our TaskListener with "Mocks.register(...)" and it gets executed when the delegateExpression + is called. + */ + Mocks.register("setFormUrlListener", new TaskListener() { + + /** + * Dummy implementation + */ + @Autowired + private Expression scanner_type; + + /** + * Dummy implementation + */ + @Override + public void notify(DelegateTask delegateTask) { + } + }); + + Scenario scenario = Scenario.run(process).startByKey(PROCESS_ID, variables).execute(); + + assertThat(scenario.instance(process)).isEnded(); + assertThat(scenario.instance(process)).hasPassed(APPROVE_RESULTS_TASK_ID); + assertThat(scenario.instance(process)).variables() + .containsEntry(DefaultFields.PROCESS_RESULT_APPROVED.name(), "approved"); + } + + /** + * Executes an external process without doing anything in the task. + * In the first step the job is executed on the Camunda engine. Therefore the token for the + * provided topic gets pushed. Then an external service is called to pull the token and execute the task + * + * @param topic the topic for the external task + */ + private void startExternalMockProcess(String topic) { + + ExternalTaskService externalTaskService = processEngine().getExternalTaskService(); + List lockedExternalTasks = externalTaskService.fetchAndLock(1, "worker") + .topic(topic, 5000L) + .execute(); + + assertThat(lockedExternalTasks.size()).isEqualTo(1); + + LockedExternalTask task = lockedExternalTasks.get(0); + externalTaskService.complete(task.getId(), "worker"); + } + + private void changeVariable(Map variables, String key, Object value) { + + if (variables.containsKey(key)) { + variables.remove(key); + } + variables.put(key, value); + } + +} diff --git a/scb-scanprocesses/wordpress-process/src/test/resources/camunda.cfg.xml b/scb-scanprocesses/wordpress-process/src/test/resources/camunda.cfg.xml new file mode 100644 index 00000000..d5e7d6f9 --- /dev/null +++ b/scb-scanprocesses/wordpress-process/src/test/resources/camunda.cfg.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/scb-scanprocesses/wordpress-process/src/test/resources/logback-test.xml b/scb-scanprocesses/wordpress-process/src/test/resources/logback-test.xml new file mode 100644 index 00000000..81dcdbcd --- /dev/null +++ b/scb-scanprocesses/wordpress-process/src/test/resources/logback-test.xml @@ -0,0 +1,27 @@ + + + + + + + + + +