From f4e2bd4e3b4bd03a41cb456b44b434aaa8838ee8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6ran=20Tesse?= Date: Fri, 18 Jan 2019 16:32:01 +0100 Subject: [PATCH 1/6] work in progress --- .../src/main/resources/application-dev.yaml | 2 + .../bpmn/combined_amass_nmap_process.bpmn | 74 +++--- .../delegate/FilterHttpSecurityHeaders.java | 147 +++++++++++ .../nmap/util/HttpHeaderStrategy.java | 229 ++++++++++++++++++ .../scanprocess/nmap/util/HttpHeaders.java | 53 ++++ .../src/main/resources/bpmn/nmap_process.bpmn | 102 ++++---- .../nmap/approve-port-scanner-results.html | 6 +- .../nmap/util/HttpHeaderStrategyTest.java | 79 ++++++ 8 files changed, 618 insertions(+), 74 deletions(-) create mode 100644 scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/delegate/FilterHttpSecurityHeaders.java create mode 100644 scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/util/HttpHeaderStrategy.java create mode 100644 scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/util/HttpHeaders.java create mode 100644 scb-scanprocesses/nmap-process/src/test/java/io/securecodebox/scanprocess/nmap/util/HttpHeaderStrategyTest.java diff --git a/scb-engine/src/main/resources/application-dev.yaml b/scb-engine/src/main/resources/application-dev.yaml index afa065d0..5386ef60 100644 --- a/scb-engine/src/main/resources/application-dev.yaml +++ b/scb-engine/src/main/resources/application-dev.yaml @@ -11,6 +11,8 @@ logging.level.io.securecodebox: DEBUG # - elasticsearch securecodebox.persistence.provider: none +securecodebox.rest.auth: none + securecodebox.rest.user.scanner-default: user-id: default-scanner password: scan diff --git a/scb-scanprocesses/combined-amass-nmap-process/src/main/resources/bpmn/combined_amass_nmap_process.bpmn b/scb-scanprocesses/combined-amass-nmap-process/src/main/resources/bpmn/combined_amass_nmap_process.bpmn index 43b16955..19780238 100644 --- a/scb-scanprocesses/combined-amass-nmap-process/src/main/resources/bpmn/combined_amass_nmap_process.bpmn +++ b/scb-scanprocesses/combined-amass-nmap-process/src/main/resources/bpmn/combined_amass_nmap_process.bpmn @@ -36,7 +36,7 @@ SequenceFlow_16u7pin - SequenceFlow_0x38sun + SequenceFlow_0phvven SequenceFlow_1r4mrzm SequenceFlow_1k9fyw2 @@ -47,7 +47,7 @@ SequenceFlow_1r4mrzm SequenceFlow_0y61th0 - + ${PROCESS_AUTOMATED == false} @@ -76,6 +76,11 @@ ${PROCESS_RESULT_APPROVED != 'approved'} + + SequenceFlow_0x38sun + SequenceFlow_0phvven + + @@ -110,35 +115,35 @@ - + - + - + - + - + - + - - - + + + - + - - + + @@ -147,45 +152,52 @@ - + - + - + - - + + - + - + - + - - + + - + - - - + + + - + - - + + + + + + + + + diff --git a/scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/delegate/FilterHttpSecurityHeaders.java b/scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/delegate/FilterHttpSecurityHeaders.java new file mode 100644 index 00000000..b23637c4 --- /dev/null +++ b/scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/delegate/FilterHttpSecurityHeaders.java @@ -0,0 +1,147 @@ +package io.securecodebox.scanprocess.nmap.delegate; + +import io.securecodebox.model.execution.ScanProcessExecution; +import io.securecodebox.model.execution.ScanProcessExecutionFactory; +import io.securecodebox.model.findings.Finding; +import io.securecodebox.model.findings.Severity; +import io.securecodebox.scanprocess.nmap.util.HttpHeaderStrategy; +import io.securecodebox.scanprocess.nmap.util.HttpHeaders; +import org.camunda.bpm.engine.delegate.DelegateExecution; +import org.camunda.bpm.engine.delegate.JavaDelegate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Map; + + +@Component +public class FilterHttpSecurityHeaders implements JavaDelegate { + + private static final Logger LOG = LoggerFactory.getLogger(FilterHttpSecurityHeaders.class); + + @Autowired + ScanProcessExecutionFactory processExecutionFactory; + + + private static final HttpHeaderStrategy[] httpStrategies = new HttpHeaderStrategy[] { + requireHttpServersToRedirectToHttps() + }; + + private static final HttpHeaderStrategy[] httpsStrategies = new HttpHeaderStrategy[] { + requireStrictTransportSecurityHeader(), + requireContentSecurityPolicyHeader(), + requirePermittedCrossDomainPolicies(), + requireFrameOptionsToBeDenied(), + requireXssProtectionToBeEnabled(), + requireContentTypeOptionsToEqualNosniff() + }; + + + @Override + public void execute(DelegateExecution delegateExecution) throws Exception { + final ScanProcessExecution process = processExecutionFactory.get(delegateExecution); + final ArrayList findings = new ArrayList<>(); + final long T_START = System.currentTimeMillis(); + process.getFindings().stream() + .filter(finding -> HttpHeaders.headersPresentInFinding(finding)) + .forEach(finding -> { + final HttpHeaders headers = HttpHeaders.fromFinding(finding); + findings.addAll(applyStrategies (headers, finding)); + }); + final long T_STRATEGIES_APPLIED = System.currentTimeMillis(); + final int numberOfAdditionalFindings = findings.size() - process.getFindings().size(); + clearFindings(process); + findings.forEach(changedFinding -> process.appendFinding(changedFinding)); + LOG.info("http-headers strategies yielded {} additional findings; finding them took {}ms, storing them {}ms", numberOfAdditionalFindings, T_STRATEGIES_APPLIED - T_START, System.currentTimeMillis() - T_STRATEGIES_APPLIED); + } + + private ArrayList applyStrategies(HttpHeaders headers, Finding finding) { + final ArrayList changedFindings = new ArrayList<>(); + changedFindings.add(finding); + + final String name = finding.getName(); + + if (name.equals("http")) { + for (HttpHeaderStrategy httpStrategy : httpStrategies) { + changedFindings.addAll(httpStrategy.apply(headers, finding)); + } + } else if (name.equals("https")) { + for (HttpHeaderStrategy httpsStrategy : httpsStrategies) { + changedFindings.addAll(httpsStrategy.apply(headers, finding)); + } + } + + return changedFindings; + } + + + private static HttpHeaderStrategy requireHttpServersToRedirectToHttps() { + return new HttpHeaderStrategy("Location") + .ifPresent() + .modifyFinding((value, finding) -> { + finding.setSeverity(Severity.INFORMATIONAL); + finding.setName(finding.getName() + " with redirect to " + value); + finding.setDescription(finding.getDescription() + " with redirect to " + value); + }) + .ifMissing() + .createFinding(Severity.HIGH, "missing redirect to https"); + } + + private static HttpHeaderStrategy requireStrictTransportSecurityHeader() { + return new HttpHeaderStrategy("Strict-Transport-Security") + .ifMissingCreateFinding(Severity.MEDIUM); + } + + private static HttpHeaderStrategy requireContentSecurityPolicyHeader() { + return new HttpHeaderStrategy("Content-Security-Policy") + .ifMissingCreateFinding(Severity.MEDIUM); + } + + private static HttpHeaderStrategy requirePermittedCrossDomainPolicies() { + return new HttpHeaderStrategy("X-Permitted-Cross-Domain-Policies") + .ifMissingCreateFinding(Severity.MEDIUM); + } + + private static HttpHeaderStrategy requireFrameOptionsToBeDenied() { + return new HttpHeaderStrategy("X-Frame-Options") + .ifMissing() + .createFinding(Severity.MEDIUM, "X-Frame-Options header missing") + .ifTrue(value -> !value.toLowerCase().contains("deny")) + .createFinding(Severity.MEDIUM, "X-Frame-Options header misconfigured", value -> "X-Frame-Options should be 'deny', instead it is set to '" + value + "'"); + } + + private static HttpHeaderStrategy requireXssProtectionToBeEnabled() { + return new HttpHeaderStrategy("X-XSS-Protection") + .ifMissing() + .createFinding(Severity.MEDIUM, "X-XSS-Protection header missing") + .ifTrue(value -> value.startsWith("0")) + .createFinding(Severity.MEDIUM, "X-XSS-Protection manually disabled"); + } + + private static HttpHeaderStrategy requireContentTypeOptionsToEqualNosniff() { + return new HttpHeaderStrategy("X-Content-Type-Options") + .ifMissing() + .createFinding(Severity.MEDIUM, "X-Content-Type-Options header missing") + .ifTrue(value -> !value.equalsIgnoreCase("nosniff")) + .createFinding(Severity.MEDIUM, "X-Content-Type-Options misconfigured", value -> "X-Conntent-Type-Options should be set to 'nosniff' instead of '" + value + "'"); + } + + + private void clearFindings(ScanProcessExecution process) { + if (!process.getFindings().isEmpty()) { + LOG.debug("Clearing findings. The process had {}", process.getFindings().size()); + process.clearFindings(); + } + } + + + private static final HttpHeaderStrategy requireHeader (final String header, final Severity severity) { + return new HttpHeaderStrategy(header) + .ifMissing() + .createFinding(severity, header + " header missing"); + } + +} diff --git a/scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/util/HttpHeaderStrategy.java b/scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/util/HttpHeaderStrategy.java new file mode 100644 index 00000000..3d447cae --- /dev/null +++ b/scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/util/HttpHeaderStrategy.java @@ -0,0 +1,229 @@ +package io.securecodebox.scanprocess.nmap.util; + +import io.securecodebox.model.findings.Finding; +import io.securecodebox.model.findings.OsiLayer; +import io.securecodebox.model.findings.Severity; +import io.securecodebox.scanprocess.nmap.delegate.FilterHttpSecurityHeaders; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.UUID; +import java.util.function.BiConsumer; +import java.util.function.BiPredicate; +import java.util.function.Consumer; +import java.util.function.Function; + +public final class HttpHeaderStrategy { + private static final Logger LOG = LoggerFactory.getLogger(HttpHeaderStrategy.class); + + private final String header; + private final ArrayList tests = new ArrayList<>(); + + + public HttpHeaderStrategy (String header) { + this.header = header; + } + + /** + * Creates a finding if the header is present + * @return + */ + public HttpHeaderStrategyExpression ifPresent () { + final HttpHeaderStrategyExpression expression = new HttpHeaderStrategyExpression(this, value -> value != null); + tests.add (expression); + return expression; + } + + /** + * Creates a finding if the header is missing + * @return + */ + public HttpHeaderStrategyExpression ifMissing () { + final HttpHeaderStrategyExpression expression = new HttpHeaderStrategyExpression(this, value -> value == null); + tests.add (expression); + return expression; + } + + /** + * Convenience method, chaining {@link #ifMissing()} and {@link HttpHeaderStrategyExpression#createFinding(Severity, String)} + * @param severity + * @return + */ + public HttpHeaderStrategy ifMissingCreateFinding (Severity severity) { + return this.ifMissing().createFinding(severity, this.header + " header missing"); + } + + /** + * Performs a lambda-based check; will not execute if header not present + * @param test lambda expression function(String headerValue) -> Boolean + * @return + */ + public HttpHeaderStrategyExpression ifTrue (Function test) { + final HttpHeaderStrategyExpression expression = new HttpHeaderStrategyExpression(this, value -> value != null && test.apply(value)); + tests.add (expression); + return expression; + } + + + /** + * Apply strategy to a finding + * @param headers + * @param finding + * @return + */ + public ArrayList apply (HttpHeaders headers, Finding finding) { + final ArrayList additionalFindings = new ArrayList<>(); + for (HttpHeaderStrategyExpression test : tests) { + final String value = headers.get(this.header); + if (test.test.apply(value)) { + if (test.findingNameAndDescriptionGenerator != null) { + test.findingNameAndDescriptionGenerator.accept(value, (name, description) + -> additionalFindings.add(createApplicationLevelFinding(finding, name, test.severity, description))); + } else { + test.findingModifier.accept(value, finding); + } + } + } + return additionalFindings; + } + + + /** + * Helper class; it is the state of a strategy having a logical expression (condition) but no name/description of + * the finding to create (if condition resolves to true) + */ + public final class HttpHeaderStrategyExpression { + private final Function test; + private final HttpHeaderStrategy strategy; + private Severity severity = Severity.INFORMATIONAL; + private BiConsumer> findingNameAndDescriptionGenerator = null; + private BiConsumer findingModifier = null; + + /** + * Private constructor only to be called from class HttpHeaderStrategy + * @param strategy + * @param test + */ + private HttpHeaderStrategyExpression (HttpHeaderStrategy strategy, Function test) { + this.strategy = strategy; + this.test = test; + } + + /** + * Shortcut for {@link #createFinding(Severity, String, String)}; name is also used as description + * @param severity severity of the created finding + * @param name name and Description of the created finding + * @return + */ + public HttpHeaderStrategy createFinding (Severity severity, String name) { + return this.createFinding(severity, name, name); + } + + /** + * Creates a finding with static name / description. If description depends on the value of the header's value + * please use {@link #createFinding(Severity, String, BiConsumer)} + * @param severity + * @param name + * @param description + * @return + */ + public HttpHeaderStrategy createFinding (Severity severity, String name, String description) { + this.severity = severity; + this.findingNameAndDescriptionGenerator = (value, callback) -> callback.accept(name, description); + return strategy; + } + + /** + * Similar to {@link #createFinding(Severity, String, String)}, but description is generated through the + * consumer function and can depend on the value of the header. + * @param severity severity of the finding + * @param name name of the finding + * @param consumer function(String headerValue, function(String findingDescription) -> void) -> void + * @return + */ + public HttpHeaderStrategy createFinding (Severity severity, String name, BiConsumer> consumer) { + this.severity = severity; + this.findingNameAndDescriptionGenerator = (value, generateFinding) -> { + consumer.accept(value, description -> { + generateFinding.accept(name, description); + }); + }; + return this.strategy; + } + + /** + * See {@link #createFinding(Severity, String, BiConsumer)} + * @param severity + * @param name + * @param consumer + * @return + */ + public HttpHeaderStrategy createFinding (Severity severity, String name, Function consumer) { + this.severity = severity; + this.findingNameAndDescriptionGenerator = (headerValue, generateFinding) -> { + generateFinding.accept(name, consumer.apply(headerValue)); + }; + return this.strategy; + } + + /** + * Similar to {@link #createFinding(Severity, String, BiConsumer)}, but the consumer generates both the name and + * the description for the finding. + * @param severity severity of the finding + * @param consumer function(String headerValue, function(String findingName, String findingDescription) -> void) -> void + * @return + */ + public HttpHeaderStrategy createFinding (Severity severity, BiConsumer> consumer) { + this.severity = severity; + this.findingNameAndDescriptionGenerator = consumer; + return strategy; + } + + public HttpHeaderStrategy modifyFinding (BiConsumer consumer) { + this.findingModifier = consumer; + return this.strategy; + } + + } + + + /** + * Creates a finding on OsiLayer.APPLICATION, copying most values (all attributes) from a given, existing finding + * @param copyDetails + * @param name + * @param severity + * @param description + * @return + */ + private Finding createApplicationLevelFinding (final Finding copyDetails, final String name, final Severity severity, final String description) { + final Finding fnd = createCopyOfFinding(copyDetails); + fnd.setName(name); + fnd.setCategory("Http Header"); + fnd.setOsiLayer(OsiLayer.APPLICATION); + fnd.setDescription(description); + fnd.setSeverity(severity); + return fnd; + } + + /** + * Creates a copy of a finding, omitting name, category, description, osi-layer and severity + * @param copyDetails + * @return + */ + private Finding createCopyOfFinding (final Finding copyDetails) { + final Finding fnd = new Finding(); + fnd.setId(UUID.randomUUID()); + fnd.setLocation(copyDetails.getLocation()); + fnd.setReference(copyDetails.getReference()); + copyDetails.getAttributes().keySet().forEach(key -> { + Object value = copyDetails.getAttributes().get(key); + if (value instanceof Serializable) { + fnd.addAttribute(key, (Serializable) value); + } + }); + return fnd; + } + +} diff --git a/scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/util/HttpHeaders.java b/scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/util/HttpHeaders.java new file mode 100644 index 00000000..656b6f69 --- /dev/null +++ b/scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/util/HttpHeaders.java @@ -0,0 +1,53 @@ +package io.securecodebox.scanprocess.nmap.util; + +import io.securecodebox.model.findings.Finding; + +import java.util.HashMap; +import java.util.Map; + +public final class HttpHeaders { + + private final HashMap headers = new HashMap<>(); + + public HttpHeaders(String rawHeaders) { + final String[] lines = rawHeaders.split ("\\r?\\n"); + for (int i = 0; i < lines.length; i++) { + final String line = lines[i]; + + // double-newline = end of http header section (ignore if first line; nmap bug) + if (line.length() == 0) { + if (i == 0) continue; + else break; + } + + int colonPos = line.indexOf(':'); + if (colonPos < 0) continue; + final String + k = line.substring(0, colonPos).trim(), + v = line.substring(colonPos + 1).trim(); + headers.put(k, v); + } + } + + public boolean has (String key) { + return headers.containsKey(key); + } + + public String get (String key) { + return headers.get(key); + } + + public static boolean headersPresentInFinding (Finding finding) { + Map attributes = finding.getAttributes(); + if (attributes == null) return false; + Object scripts = attributes.get("scripts"); + if (scripts == null || !(scripts instanceof Map)) return false; + return ((Map)scripts).containsKey("http-headers"); + } + + public static HttpHeaders fromFinding (Finding finding) { + if (!headersPresentInFinding(finding)) return null; + return new HttpHeaders(((Map)finding.getAttributes().get("scripts")).get("http-headers")); + } + +} diff --git a/scb-scanprocesses/nmap-process/src/main/resources/bpmn/nmap_process.bpmn b/scb-scanprocesses/nmap-process/src/main/resources/bpmn/nmap_process.bpmn index 306bd86c..ac0352b9 100644 --- a/scb-scanprocesses/nmap-process/src/main/resources/bpmn/nmap_process.bpmn +++ b/scb-scanprocesses/nmap-process/src/main/resources/bpmn/nmap_process.bpmn @@ -1,5 +1,5 @@ - + @@ -17,10 +17,11 @@ SequenceFlow_ManualStart SequenceFlow_DefaultConfig SequenceFlow_AdvancedConfig + SequenceFlow_HttpSecConfig - + ${NMAP_CONFIGURATION_TYPE == 'default'} SequenceFlow_ResultApproved @@ -33,7 +34,7 @@ SequenceFlow_PortscanConfigured - + ${NMAP_CONFIGURATION_TYPE == 'advanced'} @@ -50,10 +51,10 @@ SequenceFlow_ResultRejected - + ${PROCESS_RESULT_APPROVED == 'approved'} - + ${PROCESS_RESULT_APPROVED == 'disapproved'} SequenceFlow_TargetConfigured @@ -78,10 +79,13 @@ ${PROCESS_AUTOMATED == true} - + + + SequenceFlow_PortscanConfigured SequenceFlow_DefaultConfig SequenceFlow_AutomatedStart + SequenceFlow_HttpSecConfig SequenceFlow_PortscanFinished @@ -92,8 +96,12 @@ - results in a generic format - + + ${NMAP_CONFIGURATION_TYPE == 'http-security'} + + + results in a generic format + @@ -111,16 +119,16 @@ - - + + - - - + + + @@ -132,8 +140,8 @@ - - + + @@ -142,24 +150,24 @@ - - + + - - - - + + + + - - + + @@ -174,16 +182,16 @@ - - + + - - - + + + @@ -195,16 +203,16 @@ - - + + - - - + + + @@ -216,16 +224,16 @@ - - - + + + - - + + @@ -234,8 +242,8 @@ - - + + @@ -253,8 +261,18 @@ - - + + + + + + + + + + + + diff --git a/scb-scanprocesses/nmap-process/src/main/resources/forms/nmap/approve-port-scanner-results.html b/scb-scanprocesses/nmap-process/src/main/resources/forms/nmap/approve-port-scanner-results.html index 876044ee..88b7c9b1 100644 --- a/scb-scanprocesses/nmap-process/src/main/resources/forms/nmap/approve-port-scanner-results.html +++ b/scb-scanprocesses/nmap-process/src/main/resources/forms/nmap/approve-port-scanner-results.html @@ -91,7 +91,7 @@

{{ address }} ({{ port.attributes.ip_address }}) - {{ port.category === 'Open Port' ? port.attributes.port : '' }} + {{ (port.category === 'Open Port' || port.category === 'Http Header') ? port.attributes.port : '' }} {{ port.category === 'Open Port' ? port.attributes.service : port.name}} {{ port.category === 'Open Port' ? port.attributes.protocol : '' }} @@ -99,6 +99,10 @@

Open + + + {{ port.description.includes('missing') ? 'Missing' : 'Misconfigured' }} + diff --git a/scb-scanprocesses/nmap-process/src/test/java/io/securecodebox/scanprocess/nmap/util/HttpHeaderStrategyTest.java b/scb-scanprocesses/nmap-process/src/test/java/io/securecodebox/scanprocess/nmap/util/HttpHeaderStrategyTest.java new file mode 100644 index 00000000..0bb1e9ec --- /dev/null +++ b/scb-scanprocesses/nmap-process/src/test/java/io/securecodebox/scanprocess/nmap/util/HttpHeaderStrategyTest.java @@ -0,0 +1,79 @@ +package io.securecodebox.scanprocess.nmap.util; + +import io.securecodebox.model.findings.Finding; +import io.securecodebox.model.findings.OsiLayer; +import io.securecodebox.model.findings.Severity; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.UUID; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +public class HttpHeaderStrategyTest { + + private HttpHeaders headers; + private Finding finding; + + @Before + public void init () { + final StringBuilder rawHeaders = new StringBuilder(); + rawHeaders.append("Content-Type: text/imaginary\n"); + rawHeaders.append("Location: https://localhost:443/\n"); + rawHeaders.append("Done: yeah;\n\n"); + headers = new HttpHeaders(rawHeaders.toString()); + + finding = new Finding(); + finding.setName("DefaultName"); + finding.setId(UUID.randomUUID()); + finding.setDescription("DefaultDescription"); + finding.setOsiLayer(OsiLayer.NOT_APPLICABLE); + finding.setCategory("DefaultCategory"); + } + + @Test + public void testHttpHeaders () { + assertEquals(true, headers.has("Content-Type")); + assertEquals("text/imaginary", headers.get("Content-Type")); + assertEquals(true, headers.has("Location")); + assertEquals("https://localhost:443/", headers.get("Location")); + assertEquals(true, headers.has("Done")); + assertEquals("yeah;", headers.get("Done")); + assertEquals(false, headers.has("Nothing")); + assertNull(headers.get("Nothing")); + } + + @Test + public void testExistingHeader () { + HttpHeaderStrategy strategy = createStrategy("Location"); + ArrayList findings = strategy.apply(headers, finding); + + assertEquals(2, findings.size()); + assertEquals(findings.get(0).getName(), "Location header present"); + assertEquals(findings.get(1).getName(), "Does not start with 0"); + } + + @Test + public void testNonExistantHeader () { + HttpHeaderStrategy strategy = createStrategy("Nothing"); + ArrayList findings = strategy.apply(headers, finding); + + assertEquals(1, findings.size()); + assertEquals(findings.get(0).getName(), "Nothing header missing"); + } + + private HttpHeaderStrategy createStrategy(String headerName) { + return new HttpHeaderStrategy(headerName) + + .ifPresent () + .createFinding (Severity.MEDIUM, headerName + " header present") + + .ifMissingCreateFinding(Severity.MEDIUM) + + .ifTrue(value -> !value.startsWith ("0")) + .createFinding (Severity.MEDIUM, "Does not start with 0", value -> "Actual value: " + value); + } + +} \ No newline at end of file From 39da076551255c3035e59be9e6af9db360538528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6ran=20Tesse?= Date: Tue, 22 Jan 2019 12:23:43 +0100 Subject: [PATCH 2/6] wip: visualization of new findings changed --- .../main/resources/forms/amass-nmap/configure-target.html | 7 +++++++ .../nmap/delegate/FilterHttpSecurityHeaders.java | 2 +- .../scanprocess/nmap/util/HttpHeaderStrategy.java | 1 + .../forms/nmap/approve-port-scanner-results.html | 8 ++++---- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/scb-scanprocesses/combined-amass-nmap-process/src/main/resources/forms/amass-nmap/configure-target.html b/scb-scanprocesses/combined-amass-nmap-process/src/main/resources/forms/amass-nmap/configure-target.html index 65f20baf..8e87ebb4 100644 --- a/scb-scanprocesses/combined-amass-nmap-process/src/main/resources/forms/amass-nmap/configure-target.html +++ b/scb-scanprocesses/combined-amass-nmap-process/src/main/resources/forms/amass-nmap/configure-target.html @@ -83,6 +83,13 @@

Please configure the Combined Amass-Nmap Scan

+ +
+ + + diff --git a/scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/delegate/FilterHttpSecurityHeaders.java b/scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/delegate/FilterHttpSecurityHeaders.java index b23637c4..de521a35 100644 --- a/scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/delegate/FilterHttpSecurityHeaders.java +++ b/scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/delegate/FilterHttpSecurityHeaders.java @@ -55,7 +55,7 @@ public void execute(DelegateExecution delegateExecution) throws Exception { final int numberOfAdditionalFindings = findings.size() - process.getFindings().size(); clearFindings(process); findings.forEach(changedFinding -> process.appendFinding(changedFinding)); - LOG.info("http-headers strategies yielded {} additional findings; finding them took {}ms, storing them {}ms", numberOfAdditionalFindings, T_STRATEGIES_APPLIED - T_START, System.currentTimeMillis() - T_STRATEGIES_APPLIED); + LOG.debug("http-headers strategies yielded {} additional findings; finding them took {}ms, storing them {}ms", numberOfAdditionalFindings, T_STRATEGIES_APPLIED - T_START, System.currentTimeMillis() - T_STRATEGIES_APPLIED); } private ArrayList applyStrategies(HttpHeaders headers, Finding finding) { diff --git a/scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/util/HttpHeaderStrategy.java b/scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/util/HttpHeaderStrategy.java index 3d447cae..871a73b2 100644 --- a/scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/util/HttpHeaderStrategy.java +++ b/scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/util/HttpHeaderStrategy.java @@ -202,6 +202,7 @@ private Finding createApplicationLevelFinding (final Finding copyDetails, final fnd.setName(name); fnd.setCategory("Http Header"); fnd.setOsiLayer(OsiLayer.APPLICATION); + fnd.addAttribute("protocol", "http"); fnd.setDescription(description); fnd.setSeverity(severity); return fnd; diff --git a/scb-scanprocesses/nmap-process/src/main/resources/forms/nmap/approve-port-scanner-results.html b/scb-scanprocesses/nmap-process/src/main/resources/forms/nmap/approve-port-scanner-results.html index 88b7c9b1..f02437e0 100644 --- a/scb-scanprocesses/nmap-process/src/main/resources/forms/nmap/approve-port-scanner-results.html +++ b/scb-scanprocesses/nmap-process/src/main/resources/forms/nmap/approve-port-scanner-results.html @@ -92,14 +92,14 @@

{{ address }} ({{ port.attributes.ip_address }}) {{ (port.category === 'Open Port' || port.category === 'Http Header') ? port.attributes.port : '' }} - {{ port.category === 'Open Port' ? port.attributes.service : port.name}} - {{ port.category === 'Open Port' ? port.attributes.protocol : '' }} + {{ (port.category === 'Open Port' && !port.name) ? port.attributes.service : port.name}} + {{ (port.category === 'Open Port' || port.category === 'Http Header') ? port.attributes.protocol : '' }} - + Open - + {{ port.description.includes('missing') ? 'Missing' : 'Misconfigured' }} From fe924e35f4ae081e4ea2ec9e440a534eaa6aa0ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6ran=20Tesse?= Date: Tue, 22 Jan 2019 12:47:00 +0100 Subject: [PATCH 3/6] wip: add configuration for combined process --- .../amassnmap/AdditionalTargetAttributes.java | 3 ++- .../amassnmap/NmapConfigProfile.java | 3 ++- .../TransformAmassResultsToNmapInput.java | 17 +++++++++++------ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/AdditionalTargetAttributes.java b/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/AdditionalTargetAttributes.java index f85924d2..3eb0c858 100644 --- a/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/AdditionalTargetAttributes.java +++ b/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/AdditionalTargetAttributes.java @@ -20,5 +20,6 @@ package io.securecodebox.scanprocesses.amassnmap; public enum AdditionalTargetAttributes { - NMAP_CONFIGURATION_PROFILE + NMAP_CONFIGURATION_PROFILE, + NMAP_HTTP_HEADERS } diff --git a/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/NmapConfigProfile.java b/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/NmapConfigProfile.java index e059c561..c6329fe2 100644 --- a/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/NmapConfigProfile.java +++ b/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/NmapConfigProfile.java @@ -21,7 +21,8 @@ public enum NmapConfigProfile { HTTP_PORTS("-Pn -p 80,8080,443,8443"), - TOP_100_PORTS("-Pn --top-ports 100"); + TOP_100_PORTS("-Pn --top-ports 100"), + WITH_HTTP_HEADERS("--script=http-headers"); private final String parameter; diff --git a/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/TransformAmassResultsToNmapInput.java b/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/TransformAmassResultsToNmapInput.java index 3c0a4053..f7254ef5 100644 --- a/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/TransformAmassResultsToNmapInput.java +++ b/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/TransformAmassResultsToNmapInput.java @@ -55,7 +55,10 @@ public void execute(DelegateExecution execution) throws Exception { objectMapper.getTypeFactory().constructCollectionType(List.class, Target.class)); String nmapProfile = (String) targets.get(0).getAttributes().get(AdditionalTargetAttributes.NMAP_CONFIGURATION_PROFILE.name()); - String nmapParameters = getNmapParameters(nmapProfile); + Boolean nmapHttpHeaders = (Boolean) targets.get(0).getAttributes().get(AdditionalTargetAttributes.NMAP_HTTP_HEADERS.name()); + if (nmapHttpHeaders == null) nmapHttpHeaders = false; + String nmapParameters = getNmapParameters(nmapProfile, nmapHttpHeaders); + List newTargets = new ArrayList<>(); for (Finding finding : findings) { @@ -80,21 +83,23 @@ public void execute(DelegateExecution execution) throws Exception { } } - private String getNmapParameters(String nmapProfile) { + private String getNmapParameters(String nmapProfile, boolean withHttpHeaders) { + final String scriptModules = withHttpHeaders ? " " + NmapConfigProfile.WITH_HTTP_HEADERS : ""; String defaultNmapParameters = NmapConfigProfile.HTTP_PORTS.getParameter(); + if(nmapProfile == null) { LOG.info("No nmap profile set for combined amass-nmap test. Use http ports as default"); - return defaultNmapParameters; + return defaultNmapParameters + scriptModules; } switch (NmapConfigProfile.valueOf(nmapProfile)) { case HTTP_PORTS: - return NmapConfigProfile.HTTP_PORTS.getParameter(); + return NmapConfigProfile.HTTP_PORTS.getParameter() + scriptModules; case TOP_100_PORTS: - return NmapConfigProfile.TOP_100_PORTS.getParameter(); + return NmapConfigProfile.TOP_100_PORTS.getParameter() + scriptModules; default: LOG.info("Invalid nmap profile set for combined amass-nmap test. Use http ports as default"); - return defaultNmapParameters; + return defaultNmapParameters + scriptModules; } } From bc9b241f5fce4034c0c8eedf84275ff6ef96da31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6ran=20Tesse?= Date: Tue, 22 Jan 2019 13:48:32 +0100 Subject: [PATCH 4/6] moved classes to combined nmap/amass scan --- .../amassnmap}/FilterHttpSecurityHeaders.java | 7 +- .../TransformAmassResultsToNmapInput.java | 3 +- .../amassnmap}/util/HttpHeaderStrategy.java | 4 +- .../amassnmap}/util/HttpHeaders.java | 2 +- .../bpmn/combined_amass_nmap_process.bpmn | 155 ++++++++++++------ .../forms/amass-nmap/approve-results.html | 12 +- .../util/HttpHeaderStrategyTest.java | 17 +- 7 files changed, 130 insertions(+), 70 deletions(-) rename scb-scanprocesses/{nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/delegate => combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap}/FilterHttpSecurityHeaders.java (96%) rename scb-scanprocesses/{nmap-process/src/main/java/io/securecodebox/scanprocess/nmap => combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap}/util/HttpHeaderStrategy.java (98%) rename scb-scanprocesses/{nmap-process/src/main/java/io/securecodebox/scanprocess/nmap => combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap}/util/HttpHeaders.java (96%) rename scb-scanprocesses/{nmap-process/src/test/java/io/securecodebox/scanprocess/nmap => combined-amass-nmap-process/src/test/java/io/securecodebox/scanprocesses/amassnmap}/util/HttpHeaderStrategyTest.java (85%) diff --git a/scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/delegate/FilterHttpSecurityHeaders.java b/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/FilterHttpSecurityHeaders.java similarity index 96% rename from scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/delegate/FilterHttpSecurityHeaders.java rename to scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/FilterHttpSecurityHeaders.java index de521a35..f61f701f 100644 --- a/scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/delegate/FilterHttpSecurityHeaders.java +++ b/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/FilterHttpSecurityHeaders.java @@ -1,11 +1,11 @@ -package io.securecodebox.scanprocess.nmap.delegate; +package io.securecodebox.scanprocesses.amassnmap; import io.securecodebox.model.execution.ScanProcessExecution; import io.securecodebox.model.execution.ScanProcessExecutionFactory; import io.securecodebox.model.findings.Finding; import io.securecodebox.model.findings.Severity; -import io.securecodebox.scanprocess.nmap.util.HttpHeaderStrategy; -import io.securecodebox.scanprocess.nmap.util.HttpHeaders; +import io.securecodebox.scanprocesses.amassnmap.util.HttpHeaderStrategy; +import io.securecodebox.scanprocesses.amassnmap.util.HttpHeaders; import org.camunda.bpm.engine.delegate.DelegateExecution; import org.camunda.bpm.engine.delegate.JavaDelegate; import org.slf4j.Logger; @@ -14,7 +14,6 @@ import org.springframework.stereotype.Component; import java.util.ArrayList; -import java.util.Map; @Component diff --git a/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/TransformAmassResultsToNmapInput.java b/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/TransformAmassResultsToNmapInput.java index f7d52c10..1d1441d0 100644 --- a/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/TransformAmassResultsToNmapInput.java +++ b/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/TransformAmassResultsToNmapInput.java @@ -84,6 +84,7 @@ public void execute(DelegateExecution execution) throws Exception { execution.setVariable(DefaultFields.PROCESS_TARGETS.name(), objectValue); execution.setVariable("NMAP_CONFIGURATION_TYPE","default"); + execution.setVariable("PARSE_HTTP_HEADERS", nmapHttpHeaders); LOG.debug("Finished TransformAmassResultsToNmapInput Service Task. Continue with nmap scan"); @@ -93,7 +94,7 @@ public void execute(DelegateExecution execution) throws Exception { } private String getNmapParameters(String nmapProfile, boolean withHttpHeaders) { - final String scriptModules = withHttpHeaders ? " " + NmapConfigProfile.WITH_HTTP_HEADERS : ""; + final String scriptModules = withHttpHeaders ? " " + NmapConfigProfile.WITH_HTTP_HEADERS.getParameter() : ""; String defaultNmapParameters = NmapConfigProfile.HTTP_PORTS.getParameter(); if(nmapProfile == null) { diff --git a/scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/util/HttpHeaderStrategy.java b/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/util/HttpHeaderStrategy.java similarity index 98% rename from scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/util/HttpHeaderStrategy.java rename to scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/util/HttpHeaderStrategy.java index 871a73b2..c7834ef9 100644 --- a/scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/util/HttpHeaderStrategy.java +++ b/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/util/HttpHeaderStrategy.java @@ -1,9 +1,8 @@ -package io.securecodebox.scanprocess.nmap.util; +package io.securecodebox.scanprocesses.amassnmap.util; import io.securecodebox.model.findings.Finding; import io.securecodebox.model.findings.OsiLayer; import io.securecodebox.model.findings.Severity; -import io.securecodebox.scanprocess.nmap.delegate.FilterHttpSecurityHeaders; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -11,7 +10,6 @@ import java.util.ArrayList; import java.util.UUID; import java.util.function.BiConsumer; -import java.util.function.BiPredicate; import java.util.function.Consumer; import java.util.function.Function; diff --git a/scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/util/HttpHeaders.java b/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/util/HttpHeaders.java similarity index 96% rename from scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/util/HttpHeaders.java rename to scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/util/HttpHeaders.java index 656b6f69..96263a1b 100644 --- a/scb-scanprocesses/nmap-process/src/main/java/io/securecodebox/scanprocess/nmap/util/HttpHeaders.java +++ b/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/util/HttpHeaders.java @@ -1,4 +1,4 @@ -package io.securecodebox.scanprocess.nmap.util; +package io.securecodebox.scanprocesses.amassnmap.util; import io.securecodebox.model.findings.Finding; diff --git a/scb-scanprocesses/combined-amass-nmap-process/src/main/resources/bpmn/combined_amass_nmap_process.bpmn b/scb-scanprocesses/combined-amass-nmap-process/src/main/resources/bpmn/combined_amass_nmap_process.bpmn index 8592a4b4..471d5169 100644 --- a/scb-scanprocesses/combined-amass-nmap-process/src/main/resources/bpmn/combined_amass_nmap_process.bpmn +++ b/scb-scanprocesses/combined-amass-nmap-process/src/main/resources/bpmn/combined_amass_nmap_process.bpmn @@ -1,5 +1,5 @@ - + @@ -29,7 +29,7 @@ SequenceFlow_0p5mwz6 - SequenceFlow_0x38sun + SequenceFlow_133ju0r SequenceFlow_0mvz7h9 @@ -47,7 +47,6 @@ SequenceFlow_1r4mrzm SequenceFlow_0y61th0 - ${PROCESS_AUTOMATED == false} @@ -70,17 +69,35 @@ SequenceFlow_0mvz7h9 - ${PROCESS_RESULT_APPROVED == 'approved'} + - ${PROCESS_RESULT_APPROVED != 'approved'} + - SequenceFlow_0x38sun + SequenceFlow_0v9j7z6 + SequenceFlow_020pm77 SequenceFlow_0k50e6l + + SequenceFlow_0gqomie + SequenceFlow_0v9j7z6 + + + + SequenceFlow_133ju0r + SequenceFlow_0gqomie + SequenceFlow_020pm77 + + + + ${PARSE_HTTP_HEADERS == true} + + + ${PARSE_HTTP_HEADERS == false} + @@ -91,15 +108,15 @@ - - + + - - + + @@ -108,42 +125,41 @@ - - + + - + - + - + - + - + - - - - - - - + + + - + - - + + + + + @@ -152,52 +168,97 @@ - + - + - + - - + + - + - + - + - - + + - + - - - + + + - + - - + + + + + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scb-scanprocesses/combined-amass-nmap-process/src/main/resources/forms/amass-nmap/approve-results.html b/scb-scanprocesses/combined-amass-nmap-process/src/main/resources/forms/amass-nmap/approve-results.html index 1e027a0a..fa94e1e7 100644 --- a/scb-scanprocesses/combined-amass-nmap-process/src/main/resources/forms/amass-nmap/approve-results.html +++ b/scb-scanprocesses/combined-amass-nmap-process/src/main/resources/forms/amass-nmap/approve-results.html @@ -74,14 +74,18 @@

{{ address }} ({{ port.attributes.ip_address }}) - {{ port.category === 'Open Port' ? port.attributes.port : '' }} - {{ port.category === 'Open Port' ? port.attributes.service : port.name}} - {{ port.category === 'Open Port' ? port.attributes.protocol : '' }} + {{ (port.category === 'Open Port' || port.category === 'Http Header') ? port.attributes.port : '' }} + {{ (port.category === 'Open Port' && !port.name) ? port.attributes.service : port.name}} + {{ (port.category === 'Open Port' || port.category === 'Http Header') ? port.attributes.protocol : '' }} - + Open + + + {{ port.description.includes('missing') ? 'Missing' : 'Misconfigured' }} + diff --git a/scb-scanprocesses/nmap-process/src/test/java/io/securecodebox/scanprocess/nmap/util/HttpHeaderStrategyTest.java b/scb-scanprocesses/combined-amass-nmap-process/src/test/java/io/securecodebox/scanprocesses/amassnmap/util/HttpHeaderStrategyTest.java similarity index 85% rename from scb-scanprocesses/nmap-process/src/test/java/io/securecodebox/scanprocess/nmap/util/HttpHeaderStrategyTest.java rename to scb-scanprocesses/combined-amass-nmap-process/src/test/java/io/securecodebox/scanprocesses/amassnmap/util/HttpHeaderStrategyTest.java index 0bb1e9ec..98307d92 100644 --- a/scb-scanprocesses/nmap-process/src/test/java/io/securecodebox/scanprocess/nmap/util/HttpHeaderStrategyTest.java +++ b/scb-scanprocesses/combined-amass-nmap-process/src/test/java/io/securecodebox/scanprocesses/amassnmap/util/HttpHeaderStrategyTest.java @@ -1,4 +1,4 @@ -package io.securecodebox.scanprocess.nmap.util; +package io.securecodebox.scanprocesses.amassnmap.util; import io.securecodebox.model.findings.Finding; import io.securecodebox.model.findings.OsiLayer; @@ -8,12 +8,10 @@ import java.util.ArrayList; import java.util.UUID; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -public class HttpHeaderStrategyTest { +import static org.junit.Assert.*; +public class HttpHeaderStrategyTest { private HttpHeaders headers; private Finding finding; @@ -35,13 +33,13 @@ public void init () { @Test public void testHttpHeaders () { - assertEquals(true, headers.has("Content-Type")); + assertTrue(headers.has("Content-Type")); assertEquals("text/imaginary", headers.get("Content-Type")); - assertEquals(true, headers.has("Location")); + assertTrue(headers.has("Location")); assertEquals("https://localhost:443/", headers.get("Location")); - assertEquals(true, headers.has("Done")); + assertTrue(headers.has("Done")); assertEquals("yeah;", headers.get("Done")); - assertEquals(false, headers.has("Nothing")); + assertFalse(headers.has("Nothing")); assertNull(headers.get("Nothing")); } @@ -75,5 +73,4 @@ private HttpHeaderStrategy createStrategy(String headerName) { .ifTrue(value -> !value.startsWith ("0")) .createFinding (Severity.MEDIUM, "Does not start with 0", value -> "Actual value: " + value); } - } \ No newline at end of file From 7c65c00501f1d4cd29d794154cdc2476a9585234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6ran=20Tesse?= Date: Fri, 25 Jan 2019 13:53:52 +0100 Subject: [PATCH 5/6] fixed bug where findings without script output would be removed --- .../amassnmap/FilterHttpSecurityHeaders.java | 9 +- .../src/main/resources/bpmn/nmap_process.bpmn | 93 ++++++++----------- 2 files changed, 45 insertions(+), 57 deletions(-) diff --git a/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/FilterHttpSecurityHeaders.java b/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/FilterHttpSecurityHeaders.java index f61f701f..8bef4c73 100644 --- a/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/FilterHttpSecurityHeaders.java +++ b/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/FilterHttpSecurityHeaders.java @@ -45,10 +45,13 @@ public void execute(DelegateExecution delegateExecution) throws Exception { final ArrayList findings = new ArrayList<>(); final long T_START = System.currentTimeMillis(); process.getFindings().stream() - .filter(finding -> HttpHeaders.headersPresentInFinding(finding)) .forEach(finding -> { - final HttpHeaders headers = HttpHeaders.fromFinding(finding); - findings.addAll(applyStrategies (headers, finding)); + if (HttpHeaders.headersPresentInFinding(finding)) { + final HttpHeaders headers = HttpHeaders.fromFinding(finding); + findings.addAll(applyStrategies (headers, finding)); + } else { + findings.add(finding); + } }); final long T_STRATEGIES_APPLIED = System.currentTimeMillis(); final int numberOfAdditionalFindings = findings.size() - process.getFindings().size(); diff --git a/scb-scanprocesses/nmap-process/src/main/resources/bpmn/nmap_process.bpmn b/scb-scanprocesses/nmap-process/src/main/resources/bpmn/nmap_process.bpmn index ac0352b9..53d5239f 100644 --- a/scb-scanprocesses/nmap-process/src/main/resources/bpmn/nmap_process.bpmn +++ b/scb-scanprocesses/nmap-process/src/main/resources/bpmn/nmap_process.bpmn @@ -1,5 +1,5 @@ - + @@ -17,11 +17,10 @@ SequenceFlow_ManualStart SequenceFlow_DefaultConfig SequenceFlow_AdvancedConfig - SequenceFlow_HttpSecConfig - ${NMAP_CONFIGURATION_TYPE == 'default'} + SequenceFlow_ResultApproved @@ -34,7 +33,7 @@ SequenceFlow_PortscanConfigured - ${NMAP_CONFIGURATION_TYPE == 'advanced'} + @@ -51,10 +50,10 @@ SequenceFlow_ResultRejected - ${PROCESS_RESULT_APPROVED == 'approved'} + - ${PROCESS_RESULT_APPROVED == 'disapproved'} + SequenceFlow_TargetConfigured @@ -85,7 +84,6 @@ SequenceFlow_PortscanConfigured SequenceFlow_DefaultConfig SequenceFlow_AutomatedStart - SequenceFlow_HttpSecConfig SequenceFlow_PortscanFinished @@ -96,9 +94,6 @@ - - ${NMAP_CONFIGURATION_TYPE == 'http-security'} - results in a generic format @@ -119,16 +114,16 @@ - - + + - - - + + + @@ -140,8 +135,8 @@ - - + + @@ -150,24 +145,24 @@ - - + + - - - - + + + + - - + + @@ -182,16 +177,16 @@ - - + + - - - + + + @@ -203,16 +198,16 @@ - - + + - - - + + + @@ -224,16 +219,16 @@ - - - + + + - - + + @@ -242,8 +237,8 @@ - - + + @@ -261,18 +256,8 @@ - - - - - - - - - - - - + + From ed9a988a11d53fe31b0300a2afe47de97527d8f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6ran=20Tesse?= Date: Fri, 25 Jan 2019 16:12:08 +0100 Subject: [PATCH 6/6] refactoring and bugfix --- .../amassnmap/FilterHttpSecurityHeaders.java | 14 ++++----- .../amassnmap/NmapConfigProfile.java | 4 +-- .../TransformAmassResultsToNmapInput.java | 19 ++++++++---- .../bpmn/combined_amass_nmap_process.bpmn | 31 ++++++++++--------- .../CombinedAmassNmapProcessTest.java | 1 + 5 files changed, 40 insertions(+), 29 deletions(-) diff --git a/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/FilterHttpSecurityHeaders.java b/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/FilterHttpSecurityHeaders.java index 8bef4c73..a2735031 100644 --- a/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/FilterHttpSecurityHeaders.java +++ b/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/FilterHttpSecurityHeaders.java @@ -43,7 +43,7 @@ public class FilterHttpSecurityHeaders implements JavaDelegate { public void execute(DelegateExecution delegateExecution) throws Exception { final ScanProcessExecution process = processExecutionFactory.get(delegateExecution); final ArrayList findings = new ArrayList<>(); - final long T_START = System.currentTimeMillis(); + final long tStart = System.currentTimeMillis(); process.getFindings().stream() .forEach(finding -> { if (HttpHeaders.headersPresentInFinding(finding)) { @@ -53,11 +53,11 @@ public void execute(DelegateExecution delegateExecution) throws Exception { findings.add(finding); } }); - final long T_STRATEGIES_APPLIED = System.currentTimeMillis(); + final long tStrategiesApplied = System.currentTimeMillis(); final int numberOfAdditionalFindings = findings.size() - process.getFindings().size(); clearFindings(process); findings.forEach(changedFinding -> process.appendFinding(changedFinding)); - LOG.debug("http-headers strategies yielded {} additional findings; finding them took {}ms, storing them {}ms", numberOfAdditionalFindings, T_STRATEGIES_APPLIED - T_START, System.currentTimeMillis() - T_STRATEGIES_APPLIED); + LOG.debug("http-headers strategies yielded {} additional findings; finding them took {}ms, storing them {}ms", numberOfAdditionalFindings, tStrategiesApplied - tStart, System.currentTimeMillis() - tStrategiesApplied); } private ArrayList applyStrategies(HttpHeaders headers, Finding finding) { @@ -118,17 +118,17 @@ private static HttpHeaderStrategy requireFrameOptionsToBeDenied() { private static HttpHeaderStrategy requireXssProtectionToBeEnabled() { return new HttpHeaderStrategy("X-XSS-Protection") .ifMissing() - .createFinding(Severity.MEDIUM, "X-XSS-Protection header missing") + .createFinding(Severity.LOW, "X-XSS-Protection header missing") .ifTrue(value -> value.startsWith("0")) - .createFinding(Severity.MEDIUM, "X-XSS-Protection manually disabled"); + .createFinding(Severity.LOW, "X-XSS-Protection manually disabled"); } private static HttpHeaderStrategy requireContentTypeOptionsToEqualNosniff() { return new HttpHeaderStrategy("X-Content-Type-Options") .ifMissing() - .createFinding(Severity.MEDIUM, "X-Content-Type-Options header missing") + .createFinding(Severity.LOW, "X-Content-Type-Options header missing") .ifTrue(value -> !value.equalsIgnoreCase("nosniff")) - .createFinding(Severity.MEDIUM, "X-Content-Type-Options misconfigured", value -> "X-Conntent-Type-Options should be set to 'nosniff' instead of '" + value + "'"); + .createFinding(Severity.LOW, "X-Content-Type-Options misconfigured", value -> "X-Conntent-Type-Options should be set to 'nosniff' instead of '" + value + "'"); } diff --git a/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/NmapConfigProfile.java b/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/NmapConfigProfile.java index c6329fe2..b3d5a9cf 100644 --- a/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/NmapConfigProfile.java +++ b/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/NmapConfigProfile.java @@ -21,9 +21,9 @@ public enum NmapConfigProfile { HTTP_PORTS("-Pn -p 80,8080,443,8443"), + HTTP_PORTS_WITH_HTTP_HEADERS("-Pn -p 80,8080,443,8443 --script=http-headers"), TOP_100_PORTS("-Pn --top-ports 100"), - WITH_HTTP_HEADERS("--script=http-headers"); - + TOP_100_PORTS_WITH_HTTP_HEADERS("-Pn --top-ports 100 --script=http-headers"); private final String parameter; NmapConfigProfile(final String parameter) { diff --git a/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/TransformAmassResultsToNmapInput.java b/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/TransformAmassResultsToNmapInput.java index 1d1441d0..c6f94520 100644 --- a/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/TransformAmassResultsToNmapInput.java +++ b/scb-scanprocesses/combined-amass-nmap-process/src/main/java/io/securecodebox/scanprocesses/amassnmap/TransformAmassResultsToNmapInput.java @@ -94,22 +94,29 @@ public void execute(DelegateExecution execution) throws Exception { } private String getNmapParameters(String nmapProfile, boolean withHttpHeaders) { - final String scriptModules = withHttpHeaders ? " " + NmapConfigProfile.WITH_HTTP_HEADERS.getParameter() : ""; - String defaultNmapParameters = NmapConfigProfile.HTTP_PORTS.getParameter(); + String defaultNmapParameters = (withHttpHeaders ? NmapConfigProfile.HTTP_PORTS_WITH_HTTP_HEADERS : NmapConfigProfile.HTTP_PORTS).getParameter(); if(nmapProfile == null) { LOG.info("No nmap profile set for combined amass-nmap test. Use http ports as default"); - return defaultNmapParameters + scriptModules; + return defaultNmapParameters; } switch (NmapConfigProfile.valueOf(nmapProfile)) { case HTTP_PORTS: - return NmapConfigProfile.HTTP_PORTS.getParameter() + scriptModules; + if (withHttpHeaders) { + return NmapConfigProfile.HTTP_PORTS_WITH_HTTP_HEADERS.getParameter(); + } else { + return NmapConfigProfile.HTTP_PORTS.getParameter(); + } case TOP_100_PORTS: - return NmapConfigProfile.TOP_100_PORTS.getParameter() + scriptModules; + if (withHttpHeaders) { + return NmapConfigProfile.TOP_100_PORTS_WITH_HTTP_HEADERS.getParameter(); + } else { + return NmapConfigProfile.TOP_100_PORTS.getParameter(); + } default: LOG.info("Invalid nmap profile set for combined amass-nmap test. Use http ports as default"); - return defaultNmapParameters + scriptModules; + return defaultNmapParameters; } } diff --git a/scb-scanprocesses/combined-amass-nmap-process/src/main/resources/bpmn/combined_amass_nmap_process.bpmn b/scb-scanprocesses/combined-amass-nmap-process/src/main/resources/bpmn/combined_amass_nmap_process.bpmn index 471d5169..cdc8693f 100644 --- a/scb-scanprocesses/combined-amass-nmap-process/src/main/resources/bpmn/combined_amass_nmap_process.bpmn +++ b/scb-scanprocesses/combined-amass-nmap-process/src/main/resources/bpmn/combined_amass_nmap_process.bpmn @@ -88,16 +88,16 @@ SequenceFlow_133ju0r - SequenceFlow_0gqomie SequenceFlow_020pm77 + SequenceFlow_0gqomie - - - ${PARSE_HTTP_HEADERS == true} - ${PARSE_HTTP_HEADERS == false} + + ${PARSE_HTTP_HEADERS == true} + + @@ -117,6 +117,9 @@ + + + @@ -229,7 +232,7 @@ - + @@ -238,11 +241,11 @@ - - - + + + - + @@ -253,11 +256,11 @@ - - - + + + - + diff --git a/scb-scanprocesses/combined-amass-nmap-process/src/test/java/io/securecodebox/scanprocess/amassnmap/CombinedAmassNmapProcessTest.java b/scb-scanprocesses/combined-amass-nmap-process/src/test/java/io/securecodebox/scanprocess/amassnmap/CombinedAmassNmapProcessTest.java index 75de7d34..540e7d45 100644 --- a/scb-scanprocesses/combined-amass-nmap-process/src/test/java/io/securecodebox/scanprocess/amassnmap/CombinedAmassNmapProcessTest.java +++ b/scb-scanprocesses/combined-amass-nmap-process/src/test/java/io/securecodebox/scanprocess/amassnmap/CombinedAmassNmapProcessTest.java @@ -109,6 +109,7 @@ public void init() { //Creating a map of default variables for the process defaultVariables.put(DefaultFields.PROCESS_AUTOMATED.name(), true); defaultVariables.put(DefaultFields.PROCESS_CONTEXT.name(), "BodgeIT"); + defaultVariables.put("PARSE_HTTP_HEADERS", false); /* Mocking everything in the BPMN Model