diff --git a/.github/actions/unit-test/action.yml b/.github/actions/unit-test/action.yml index 06ab3371d..b22a07f5a 100644 --- a/.github/actions/unit-test/action.yml +++ b/.github/actions/unit-test/action.yml @@ -5,6 +5,8 @@ inputs: description: 'The JVM Version to use' required: true default: '8' + codecov-token: + description: 'The CODECOV TOKEN' runs: using: composite @@ -42,4 +44,34 @@ runs: if: steps.run_tests_3.outcome == 'failure' run: | echo "Running attempt 4" - ./gradlew ${GRADLE_OPTIONS} --info test -Ptest${{ inputs.java-version }} --continue \ No newline at end of file + ./gradlew ${GRADLE_OPTIONS} --info test -Ptest${{ inputs.java-version }} --continue + + - name: Upload coverage to Codecov + if: matrix.java-version == '8' + uses: codecov/codecov-action@v3 + with: + token: ${{ inputs.codecov-token }} + files: '**/build/reports/jacoco/test/jacocoTestReport.xml' + fail_ci_if_error: false #default is false, but being explicit about what to expect. + verbose: true + + - name: Capture Jacoco reports + if: success() + uses: actions/upload-artifact@v4 + with: + name: jacoco-reports-java-${{ matrix.java-version }} + path: | + **/build/reports/jacoco/** + + - name: Capture build reports + # If previous step fails, run this step regardless + if: ${{ failure() }} + uses: actions/upload-artifact@v4 + with: + name: unit-tests-results-java-${{ matrix.java-version }} + # The regex for the path below will capture unit test HTML reports generated by gradle for all + # related modules: (newrelic-security-agent, newrelic-security-api, etc). + # However, it's critical that the previous build step does a ./gradlew clean or the regex will capture test reports + # that were leftover in unrelated modules for the instrumentation tests. + path: | + **/build/reports/tests/* \ No newline at end of file diff --git a/.github/codecov.yml b/.github/codecov.yml new file mode 100644 index 000000000..933935474 --- /dev/null +++ b/.github/codecov.yml @@ -0,0 +1,2 @@ +codecov: + max_report_age: off \ No newline at end of file diff --git a/.github/workflows/X-Reusable-Build-Security-Agent.yml b/.github/workflows/X-Reusable-Build-Security-Agent.yml index 516344f99..430e9fc5a 100644 --- a/.github/workflows/X-Reusable-Build-Security-Agent.yml +++ b/.github/workflows/X-Reusable-Build-Security-Agent.yml @@ -86,4 +86,5 @@ jobs: if: ${{ inputs.run-unit-test == 'true' }} uses: ./.github/actions/unit-test with: - java-version: ${{ matrix.java-version }} \ No newline at end of file + java-version: ${{ matrix.java-version }} + codecov-token: ${{ secrets.CODECOV_TOKEN }} \ No newline at end of file diff --git a/README.md b/README.md index dc2647886..9e62013b8 100644 --- a/README.md +++ b/README.md @@ -175,6 +175,22 @@ To publish csec agent on maven local use below command : ```./gradlew clean publishToMavenLocal``` + +## Code Quality + +The agent utilizes [Jacoco](https://www.jacoco.org/jacoco/) to measure and improve code quality. We also use [Codecov](https://docs.codecov.com/docs/quick-start) to report +code coverage. Jacoco tool is configured through the gradle build system. Codecov is configured and uploaded through a GitHub Actions workflow. + +#### Jacoco + +The `jacocoTestReport` task depends on the unit `test` task. It uses data generated by the test task to create the coverage reports. `jacocoTestReport` task creates an html and xml file of the output. We store these files locally in the respective module's `build/reports/jacoco` folder. The html file can be opened normally in a browser. +Some subprojects have not been configured to run because the code is either too trivial to test or it is code that is only compile time dependency and not necessary to test due to the nature +of how the agent instruments customer code. + +#### Codecov + +We use a codecov github action to upload the jacoco coverage reports to [codecov.io](https://app.codecov.io/gh/newrelic/csec-java-agent). Additionally, codecov will comment on pull requests (PRs) with a quick overview of how PRs (and relevant commits) will affect the code coverage as compared to the `main` branch. + ## **Contributing Feedback** Any feedback provided to New Relic about the New Relic csec-java-agent, including feedback provided as source code, comments, or other copyrightable or patentable material, is provided to New Relic under the terms of the New Relic Software License version, 1.0. If you do not provide attribution information or a copy of the license with your feedback, you waive the performance of those requirements of the New Relic Software License with respect to New Relic. The license grant regarding any feedback is irrevocable. diff --git a/gradle/script/jacoco.gradle b/gradle/script/jacoco.gradle new file mode 100644 index 000000000..ae1cc458e --- /dev/null +++ b/gradle/script/jacoco.gradle @@ -0,0 +1,73 @@ +apply plugin: 'java' +apply plugin: 'jacoco' + +jacoco { + toolVersion = "0.8.11" +} + +test { + jacoco { + enabled = true + destinationFile = layout.buildDirectory.file('jacoco/test.exec').get().asFile + classDumpDir = layout.buildDirectory.dir('jacoco/classpathdumps').get().asFile + destinationFile = layout.buildDirectory.file("jacoco/${name}.exec").get().asFile + + } + finalizedBy jacocoTestReport // report is always generated after tests run +} + +jacocoTestReport { + + dependsOn test + afterEvaluate { + classDirectories.setFrom(files(classDirectories.files.collect { + fileTree(dir: it, + exclude: ['**/*NoOp*.class', + '**/SecurityAgent.class', + '**/*Exception.class', + '**/*Error.class', + '**/*Constant*.class', + '**/*Pool*.class', + 'com/newrelic/agent/security/intcodeagent/utils/TTLMap.class', + 'com/newrelic/agent/security/intcodeagent/utils/ResourceUtils.class', + 'com/newrelic/agent/security/intcodeagent/models/**', + 'com/newrelic/agent/security/util/*.class', + 'com/newrelic/agent/security/intcodeagent/properties/*.class', + 'com/newrelic/agent/security/intcodeagent/*logging/*', + 'com/newrelic/agent/security/intcodeagent/serializers/*', + 'com/newrelic/agent/security/intcodeagent/schedulers/*', + 'com/newrelic/agent/security/intcodeagent/controlcommand/*', + 'com/newrelic/agent/security/intcodeagent/websocket/*', + 'com/newrelic/agent/security/intcodeagent/executor/*', + 'com/newrelic/agent/security/intcodeagent/constants/*.class', + 'com/newrelic/agent/security/instrumentator/utils/AgentUtils.class', + 'com/newrelic/agent/security/instrumentator/utils/ApplicationInfoUtils.class', + 'com/newrelic/agent/security/instrumentator/utils/EnvLogUtils*.class', + 'com/newrelic/agent/security/instrumentator/utils/HashGenerator.class', + 'com/newrelic/agent/security/instrumentator/utils/InstrumentationUtils.class', + 'com/newrelic/agent/security/instrumentator/utils/INRSettingsKey.class', + 'com/newrelic/agent/security/instrumentator/utils/NameFileFilter.class', + 'com/newrelic/agent/security/instrumentator/os/*', + 'com/newrelic/agent/security/instrumentator/httpclient/*.class', + 'com/newrelic/agent/security/instrumentator/*Hooks.class', + 'com/newrelic/agent/security/intcodeagent/websocket/WSUtils.class', + 'com/newrelic/agent/security/intcodeagent/websocket/CustomTrustStoreManagerUtils.class', + 'com/newrelic/agent/security/intcodeagent/apache/httpclient/*', + 'com/newrelic/api/agent/security/*.class', + 'com/newrelic/agent/security/*.class', + 'com/newrelic/api/agent/security/schema/*', + 'com/newrelic/api/agent/security/NewRelicSecurity.class', + 'com/newrelic/api/agent/security/instrumentation/helpers/VertxApiEndpointUtils*', + 'com/newrelic/api/agent/security/utils/UserDataTranslationHelper.class', + 'com/newrelic/api/agent/security/utils/logging/LogLevel.class', + 'com/newrelic/api/agent/security/instrumentation/helpers/GrpcClientRequestReplayHelper*', + 'com/newrelic/api/agent/security/instrumentation/helpers/AppServerInfoHelper.class', + ]) + })) + } + reports { + xml.required = true + html.outputLocation = layout.buildDirectory.dir('reports/jacoco') + } + +} \ No newline at end of file diff --git a/newrelic-security-agent/build.gradle b/newrelic-security-agent/build.gradle index b3880c69b..4a9004875 100644 --- a/newrelic-security-agent/build.gradle +++ b/newrelic-security-agent/build.gradle @@ -14,6 +14,8 @@ plugins { id 'org.cyclonedx.bom' version '1.7.3' } +apply from: '../gradle/script/jacoco.gradle' + java.sourceCompatibility = JavaVersion.VERSION_1_8 repositories { @@ -79,6 +81,9 @@ dependencies { shadowIntoJar 'com.google.code.gson:gson:2.10.1' shadowIntoJar 'org.apache.httpcomponents:httpclient:4.5.14' implementation "com.newrelic.agent.java:newrelic-api:${nrAPIVersion}" + testImplementation('junit:junit:4.13.2') + testImplementation('org.mockito:mockito-inline:4.11.0') + testImplementation('software.amazon.awssdk:dynamodb:2.16.46') } /** @@ -253,6 +258,17 @@ jar { enabled = false } +test { + forkEvery = 1 + maxParallelForks = Runtime.runtime.availableProcessors() + useJUnit { + + } + + minHeapSize = "256m" + maxHeapSize = "768m" +} + artifacts { finalArtifact newrelicVersionedAgentJar archives newrelicVersionedAgentJar diff --git a/newrelic-security-agent/src/test/java/com/newrelic/agent/security/AgentConfigTest.java b/newrelic-security-agent/src/test/java/com/newrelic/agent/security/AgentConfigTest.java new file mode 100644 index 000000000..97514a960 --- /dev/null +++ b/newrelic-security-agent/src/test/java/com/newrelic/agent/security/AgentConfigTest.java @@ -0,0 +1,63 @@ +package com.newrelic.agent.security; + +import com.newrelic.agent.security.intcodeagent.exceptions.RestrictionModeException; +import com.newrelic.agent.security.util.IUtilConstants; +import com.newrelic.api.agent.NewRelic; +import org.apache.commons.io.FileUtils; +import org.junit.Assert; + +import org.junit.Test; +import org.mockito.Answers; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +import java.io.File; +import java.io.IOException; +import java.util.UUID; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; + +public class AgentConfigTest { + + @Test + public void applyRequiredGroup() throws RestrictionModeException { + AgentConfig.getInstance().instantiate(); + Assert.assertEquals("IAST", AgentConfig.getInstance().getGroupName()); + } + @Test + + public void applyRequiredGroup1() throws RestrictionModeException{ +// try (MockedStatic nrMock = Mockito.mockStatic(NewRelic.class, Answers.RETURNS_DEEP_STUBS)){ +// nrMock.when(NewRelic.getAgent().getConfig().getValue(IUtilConstants.SECURITY_MODE)).thenReturn("RASP"); +// nrMock.when(NewRelic.getAgent().getConfig().getValue(eq(IUtilConstants.NR_SECURITY_ENABLED), any())).thenReturn(false); +// AgentConfig.getInstance().instantiate(); +// Assert.assertEquals("RASP", AgentConfig.getInstance().getGroupName()); +// nrMock.reset(); +// nrMock.clearInvocations(); +// } + } + @Test + public void isNRSecurityEnabled() throws RestrictionModeException{ + AgentConfig.getInstance().instantiate(); + Assert.assertFalse(AgentConfig.getInstance().isNRSecurityEnabled()); + } + @Test + public void setK2HomePath() { + Assert.assertFalse(AgentConfig.getInstance().setSecurityHomePath()); + } + @Test + public void setK2HomePath1() throws IOException { + String AGENT_HOME = "/tmp/file_"+ UUID.randomUUID(); + try (MockedStatic nrMock = Mockito.mockStatic(NewRelic.class, Answers.RETURNS_DEEP_STUBS)){ + nrMock.when(NewRelic.getAgent().getConfig().getValue("agent_home")).thenReturn(AGENT_HOME); + + Assert.assertTrue(AgentConfig.getInstance().setSecurityHomePath()); + Assert.assertEquals(AGENT_HOME+"/nr-security-home", AgentConfig.getInstance().getSecurityHome()); + nrMock.reset(); + nrMock.clearInvocations(); + } finally { + FileUtils.forceDeleteOnExit(new File(AGENT_HOME)); + } + } +} diff --git a/newrelic-security-agent/src/test/java/com/newrelic/agent/security/AgentInfoTest.java b/newrelic-security-agent/src/test/java/com/newrelic/agent/security/AgentInfoTest.java new file mode 100644 index 000000000..5b70fd677 --- /dev/null +++ b/newrelic-security-agent/src/test/java/com/newrelic/agent/security/AgentInfoTest.java @@ -0,0 +1,105 @@ +package com.newrelic.agent.security; + +import com.newrelic.agent.security.instrumentator.utils.INRSettingsKey; +import com.newrelic.agent.security.intcodeagent.models.collectorconfig.CollectorConfig; +import com.newrelic.agent.security.intcodeagent.models.javaagent.ApplicationInfoBean; +import com.newrelic.agent.security.intcodeagent.models.javaagent.EventStats; +import com.newrelic.agent.security.intcodeagent.models.javaagent.Identifier; +import com.newrelic.agent.security.intcodeagent.models.javaagent.IdentifierEnvs; +import com.newrelic.agent.security.intcodeagent.models.javaagent.JAHealthCheck; +import com.newrelic.agent.security.util.IUtilConstants; +import com.newrelic.api.agent.NewRelic; +import org.junit.Assert; +import org.junit.BeforeClass; + +import org.junit.Test; +import org.mockito.Mockito; + +import java.util.Collections; +import java.util.Properties; +import java.util.concurrent.atomic.AtomicInteger; + +public class AgentInfoTest { + @BeforeClass + public static void setUp() { + Identifier identifier = new Identifier(); + identifier.setKind(IdentifierEnvs.HOST); + AgentInfo.getInstance().setIdentifier(identifier); + } + + @Test + + public void generateAppInfo() { +// ApplicationInfoBean appInfoBean = AgentInfo.getInstance().generateAppInfo(Mockito.mock(CollectorConfig.class)); +// Assert.assertEquals(AgentInfo.getInstance().getApplicationUUID(), appInfoBean.getApplicationUUID()); +// Assert.assertEquals("STATIC", appInfoBean.getAgentAttachmentType()); +// Assert.assertEquals(AgentInfo.getInstance().getVMPID(), appInfoBean.getPid()); +// Assert.assertEquals("JAVA", appInfoBean.getCollectorType()); +// Assert.assertEquals("Java", appInfoBean.getLanguage()); + } + + @Test + public void initializeHC() { +// AgentInfo.getInstance().generateAppInfo(Mockito.mock(CollectorConfig.class)); +// AgentInfo.getInstance().initialiseHC(); +// JAHealthCheck jaHealthCheck = AgentInfo.getInstance().getJaHealthCheck(); + Properties properties = new Properties(); + //default application_logging is true + properties.put("newrelic.config.application_logging.enabled", "false"); + System.setProperty("newrelic.config.security.scan_controllers.scan_instance_count", "1"); + System.out.println("config found ---" + NewRelic.getAgent().getConfig().getValue(IUtilConstants.IAST_SCAN_INSTANCE_COUNT)); +// assertion(jaHealthCheck, new AtomicInteger(0), new EventStats()); + } + + @Test + public void isAgentActive() { + Assert.assertFalse(AgentInfo.getInstance().isAgentActive()); + } +// @Test +// public void initializeHC1() { +// AgentInfo.getInstance().generateAppInfo(Mockito.mock(CollectorConfig.class)); +// AgentInfo.getInstance().initialiseHC(); +// JAHealthCheck jaHealthCheck = AgentInfo.getInstance().getJaHealthCheck(); +// jaHealthCheck.incrementInvokedHookCount(); +// jaHealthCheck.incrementDropCount(); +// jaHealthCheck.incrementProcessedCount(); +// jaHealthCheck.incrementEventSentCount(); +// jaHealthCheck.incrementHttpRequestCount(); +// jaHealthCheck.incrementExitEventSentCount(); +// jaHealthCheck.incrementEventRejectionCount(); +// jaHealthCheck.incrementEventProcessingErrorCount(); +// jaHealthCheck.incrementEventSendRejectionCount(); +// jaHealthCheck.incrementEventSendErrorCount(); +// assertion(jaHealthCheck, new AtomicInteger(1), new EventStats()); +// +// // resetting the JAHealthCheck +// jaHealthCheck.reset(); +// assertion(jaHealthCheck, new AtomicInteger(0), new EventStats()); +// } + +// private void assertion(JAHealthCheck jaHealthCheck, AtomicInteger atomicInteger, EventStats expectedEventStats) { +// Assert.assertEquals(AgentInfo.getInstance().getApplicationUUID(), jaHealthCheck.getApplicationUUID()); +// Assert.assertEquals(atomicInteger.get(), jaHealthCheck.getInvokedHookCount()); +// Assert.assertEquals(atomicInteger.get(), jaHealthCheck.getEventDropCount().intValue()); +// Assert.assertEquals(atomicInteger.get(), jaHealthCheck.getEventProcessed().intValue()); +// Assert.assertEquals(atomicInteger.get(), jaHealthCheck.getEventSentCount().get()); +// Assert.assertEquals(atomicInteger.get(), jaHealthCheck.getHttpRequestCount().get()); +// Assert.assertEquals(atomicInteger.get(), jaHealthCheck.getExitEventSentCount().get()); +// Assert.assertEquals(atomicInteger.get(), jaHealthCheck.getEventRejectionCount().get()); +// Assert.assertEquals(atomicInteger.get(), jaHealthCheck.getEventProcessingErrorCount().get()); +// Assert.assertEquals(atomicInteger.get(), jaHealthCheck.getEventSendRejectionCount().get()); +// Assert.assertEquals(atomicInteger.get(), jaHealthCheck.getEventSendErrorCount().get()); +// +// assertEventStats(expectedEventStats, jaHealthCheck.getExitEventStats()); +// assertEventStats(expectedEventStats, jaHealthCheck.getIastEventStats()); +// assertEventStats(expectedEventStats, jaHealthCheck.getRaspEventStats()); +// Assert.assertEquals("HOST", jaHealthCheck.getKind().name()); +// } + +// private void assertEventStats(EventStats expectedEventStats, EventStats actualEventStats) { +// Assert.assertSame(expectedEventStats.getErrorCount().get(), actualEventStats.getErrorCount().get()); +// Assert.assertSame(expectedEventStats.getProcessed().get(), actualEventStats.getProcessed().get()); +// Assert.assertSame(expectedEventStats.getSent().get(), actualEventStats.getSent().get()); +// Assert.assertSame(expectedEventStats.getRejected().get(), actualEventStats.getRejected().get()); +// } +} diff --git a/newrelic-security-agent/src/test/java/com/newrelic/agent/security/instrumentator/dispatcher/DispatcherTest.java b/newrelic-security-agent/src/test/java/com/newrelic/agent/security/instrumentator/dispatcher/DispatcherTest.java new file mode 100644 index 000000000..87f4ccc9f --- /dev/null +++ b/newrelic-security-agent/src/test/java/com/newrelic/agent/security/instrumentator/dispatcher/DispatcherTest.java @@ -0,0 +1,680 @@ +package com.newrelic.agent.security.instrumentator.dispatcher; + +import com.newrelic.agent.security.AgentConfig; +import com.newrelic.agent.security.AgentInfo; +import com.newrelic.agent.security.intcodeagent.exceptions.RestrictionModeException; +import com.newrelic.agent.security.intcodeagent.filelogging.FileLoggerThreadPool; +import com.newrelic.agent.security.intcodeagent.models.collectorconfig.CollectorConfig; +import com.newrelic.agent.security.intcodeagent.models.collectorconfig.CustomerInfo; +import com.newrelic.agent.security.intcodeagent.models.javaagent.ExitEventBean; +import com.newrelic.agent.security.intcodeagent.models.javaagent.Identifier; +import com.newrelic.agent.security.intcodeagent.models.javaagent.IdentifierEnvs; +import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; +import com.newrelic.api.agent.security.schema.AbstractOperation; +import com.newrelic.api.agent.security.schema.AgentMetaData; +import com.newrelic.api.agent.security.schema.HttpRequest; +import com.newrelic.api.agent.security.schema.HttpResponse; +import com.newrelic.api.agent.security.schema.K2RequestIdentifier; +import com.newrelic.api.agent.security.schema.SecurityMetaData; +import com.newrelic.api.agent.security.schema.UserClassEntity; +import com.newrelic.api.agent.security.schema.VulnerabilityCaseType; +import com.newrelic.api.agent.security.schema.operation.*; +import com.newrelic.api.agent.security.schema.policy.ScanSchedule; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.mockito.Mockito; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.HashMap; +import java.util.UUID; + +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.doReturn; + +public class DispatcherTest { + + @BeforeClass + public static void beforeClass() throws RestrictionModeException { + CollectorConfig collectorConfig = Mockito.mock(CollectorConfig.class); + Identifier identifier = new Identifier(); + identifier.setKind(IdentifierEnvs.HOST); + AgentInfo.getInstance().setIdentifier(identifier); + FileLoggerThreadPool.getInstance().initialiseLogger(); + AgentInfo.initialiseLogger(); + AgentConfig.getInstance().setConfig(new CollectorConfig()); + AgentConfig.getInstance().getConfig().setCustomerInfo(new CustomerInfo()); + AgentConfig.getInstance().getConfig().getCustomerInfo().setAccountId("1"); + + AgentConfig.getInstance().instantiate(); + AgentConfig.getInstance().getAgentMode().setScanSchedule(new ScanSchedule()); + + AgentInfo.getInstance().generateAppInfo(collectorConfig); + AgentInfo.getInstance().initialiseHC(); + } + + @Test + public void testProcessNullEventTest() throws Exception { + + Dispatcher dispatcher = new Dispatcher(null, Mockito.mock(SecurityMetaData.class)); + Assert.assertNull(dispatcher.call()); + } + + @Test + public void testProcessFileOpTest() throws Exception { + FileOperation fileOp = Mockito.mock(FileOperation.class); + SecurityMetaData metaData = Mockito.mock(SecurityMetaData.class); + setMocks(metaData, fileOp, VulnerabilityCaseType.FILE_OPERATION); + + Dispatcher dispatcher = new Dispatcher(fileOp, metaData); + dispatcher.call(); + + Mockito.verify(fileOp, atLeastOnce()).getCaseType(); + Mockito.verify(fileOp, atLeastOnce()).getFileName(); + Mockito.verify(fileOp, atLeastOnce()).getUserClassEntity(); + Mockito.verify(fileOp, atLeastOnce()).isGetBooleanAttributesCall(); + + Mockito.verify(metaData, atLeastOnce()).getRequest(); + Mockito.verify(metaData, atLeastOnce()).getMetaData(); + + Mockito.clearInvocations(fileOp); + Mockito.clearInvocations(metaData); + Mockito.clearAllCaches(); + } + + @Test + public void testProcessRXSSTest() throws Exception { + RXSSOperation rxss = Mockito.mock(RXSSOperation.class); + SecurityMetaData metaData = Mockito.mock(SecurityMetaData.class); + setMocks(metaData, rxss, VulnerabilityCaseType.REFLECTED_XSS); + + Dispatcher dispatcher = new Dispatcher(rxss, metaData); + dispatcher.call(); + + Mockito.verify(rxss, atLeastOnce()).getCaseType(); + Mockito.verify(rxss, atLeastOnce()).getUserClassEntity(); + + Mockito.verify(metaData, atLeastOnce()).getRequest(); + Mockito.verify(metaData, atLeastOnce()).getResponse(); + Mockito.verify(metaData, atLeastOnce()).getMetaData(); + + Mockito.clearInvocations(rxss); + Mockito.clearInvocations(metaData); + Mockito.clearAllCaches(); + } + + @Test + public void testProcessRCETest() throws Exception { + Path fileName = Paths.get(String.format("/tmp/tmp%s.sh", UUID.randomUUID())); + Files.createFile(fileName); + Files.write(fileName, "echo 'hello'".getBytes()); + + ForkExecOperation systemCmd = Mockito.mock(ForkExecOperation.class); + doReturn(fileName.toString()).when(systemCmd).getCommand(); + doReturn(new HashMap<>()).when(systemCmd).getScriptContent(); + doReturn(new HashMap<>()).when(systemCmd).getEnvironment(); + SecurityMetaData metaData = Mockito.mock(SecurityMetaData.class); + setMocks(metaData, systemCmd, VulnerabilityCaseType.SYSTEM_COMMAND); + + Dispatcher dispatcher = new Dispatcher(systemCmd, metaData); + dispatcher.call(); + + Mockito.verify(systemCmd, atLeastOnce()).getCaseType(); + Mockito.verify(systemCmd, atLeastOnce()).getCommand(); + Mockito.verify(systemCmd, atLeastOnce()).getEnvironment(); + Mockito.verify(systemCmd, atLeastOnce()).getUserClassEntity(); + Mockito.verify(systemCmd, atLeastOnce()).getScriptContent(); + + Mockito.verify(metaData, atLeastOnce()).getRequest(); + Mockito.verify(metaData, atLeastOnce()).getMetaData(); + + Mockito.clearInvocations(systemCmd, metaData); + Mockito.clearInvocations(); + Mockito.clearAllCaches(); + Files.deleteIfExists(fileName); + } + + @Test + public void testProcessSQLTest() throws Exception { + SQLOperation sqlOperation = Mockito.mock(SQLOperation.class); + SecurityMetaData metaData = Mockito.mock(SecurityMetaData.class); + setMocks(metaData, sqlOperation, VulnerabilityCaseType.SQL_DB_COMMAND); + + Dispatcher dispatcher = new Dispatcher(sqlOperation, metaData); + dispatcher.call(); + + Mockito.verify(sqlOperation, atLeastOnce()).getCaseType(); + Mockito.verify(sqlOperation, atLeastOnce()).getDbName(); + Mockito.verify(sqlOperation, atLeastOnce()).getParams(); + Mockito.verify(sqlOperation, atLeastOnce()).getUserClassEntity(); + Mockito.verify(sqlOperation, atLeastOnce()).getQuery(); + + Mockito.verify(metaData, atLeastOnce()).getRequest(); + Mockito.verify(metaData, atLeastOnce()).getMetaData(); + + Mockito.clearInvocations(sqlOperation); + Mockito.clearInvocations(metaData); + Mockito.clearAllCaches(); + } + + @Test + public void testProcessBatchSQLTest() throws Exception { + BatchSQLOperation sqlOperation = Mockito.mock(BatchSQLOperation.class); + + SQLOperation op = Mockito.mock(SQLOperation.class); + Mockito.doReturn(Collections.singletonMap("key","val")).when(op).getParams(); + Mockito.doReturn(Collections.singletonList(op)).when(sqlOperation).getOperations(); + SecurityMetaData metaData = Mockito.mock(SecurityMetaData.class); + setMocks(metaData, sqlOperation, VulnerabilityCaseType.SQL_DB_COMMAND); + + Dispatcher dispatcher = new Dispatcher(sqlOperation, metaData); + dispatcher.call(); + + Mockito.verify(sqlOperation, atLeastOnce()).getCaseType(); + Mockito.verify(sqlOperation, atLeastOnce()).getOperations(); + Mockito.verify(sqlOperation, atLeastOnce()).getUserClassEntity(); + + Mockito.verify(metaData, atLeastOnce()).getRequest(); + Mockito.verify(metaData, atLeastOnce()).getMetaData(); + + Mockito.clearInvocations(sqlOperation); + Mockito.clearInvocations(metaData); + Mockito.clearAllCaches(); + } + + @Test + public void testProcessNoSQLTest() throws Exception { + SQLOperation noSqlOperation = Mockito.mock(SQLOperation.class); + SecurityMetaData metaData = Mockito.mock(SecurityMetaData.class); + setMocks(metaData, noSqlOperation, VulnerabilityCaseType.NOSQL_DB_COMMAND); + + Dispatcher dispatcher = new Dispatcher(noSqlOperation, metaData); + dispatcher.call(); + + Mockito.verify(noSqlOperation, atLeastOnce()).getCaseType(); + Mockito.verify(noSqlOperation, atLeastOnce()).getDbName(); + Mockito.verify(noSqlOperation, atLeastOnce()).getParams(); + Mockito.verify(noSqlOperation, atLeastOnce()).getUserClassEntity(); + Mockito.verify(noSqlOperation, atLeastOnce()).getQuery(); + + Mockito.verify(metaData, atLeastOnce()).getRequest(); + Mockito.verify(metaData, atLeastOnce()).getMetaData(); + + Mockito.clearInvocations(noSqlOperation); + Mockito.clearInvocations(metaData); + Mockito.clearAllCaches(); + } + + @Test + public void testProcessBatchNoSQLTest() throws Exception { + BatchSQLOperation noSqlOperation = Mockito.mock(BatchSQLOperation.class); + SecurityMetaData metaData = Mockito.mock(SecurityMetaData.class); + SQLOperation op = Mockito.mock(SQLOperation.class); + Mockito.doReturn(Collections.singletonMap("key","val")).when(op).getParams(); + Mockito.doReturn(Collections.singletonList(op)).when(noSqlOperation).getOperations(); + setMocks(metaData, noSqlOperation, VulnerabilityCaseType.NOSQL_DB_COMMAND); + + Dispatcher dispatcher = new Dispatcher(noSqlOperation, metaData); + dispatcher.call(); + + Mockito.verify(noSqlOperation, atLeastOnce()).getCaseType(); + Mockito.verify(noSqlOperation, atLeastOnce()).getOperations(); + Mockito.verify(noSqlOperation, atLeastOnce()).getUserClassEntity(); + + Mockito.verify(metaData, atLeastOnce()).getRequest(); + Mockito.verify(metaData, atLeastOnce()).getMetaData(); + + Mockito.clearInvocations(noSqlOperation); + Mockito.clearInvocations(metaData); + Mockito.clearAllCaches(); + } + + @Test + public void testProcessNoSQLDBTest() throws Exception { + NoSQLOperation noSqlOperation = Mockito.mock(NoSQLOperation.class); + Mockito.doReturn(Collections.singletonList("payload")).when(noSqlOperation).getPayload(); + SecurityMetaData metaData = Mockito.mock(SecurityMetaData.class); + setMocks(metaData, noSqlOperation, VulnerabilityCaseType.NOSQL_DB_COMMAND); + + Dispatcher dispatcher = new Dispatcher(noSqlOperation, metaData); + dispatcher.call(); + + Mockito.verify(noSqlOperation, atLeastOnce()).getCaseType(); + Mockito.verify(noSqlOperation, atLeastOnce()).getPayload(); + Mockito.verify(noSqlOperation, atLeastOnce()).getUserClassEntity(); + + Mockito.verify(metaData, atLeastOnce()).getRequest(); + Mockito.verify(metaData, atLeastOnce()).getMetaData(); + + Mockito.clearInvocations(noSqlOperation); + Mockito.clearInvocations(metaData); + Mockito.clearAllCaches(); + } + + @Test + public void testProcessDynamoTest() throws Exception { + DynamoDBOperation dynamoDBOperation = Mockito.mock(DynamoDBOperation.class); + SecurityMetaData metaData = Mockito.mock(SecurityMetaData.class); + setMocks(metaData, dynamoDBOperation, VulnerabilityCaseType.NOSQL_DB_COMMAND); + doReturn(DynamoDBOperation.Category.DQL).when(dynamoDBOperation).getCategory(); + + Dispatcher dispatcher = new Dispatcher(dynamoDBOperation, metaData); + dispatcher.call(); + + Mockito.verify(dynamoDBOperation, atLeastOnce()).getCaseType(); + Mockito.verify(dynamoDBOperation, atLeastOnce()).getPayload(); + Mockito.verify(dynamoDBOperation, atLeastOnce()).getCategory(); + Mockito.verify(dynamoDBOperation, atLeastOnce()).getUserClassEntity(); + + Mockito.verify(metaData, atLeastOnce()).getRequest(); + Mockito.verify(metaData, atLeastOnce()).getMetaData(); + + Mockito.clearInvocations(dynamoDBOperation); + Mockito.clearInvocations(metaData); + Mockito.clearAllCaches(); + } + + @Test + public void testProcessFileIntegrityTest() throws Exception { + FileIntegrityOperation fileIntegrityOperation = Mockito.mock(FileIntegrityOperation.class); + SecurityMetaData metaData = Mockito.mock(SecurityMetaData.class); + setMocks(metaData, fileIntegrityOperation, VulnerabilityCaseType.FILE_INTEGRITY); + + Dispatcher dispatcher = new Dispatcher(fileIntegrityOperation, metaData); + dispatcher.call(); + + Mockito.verify(fileIntegrityOperation, atLeastOnce()).getCaseType(); + Mockito.verify(fileIntegrityOperation, atLeastOnce()).getFileName(); + Mockito.verify(fileIntegrityOperation, atLeastOnce()).getUserClassEntity(); + + Mockito.verify(metaData, atLeastOnce()).getRequest(); + Mockito.verify(metaData, atLeastOnce()).getMetaData(); + + Mockito.clearInvocations(fileIntegrityOperation); + Mockito.clearInvocations(metaData); + Mockito.clearAllCaches(); + } + + @Test + public void testProcessLdapTest() throws Exception { + LDAPOperation ldapOperation = Mockito.mock(LDAPOperation.class); + SecurityMetaData metaData = Mockito.mock(SecurityMetaData.class); + setMocks(metaData, ldapOperation, VulnerabilityCaseType.LDAP); + + Dispatcher dispatcher = new Dispatcher(ldapOperation, metaData); + dispatcher.call(); + + Mockito.verify(ldapOperation, atLeastOnce()).getCaseType(); + Mockito.verify(ldapOperation, atLeastOnce()).getFilter(); + Mockito.verify(ldapOperation, atLeastOnce()).getName(); + Mockito.verify(ldapOperation, atLeastOnce()).getUserClassEntity(); + + Mockito.verify(metaData, atLeastOnce()).getRequest(); + Mockito.verify(metaData, atLeastOnce()).getMetaData(); + + Mockito.clearInvocations(ldapOperation); + Mockito.clearInvocations(metaData); + Mockito.clearAllCaches(); + } + + @Test + public void testProcessRandomTest() throws Exception { + RandomOperation randomOperation = Mockito.mock(RandomOperation.class); + SecurityMetaData metaData = Mockito.mock(SecurityMetaData.class); + setMocks(metaData, randomOperation, VulnerabilityCaseType.RANDOM); + + Dispatcher dispatcher = new Dispatcher(randomOperation, metaData); + dispatcher.call(); + + Mockito.verify(randomOperation, atLeastOnce()).getCaseType(); + Mockito.verify(randomOperation, atLeastOnce()).getClassName(); + Mockito.verify(randomOperation, atLeastOnce()).getEventCatgory(); + Mockito.verify(randomOperation, atLeastOnce()).getUserClassEntity(); + + Mockito.verify(metaData, atLeastOnce()).getRequest(); + Mockito.verify(metaData, atLeastOnce()).getMetaData(); + + Mockito.clearInvocations(randomOperation); + Mockito.clearInvocations(metaData); + Mockito.clearAllCaches(); + } + + @Test + public void testProcessSSRFTest() throws Exception { + SSRFOperation ssrfOperation = Mockito.mock(SSRFOperation.class); + SecurityMetaData metaData = Mockito.mock(SecurityMetaData.class); + setMocks(metaData, ssrfOperation, VulnerabilityCaseType.HTTP_REQUEST); + + Dispatcher dispatcher = new Dispatcher(ssrfOperation, metaData); + dispatcher.call(); + + Mockito.verify(ssrfOperation, atLeastOnce()).getCaseType(); + Mockito.verify(ssrfOperation, atLeastOnce()).isJNDILookup(); + Mockito.verify(ssrfOperation, atLeastOnce()).getArg(); + Mockito.verify(ssrfOperation, atLeastOnce()).getUserClassEntity(); + + Mockito.verify(metaData, atLeastOnce()).getRequest(); + Mockito.verify(metaData, atLeastOnce()).getMetaData(); + + Mockito.clearInvocations(ssrfOperation); + Mockito.clearInvocations(metaData); + Mockito.clearAllCaches(); + } + + @Test + public void testProcessXPathTest() throws Exception { + XPathOperation xPathOperation = Mockito.mock(XPathOperation.class); + SecurityMetaData metaData = Mockito.mock(SecurityMetaData.class); + + setMocks(metaData, xPathOperation, VulnerabilityCaseType.XPATH); + + Dispatcher dispatcher = new Dispatcher(xPathOperation, metaData); + dispatcher.call(); + + Mockito.verify(xPathOperation, atLeastOnce()).getCaseType(); + Mockito.verify(xPathOperation, atLeastOnce()).getExpression(); + Mockito.verify(xPathOperation, atLeastOnce()).getUserClassEntity(); + + Mockito.verify(metaData, atLeastOnce()).getRequest(); + Mockito.verify(metaData, atLeastOnce()).getMetaData(); + + Mockito.clearInvocations(xPathOperation); + Mockito.clearInvocations(metaData); + Mockito.clearAllCaches(); + } + + @Test + public void testProcessSecureTest() throws Exception { + SecureCookieOperationSet operationSet = Mockito.mock(SecureCookieOperationSet.class); + SecureCookieOperationSet.SecureCookieOperation cookieOperation = Mockito.mock(SecureCookieOperationSet.SecureCookieOperation.class); + SecurityMetaData metaData = Mockito.mock(SecurityMetaData.class); + + Mockito.doReturn(Collections.singleton(cookieOperation)).when(operationSet).getOperations(); + setMocks(metaData, operationSet, VulnerabilityCaseType.SECURE_COOKIE); + + Dispatcher dispatcher = new Dispatcher(operationSet, metaData); + dispatcher.call(); + + Mockito.verify(operationSet, atLeastOnce()).getCaseType(); + Mockito.verify(operationSet, atLeastOnce()).getOperations(); + Mockito.verify(cookieOperation, atLeastOnce()).getName(); + Mockito.verify(cookieOperation, atLeastOnce()).getValue(); + Mockito.verify(cookieOperation, atLeastOnce()).isSecure(); + Mockito.verify(cookieOperation, atLeastOnce()).isHttpOnly(); + + Mockito.verify(metaData, atLeastOnce()).getRequest(); + Mockito.verify(metaData, atLeastOnce()).getMetaData(); + + Mockito.clearInvocations(cookieOperation); + Mockito.clearInvocations(metaData); + Mockito.clearAllCaches(); + } + + @Test + public void testProcessTrustBoundaryTest() throws Exception { + TrustBoundaryOperation trustBoundaryOperation = Mockito.mock(TrustBoundaryOperation.class); + SecurityMetaData metaData = Mockito.mock(SecurityMetaData.class); + setMocks(metaData, trustBoundaryOperation, VulnerabilityCaseType.TRUSTBOUNDARY); + + Dispatcher dispatcher = new Dispatcher(trustBoundaryOperation, metaData); + dispatcher.call(); + + Mockito.verify(trustBoundaryOperation, atLeastOnce()).getCaseType(); + Mockito.verify(trustBoundaryOperation, atLeastOnce()).getKey(); + Mockito.verify(trustBoundaryOperation, atLeastOnce()).getValue(); + Mockito.verify(trustBoundaryOperation, atLeastOnce()).getUserClassEntity(); + + Mockito.verify(metaData, atLeastOnce()).getRequest(); + Mockito.verify(metaData, atLeastOnce()).getMetaData(); + + Mockito.clearInvocations(trustBoundaryOperation); + Mockito.clearInvocations(metaData); + Mockito.clearAllCaches(); + } + + @Test + public void testProcessCryptoTest() throws Exception { + HashCryptoOperation cryptoOperation = Mockito.mock(HashCryptoOperation.class); + SecurityMetaData metaData = Mockito.mock(SecurityMetaData.class); + setMocks(metaData, cryptoOperation, VulnerabilityCaseType.CRYPTO); + + Dispatcher dispatcher = new Dispatcher(cryptoOperation, metaData); + dispatcher.call(); + + Mockito.verify(cryptoOperation, atLeastOnce()).getCaseType(); + Mockito.verify(cryptoOperation, atLeastOnce()).getName(); + Mockito.verify(cryptoOperation, atLeastOnce()).getEventCategory(); + Mockito.verify(cryptoOperation, atLeastOnce()).getProvider(); + Mockito.verify(cryptoOperation, atLeastOnce()).getUserClassEntity(); + + Mockito.verify(metaData, atLeastOnce()).getRequest(); + Mockito.verify(metaData, atLeastOnce()).getMetaData(); + + Mockito.clearInvocations(cryptoOperation); + Mockito.clearInvocations(metaData); + Mockito.clearAllCaches(); + } + + @Test + public void testProcessHashTest() throws Exception { + HashCryptoOperation hashCryptoOperation = Mockito.mock(HashCryptoOperation.class); + SecurityMetaData metaData = Mockito.mock(SecurityMetaData.class); + setMocks(metaData, hashCryptoOperation, VulnerabilityCaseType.HASH); + + Dispatcher dispatcher = new Dispatcher(hashCryptoOperation, metaData); + dispatcher.call(); + + Mockito.verify(hashCryptoOperation, atLeastOnce()).getCaseType(); + Mockito.verify(hashCryptoOperation, atLeastOnce()).getName(); + Mockito.verify(hashCryptoOperation, atLeastOnce()).getProvider(); + Mockito.verify(hashCryptoOperation, atLeastOnce()).getUserClassEntity(); + + Mockito.verify(metaData, atLeastOnce()).getRequest(); + Mockito.verify(metaData, atLeastOnce()).getMetaData(); + + Mockito.clearInvocations(hashCryptoOperation); + Mockito.clearInvocations(metaData); + Mockito.clearAllCaches(); + } + + @Test + public void testProcessJSTest() throws Exception { + JSInjectionOperation jsInjectionOperation = Mockito.mock(JSInjectionOperation.class); + SecurityMetaData metaData = Mockito.mock(SecurityMetaData.class); + setMocks(metaData, jsInjectionOperation, VulnerabilityCaseType.JAVASCRIPT_INJECTION); + + Dispatcher dispatcher = new Dispatcher(jsInjectionOperation, metaData); + dispatcher.call(); + + Mockito.verify(jsInjectionOperation, atLeastOnce()).getCaseType(); + Mockito.verify(jsInjectionOperation, atLeastOnce()).getJavaScriptCode(); + Mockito.verify(jsInjectionOperation, atLeastOnce()).getUserClassEntity(); + + Mockito.verify(metaData, atLeastOnce()).getRequest(); + Mockito.verify(metaData, atLeastOnce()).getMetaData(); + + Mockito.clearInvocations(jsInjectionOperation); + Mockito.clearInvocations(metaData); + Mockito.clearAllCaches(); + } + + @Test + public void testProcessXQueryTest() throws Exception { + XQueryOperation xQueryOperation = Mockito.mock(XQueryOperation.class); + SecurityMetaData metaData = Mockito.mock(SecurityMetaData.class); + setMocks(metaData, xQueryOperation, VulnerabilityCaseType.XQUERY_INJECTION); + + Dispatcher dispatcher = new Dispatcher(xQueryOperation, metaData); + dispatcher.call(); + + Mockito.verify(xQueryOperation, atLeastOnce()).getCaseType(); + Mockito.verify(xQueryOperation, atLeastOnce()).getExpression(); + Mockito.verify(xQueryOperation, atLeastOnce()).getUserClassEntity(); + + Mockito.verify(metaData, atLeastOnce()).getRequest(); + Mockito.verify(metaData, atLeastOnce()).getMetaData(); + + Mockito.clearInvocations(xQueryOperation); + Mockito.clearInvocations(metaData); + Mockito.clearAllCaches(); + } + + @Test + public void redisOperationTest() throws Exception { + RedisOperation redisOperation = Mockito.mock(RedisOperation.class); + SecurityMetaData metaData = Mockito.mock(SecurityMetaData.class); + setMocks(metaData, redisOperation, VulnerabilityCaseType.CACHING_DATA_STORE); + + Dispatcher dispatcher = new Dispatcher(redisOperation, metaData); + dispatcher.call(); + + Mockito.verify(redisOperation, atLeastOnce()).getCaseType(); + Mockito.verify(redisOperation, atLeastOnce()).getArguments(); + Mockito.verify(redisOperation, atLeastOnce()).getMode(); + Mockito.verify(redisOperation, atLeastOnce()).getType(); + + Mockito.clearInvocations(redisOperation); + Mockito.clearInvocations(metaData); + Mockito.clearAllCaches(); + } + + @Test + public void jCacheOperationTest() throws Exception { + JCacheOperation operation = Mockito.mock(JCacheOperation.class); + SecurityMetaData metaData = Mockito.mock(SecurityMetaData.class); + setMocks(metaData, operation, VulnerabilityCaseType.CACHING_DATA_STORE); + + Dispatcher dispatcher = new Dispatcher(operation, metaData); + dispatcher.call(); + + Mockito.verify(operation, atLeastOnce()).getCaseType(); + Mockito.verify(operation, atLeastOnce()).getArguments(); + Mockito.verify(operation, atLeastOnce()).getCategory(); + Mockito.verify(operation, atLeastOnce()).getType(); + + Mockito.clearInvocations(operation); + Mockito.clearInvocations(metaData); + Mockito.clearAllCaches(); + } + + @Test + public void memcachedOperationTest() throws Exception { + MemcachedOperation operation = Mockito.mock(MemcachedOperation.class); + SecurityMetaData metaData = Mockito.mock(SecurityMetaData.class); + setMocks(metaData, operation, VulnerabilityCaseType.CACHING_DATA_STORE); + + Dispatcher dispatcher = new Dispatcher(operation, metaData); + dispatcher.call(); + + Mockito.verify(operation, atLeastOnce()).getCaseType(); + Mockito.verify(operation, atLeastOnce()).getArguments(); + Mockito.verify(operation, atLeastOnce()).getCategory(); + Mockito.verify(operation, atLeastOnce()).getType(); + + Mockito.clearInvocations(operation); + Mockito.clearInvocations(metaData); + Mockito.clearAllCaches(); + } + + + @Test + public void testSolrDbOperation() throws Exception { + SolrDbOperation operation = Mockito.mock(SolrDbOperation.class); + Mockito.doReturn(Thread.currentThread().getStackTrace()).when(operation).getStackTrace(); + SecurityMetaData metaData = Mockito.mock(SecurityMetaData.class); + setMocks(metaData, operation, VulnerabilityCaseType.SOLR_DB_REQUEST); + + Dispatcher dispatcher = new Dispatcher(operation, metaData); + dispatcher.call(); + Assert.assertNotNull(dispatcher.getSecurityMetaData()); + Assert.assertNotNull(dispatcher.getOperation()); + Assert.assertNull(dispatcher.getExitEventBean()); + + Mockito.verify(operation, atLeastOnce()).getCaseType(); + Mockito.verify(operation, atLeastOnce()).getCollection(); + Mockito.verify(operation, atLeastOnce()).getMethod(); + Mockito.verify(operation, atLeastOnce()).getConnectionURL(); + Mockito.verify(operation, atLeastOnce()).getPath(); + Mockito.verify(operation, atLeastOnce()).getParams(); + Mockito.verify(operation, atLeastOnce()).getDocuments(); + + Mockito.clearInvocations(operation); + Mockito.clearAllCaches(); + } + + @Test + public void testRXSSOperation() throws Exception { + RXSSOperation operation = Mockito.mock(RXSSOperation.class); + Mockito.doReturn(Thread.currentThread().getStackTrace()).when(operation).getStackTrace(); + SecurityMetaData metaData = Mockito.mock(SecurityMetaData.class); + + setMocks(metaData, operation, VulnerabilityCaseType.REFLECTED_XSS); + + Dispatcher dispatcher = new Dispatcher(operation, metaData); + dispatcher.call(); + Assert.assertNotNull(dispatcher.getSecurityMetaData()); + Assert.assertNotNull(dispatcher.getOperation()); + Assert.assertNull(dispatcher.getExitEventBean()); + + Mockito.verify(operation, atLeastOnce()).getCaseType(); + + Mockito.clearInvocations(operation); + Mockito.clearAllCaches(); + } + + @Test + public void testProcessStackTrace() throws Exception { + SSRFOperation ssrfOperation = Mockito.mock(SSRFOperation.class); + Mockito.doReturn(Thread.currentThread().getStackTrace()).when(ssrfOperation).getStackTrace(); + SecurityMetaData metaData = Mockito.mock(SecurityMetaData.class); + setMocks(metaData, ssrfOperation, VulnerabilityCaseType.HTTP_REQUEST); + + Dispatcher dispatcher = new Dispatcher(ssrfOperation, metaData); + dispatcher.call(); + Assert.assertNotNull(dispatcher.getSecurityMetaData()); + Assert.assertNotNull(dispatcher.getOperation()); + Assert.assertNull(dispatcher.getExitEventBean()); + + Mockito.verify(ssrfOperation, atLeastOnce()).getStackTrace(); + Mockito.clearInvocations(ssrfOperation); + Mockito.clearAllCaches(); + } + + @Test + public void testExitEvent() throws Exception { + ExitEventBean exitEventBean = Mockito.mock(ExitEventBean.class); + + Dispatcher dispatcher = new Dispatcher(exitEventBean); + dispatcher.call(); + Assert.assertNull(dispatcher.getSecurityMetaData()); + Assert.assertNull(dispatcher.getOperation()); + Assert.assertNotNull(dispatcher.getExitEventBean()); + + Mockito.clearAllCaches(); + } + + + + private void setMocks(SecurityMetaData metaData, AbstractOperation operation, VulnerabilityCaseType caseType) { + doReturn(caseType).when(operation).getCaseType(); + doReturn(Mockito.mock(AgentMetaData.class)).when(metaData).getMetaData(); + HttpRequest httpRequest = new HttpRequest(); + HttpResponse response = new HttpResponse(); + httpRequest.setUrl("/url"); httpRequest.getBody().append("hello"); + + doReturn(httpRequest).when(metaData).getRequest(); + doReturn(response).when(metaData).getResponse(); + doReturn(Mockito.mock(K2RequestIdentifier.class)).when(metaData).getFuzzRequestIdentifier(); + String header = "header"; + doReturn(header).when(metaData).getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class); + doReturn(header).when(metaData).getCustomAttribute("trace.id", String.class); + doReturn(header).when(metaData).getCustomAttribute("span.id", String.class); + UserClassEntity entity = new UserClassEntity(); + entity.setUserClassElement(Thread.currentThread().getStackTrace()[1]); + doReturn(entity).when(operation).getUserClassEntity(); + } + +} diff --git a/newrelic-security-agent/src/test/java/com/newrelic/agent/security/instrumentator/helper/DynamoDBRequestConverterTest.java b/newrelic-security-agent/src/test/java/com/newrelic/agent/security/instrumentator/helper/DynamoDBRequestConverterTest.java new file mode 100644 index 000000000..13c46ae77 --- /dev/null +++ b/newrelic-security-agent/src/test/java/com/newrelic/agent/security/instrumentator/helper/DynamoDBRequestConverterTest.java @@ -0,0 +1,389 @@ +package com.newrelic.agent.security.instrumentator.helper; + +import com.newrelic.api.agent.security.schema.helper.DynamoDBRequest; +import org.json.simple.JSONObject; +import org.junit.Assert; +import org.junit.Test; +import software.amazon.awssdk.services.dynamodb.model.AttributeValue; +import software.amazon.awssdk.services.dynamodb.model.AttributeValueUpdate; +import software.amazon.awssdk.services.dynamodb.model.ExpectedAttributeValue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; + +import static com.newrelic.api.agent.security.schema.operation.DynamoDBOperation.Category.*; + +public class DynamoDBRequestConverterTest { + public final String PARAMETERS = "parameters"; + private final String PAYLOAD = "payload"; + private final String QUERY = "query"; + private final String PAYLOAD_TYPE = "payloadType"; + private final String OP = "operation"; + private final String EXPRESSION = "#col = :val"; + private final String TABLE = "test"; + private final String stringVal = "value"; + private final String STMT = "select * from test;"; + private final DynamoDBRequest REQUEST = new DynamoDBRequest(null, OP); + @Test(expected = RuntimeException.class) + public void Convert0Test(){ + DynamoDBRequestConverter.convert(DQL, REQUEST); + } + @Test + public void Convert1Test(){ + REQUEST.setQuery(new DynamoDBRequest.Query()); + REQUEST.setQueryType(null); + JSONObject obj = DynamoDBRequestConverter.convert(DQL, REQUEST); + Assert.assertNull(obj.get(PAYLOAD_TYPE)); + Assert.assertEquals("{}", obj.get(PAYLOAD).toString()); + } + @Test + public void Convert2Test(){ + REQUEST.setQuery(new DynamoDBRequest.Query()); + JSONObject obj = DynamoDBRequestConverter.convert(DQL, REQUEST); + Assert.assertEquals(OP, obj.get(PAYLOAD_TYPE)); + Assert.assertEquals("{}", obj.get(PAYLOAD).toString()); + } + @Test + public void Convert3Test(){ + REQUEST.setQuery(new DynamoDBRequest.Query()); + JSONObject obj = DynamoDBRequestConverter.convert(DQL, REQUEST); + Assert.assertEquals(OP, obj.get(PAYLOAD_TYPE)); + Assert.assertEquals("{}", obj.get(PAYLOAD).toString()); + } + + @Test + public void PartiQLTest(){ + DynamoDBRequest.Query query = new DynamoDBRequest.Query(); + query.setStatement(STMT); + query.setParameters(new Object()); + REQUEST.setQuery(query); + JSONObject obj = DynamoDBRequestConverter.convert(PARTIQL, REQUEST); + Assert.assertEquals(STMT, obj.get(QUERY)); + } + @Test + public void PartiQL1Test(){ + DynamoDBRequest.Query query = new DynamoDBRequest.Query(); + query.setStatement(STMT); + + query.setParameters(Collections.singletonList(ExpectedAttributeValue.builder().value(AttributeValue.builder().s(stringVal).build()).build())); + REQUEST.setQuery(query); + JSONObject obj = DynamoDBRequestConverter.convert(PARTIQL, REQUEST); + Assert.assertEquals(STMT, obj.get(QUERY)); + + Object[] some = ((Object[])(obj.get(PARAMETERS))); + Assert.assertTrue(some[0] instanceof JSONObject); + Assert.assertEquals(stringVal, ((JSONObject)(some[0])).get("s")); + } + @Test + public void PartiQL2Test(){ + DynamoDBRequest.Query query = new DynamoDBRequest.Query(); + query.setStatement(STMT); + + query.setParameters(Collections.singletonList(AttributeValue.builder().s(stringVal).build())); + REQUEST.setQuery(query); + JSONObject obj = DynamoDBRequestConverter.convert(PARTIQL, REQUEST); + Assert.assertEquals(STMT, obj.get(QUERY)); + + Object[] some = ((Object[])(obj.get(PARAMETERS))); + Assert.assertTrue(some[0] instanceof JSONObject); + Assert.assertEquals(stringVal, ((JSONObject)(some[0])).get("s")); + } + @Test + public void PartiQL3Test(){ + DynamoDBRequest.Query query = new DynamoDBRequest.Query(); + query.setStatement(STMT); + + query.setParameters(Collections.singletonList(AttributeValueUpdate.builder().value(AttributeValue.builder().s(stringVal).build()).build())); + REQUEST.setQuery(query); + JSONObject obj = DynamoDBRequestConverter.convert(PARTIQL, REQUEST); + Assert.assertEquals(STMT, obj.get(QUERY)); + + Object[] some = ((Object[])(obj.get(PARAMETERS))); + Assert.assertTrue(some[0] instanceof JSONObject); + Assert.assertEquals(stringVal, ((JSONObject)(some[0])).get("s")); + } + + @Test + public void ConvertKeyExTest(){ + HashMap map = new HashMap<>(); + map.put("key", "val"); + map.put("key1", "val1"); + + ArrayList list = new ArrayList<>(); + list.add(map); + + DynamoDBRequest.Query query = new DynamoDBRequest.Query(); + query.setKey(list); + + REQUEST.setQuery(query); + JSONObject obj = DynamoDBRequestConverter.convert(DQL, REQUEST); + Assert.assertEquals(OP, obj.get(PAYLOAD_TYPE)); + + JSONObject payload = (JSONObject) obj.get(PAYLOAD); + Assert.assertNotNull(payload); + + Assert.assertNotNull(payload.get("key")); + Assert.assertEquals(list, new ArrayList<>(Arrays.asList((Object[]) payload.get("key")))); + } + @Test + public void ConvertItemExTest(){ + HashMap map = new HashMap<>(); + map.put("key", "val"); + map.put("key1", "val1"); + + DynamoDBRequest.Query query = new DynamoDBRequest.Query(); + query.setItem(map); + + REQUEST.setQuery(query); + JSONObject obj = DynamoDBRequestConverter.convert(DQL, REQUEST); + Assert.assertEquals(OP, obj.get(PAYLOAD_TYPE)); + + JSONObject payload = (JSONObject) obj.get(PAYLOAD); + Assert.assertNotNull(payload); + + Assert.assertNotNull(payload.get("item")); + Assert.assertEquals(map, payload.get("item")); + } + @Test + public void ConvertExAttNamesTest(){ + HashMap map = new HashMap<>(); + map.put("key", "val"); + map.put("key1", "val1"); + + DynamoDBRequest.Query query = new DynamoDBRequest.Query(); + query.setExpressionAttributeNames(map); + + REQUEST.setQuery(query); + JSONObject obj = DynamoDBRequestConverter.convert(DQL, REQUEST); + Assert.assertEquals(OP, obj.get(PAYLOAD_TYPE)); + + JSONObject payload = (JSONObject) obj.get(PAYLOAD); + Assert.assertNotNull(payload); + + Assert.assertNotNull(payload.get("expressionAttributeNames")); + Assert.assertEquals(map, payload.get("expressionAttributeNames")); + } + @Test + public void ConvertExAttValuesTest(){ + HashMap map = new HashMap<>(); + map.put("key", "val"); + map.put("key1", "val1"); + + DynamoDBRequest.Query query = new DynamoDBRequest.Query(); + query.setExpressionAttributeValues(map); + + REQUEST.setQuery(query); + JSONObject obj = DynamoDBRequestConverter.convert(DQL, REQUEST); + Assert.assertEquals(OP, obj.get(PAYLOAD_TYPE)); + + JSONObject payload = (JSONObject) obj.get(PAYLOAD); + Assert.assertNotNull(payload); + + Assert.assertNotNull(payload.get("expressionAttributeValues")); + Assert.assertEquals(map, payload.get("expressionAttributeValues")); + } + @Test + public void ConvertAttToGetTest(){ + ArrayList list1 = new ArrayList<>(); + list1.add("col1"); + list1.add("col2"); + + DynamoDBRequest.Query query = new DynamoDBRequest.Query(); + query.setAttributesToGet(list1); + + REQUEST.setQuery(query); + JSONObject obj = DynamoDBRequestConverter.convert(DQL, REQUEST); + Assert.assertEquals(OP, obj.get(PAYLOAD_TYPE)); + + JSONObject payload = (JSONObject) obj.get(PAYLOAD); + Assert.assertNotNull(payload); + + Assert.assertNotNull(payload.get("attributesToGet")); + Assert.assertEquals(list1, payload.get("attributesToGet")); + } + @Test + public void ConvertScanFilterTest(){ + HashMap map = new HashMap<>(); + map.put("key", "val"); + map.put("key1", "val1"); + + DynamoDBRequest.Query query = new DynamoDBRequest.Query(); + query.setScanFilter(map); + + REQUEST.setQuery(query); + JSONObject obj = DynamoDBRequestConverter.convert(DQL, REQUEST); + Assert.assertEquals(OP, obj.get(PAYLOAD_TYPE)); + + JSONObject payload = (JSONObject) obj.get(PAYLOAD); + Assert.assertNotNull(payload); + + Assert.assertNotNull(payload.get("scanFilter")); + Assert.assertEquals(map, payload.get("scanFilter")); + } + @Test + public void ConvertQueryFilterTest(){ + HashMap map = new HashMap<>(); + map.put("key", "val"); + map.put("key1", "val1"); + + DynamoDBRequest.Query query = new DynamoDBRequest.Query(); + query.setQueryFilter(map); + + REQUEST.setQuery(query); + JSONObject obj = DynamoDBRequestConverter.convert(DQL, REQUEST); + Assert.assertEquals(OP, obj.get(PAYLOAD_TYPE)); + + JSONObject payload = (JSONObject) obj.get(PAYLOAD); + Assert.assertNotNull(payload); + + Assert.assertNotNull(payload.get("queryFilter")); + Assert.assertEquals(map, payload.get("queryFilter")); + } + @Test + public void ConvertExpectedTest(){ + HashMap map = new HashMap<>(); + map.put("key", "val"); + map.put("key1", "val1"); + + DynamoDBRequest.Query query = new DynamoDBRequest.Query(); + query.setExpected(map); + + REQUEST.setQuery(query); + JSONObject obj = DynamoDBRequestConverter.convert(DQL, REQUEST); + Assert.assertEquals(OP, obj.get(PAYLOAD_TYPE)); + + JSONObject payload = (JSONObject) obj.get(PAYLOAD); + Assert.assertNotNull(payload); + + Assert.assertNotNull(payload.get("expected")); + Assert.assertEquals(map, payload.get("expected")); + } + @Test + public void ConvertAttUpdatesTest(){ + HashMap map = new HashMap<>(); + map.put("key", "val"); + map.put("key1", "val1"); + + DynamoDBRequest.Query query = new DynamoDBRequest.Query(); + query.setAttributeUpdates(map); + + REQUEST.setQuery(query); + JSONObject obj = DynamoDBRequestConverter.convert(DQL, REQUEST); + Assert.assertEquals(OP, obj.get(PAYLOAD_TYPE)); + + JSONObject payload = (JSONObject) obj.get(PAYLOAD); + Assert.assertNotNull(payload); + + Assert.assertNotNull(payload.get("attributeUpdates")); + Assert.assertEquals(map, payload.get("attributeUpdates")); + } + + @Test + public void ConvertParametersTest(){ + ArrayList list1 = new ArrayList<>(); + list1.add("val1"); + list1.add("val2"); + + DynamoDBRequest.Query query = new DynamoDBRequest.Query(); + query.setParameters(list1); + + REQUEST.setQuery(query); + JSONObject obj = DynamoDBRequestConverter.convert(DQL, REQUEST); + Assert.assertEquals(OP, obj.get(PAYLOAD_TYPE)); + + JSONObject payload = (JSONObject) obj.get(PAYLOAD); + Assert.assertNotNull(payload); + + Assert.assertNotNull(payload.get(PARAMETERS)); + Assert.assertEquals(list1, new ArrayList<>(Arrays.asList((Object[]) payload.get(PARAMETERS)))); + } + @Test + public void ConvertAllTest(){ + HashMap map = new HashMap<>(); + map.put("key", "val"); + + ArrayList list1 = new ArrayList<>(); + list1.add("col1"); + + DynamoDBRequest.Query query = new DynamoDBRequest.Query(); + query.setKey(map); + query.setItem(list1); + query.setTableName(TABLE); + query.setConditionExpression(EXPRESSION); + query.setKeyConditionExpression(EXPRESSION); + query.setFilterExpression(EXPRESSION); + query.setUpdateExpression(EXPRESSION); + query.setProjectionExpression(EXPRESSION); + query.setExpressionAttributeNames(map); + query.setExpressionAttributeValues(map); + query.setAttributesToGet(list1); + query.setQueryFilter(map); + query.setScanFilter(map); + query.setExpected(list1); + query.setAttributeUpdates(map); + query.setStatement(STMT); + query.setParameters(map); + + REQUEST.setQuery(query); + JSONObject obj = DynamoDBRequestConverter.convert(DQL, REQUEST); + Assert.assertEquals(OP, obj.get(PAYLOAD_TYPE)); + + + JSONObject payload = (JSONObject) obj.get(PAYLOAD); + Assert.assertNotNull(payload); + + Assert.assertNotNull(payload.get("key")); + Assert.assertEquals(map, payload.get("key")); + + Assert.assertNotNull(payload.get("item")); + Assert.assertEquals(list1, new ArrayList<>(Arrays.asList(((Object[]) payload.get("item"))))); + + Assert.assertNotNull(payload.get("tableName")); + Assert.assertEquals(TABLE, payload.get("tableName")); + + Assert.assertNotNull(payload.get("conditionExpression")); + Assert.assertEquals(EXPRESSION, payload.get("conditionExpression")); + + Assert.assertNotNull(payload.get("keyConditionExpression")); + Assert.assertEquals(EXPRESSION, payload.get("keyConditionExpression")); + + Assert.assertNotNull(payload.get("filterExpression")); + Assert.assertEquals(EXPRESSION, payload.get("filterExpression")); + + Assert.assertNotNull(payload.get("updateExpression")); + Assert.assertEquals(EXPRESSION, payload.get("updateExpression")); + + Assert.assertNotNull(payload.get("projectionExpression")); + Assert.assertEquals(EXPRESSION, payload.get("projectionExpression")); + + Assert.assertNotNull(payload.get("expressionAttributeNames")); + Assert.assertEquals(map, payload.get("expressionAttributeNames")); + + Assert.assertNotNull(payload.get("expressionAttributeValues")); + Assert.assertEquals(map, payload.get("expressionAttributeValues")); + + Assert.assertNotNull(payload.get("attributesToGet")); + Assert.assertEquals(list1, payload.get("attributesToGet")); + + Assert.assertNotNull(payload.get("queryFilter")); + Assert.assertEquals(map, payload.get("queryFilter")); + + Assert.assertNotNull(payload.get("scanFilter")); + Assert.assertEquals(map, payload.get("scanFilter")); + + Assert.assertNotNull(payload.get("expected")); + Assert.assertEquals(list1, new ArrayList<>(Arrays.asList(((Object[]) payload.get("expected"))))); + + Assert.assertNotNull(payload.get("statement")); + Assert.assertEquals(STMT, payload.get("statement")); + + Assert.assertNotNull(payload.get("attributeUpdates")); + Assert.assertEquals(map, payload.get("attributeUpdates")); + + Assert.assertNotNull(payload.get(PARAMETERS)); + Assert.assertEquals(map, payload.get(PARAMETERS)); + } + +} diff --git a/newrelic-security-agent/src/test/java/com/newrelic/agent/security/instrumentator/httpclient/RestRequestProcessorTest.java b/newrelic-security-agent/src/test/java/com/newrelic/agent/security/instrumentator/httpclient/RestRequestProcessorTest.java new file mode 100644 index 000000000..69e421c24 --- /dev/null +++ b/newrelic-security-agent/src/test/java/com/newrelic/agent/security/instrumentator/httpclient/RestRequestProcessorTest.java @@ -0,0 +1,43 @@ +package com.newrelic.agent.security.instrumentator.httpclient; + +import com.newrelic.agent.security.AgentConfig; +import com.newrelic.agent.security.AgentInfo; +import com.newrelic.agent.security.intcodeagent.filelogging.FileLoggerThreadPool; +import com.newrelic.agent.security.intcodeagent.models.javaagent.IntCodeControlCommand; +import org.junit.Assert; + +import org.junit.Test; +import org.mockito.Mockito; +import java.util.Arrays; + +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.doReturn; + +public class RestRequestProcessorTest { + + @Test + public void reqProcessingTest() throws InterruptedException { + // controlCommand size is less than 2 + IntCodeControlCommand cc = Mockito.mock(IntCodeControlCommand.class); + Assert.assertTrue(new RestRequestProcessor(cc, 1).call()); + + Mockito.verify(cc, atLeastOnce()).getArguments(); + Mockito.clearInvocations(cc); + Mockito.clearAllCaches(); + } + + @Test + public void reqProcessingFailTest() throws InterruptedException { + // fails in JSONProcessing since the fuzz request is invalid + AgentInfo.getInstance().setAgentActive(false); + + IntCodeControlCommand cc = Mockito.mock(IntCodeControlCommand.class); + doReturn(Arrays.asList("arg", "arg", "arg")).when(cc).getArguments(); + Assert.assertFalse(new RestRequestProcessor(cc, 1).call()); + + Mockito.verify(cc, atLeastOnce()).getArguments(); + Mockito.clearInvocations(cc); + Mockito.clearAllCaches(); + } + +} diff --git a/newrelic-security-agent/src/test/java/com/newrelic/agent/security/instrumentator/utils/AgentUtilsTest.java b/newrelic-security-agent/src/test/java/com/newrelic/agent/security/instrumentator/utils/AgentUtilsTest.java new file mode 100644 index 000000000..e31484afc --- /dev/null +++ b/newrelic-security-agent/src/test/java/com/newrelic/agent/security/instrumentator/utils/AgentUtilsTest.java @@ -0,0 +1,113 @@ +package com.newrelic.agent.security.instrumentator.utils; + +import com.newrelic.api.agent.NewRelic; +import com.newrelic.api.agent.security.schema.policy.AgentPolicy; +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Answers; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; + +public class AgentUtilsTest { + + @Test + public void applyPolicyOverrideIfApplicable(){ + Assert.assertFalse(AgentUtils.getInstance().applyPolicyOverrideIfApplicable()); + } + + @Test + public void applyPolicyOverrideIfApplicable1(){ + try (MockedStatic nrMock = Mockito.mockStatic(NewRelic.class, Answers.RETURNS_DEEP_STUBS)){ + nrMock.when(NewRelic.getAgent().getConfig().getValue(eq(INRSettingsKey.SECURITY_POLICY_ENFORCE), any())).thenReturn(false); + + Assert.assertFalse(AgentUtils.getInstance().applyPolicyOverrideIfApplicable()); + Assert.assertFalse(AgentUtils.getInstance().isPolicyOverridden()); + + + nrMock.reset(); + nrMock.clearInvocations(); + } + } + @Test + public void applyPolicyOverrideIfApplicable2(){ + try (MockedStatic nrMock = Mockito.mockStatic(NewRelic.class, Answers.RETURNS_DEEP_STUBS)){ + nrMock.when(NewRelic.getAgent().getConfig().getValue(eq(INRSettingsKey.SECURITY_POLICY_ENFORCE), any())).thenReturn(false); + nrMock.when(NewRelic.getAgent().getConfig().getValue(INRSettingsKey.SECURITY_POLICY_VULNERABILITY_SCAN_ENABLE)).thenReturn(false); + nrMock.when(NewRelic.getAgent().getConfig().getValue(INRSettingsKey.SECURITY_POLICY_VULNERABILITY_SCAN_IAST_SCAN_ENABLE)).thenReturn(false); + nrMock.when(NewRelic.getAgent().getConfig().getValue(INRSettingsKey.SECURITY_POLICY_VULNERABILITY_SCAN_IAST_SCAN_PROBING_INTERVAL)).thenReturn(1); + nrMock.when(NewRelic.getAgent().getConfig().getValue(INRSettingsKey.SECURITY_POLICY_VULNERABILITY_SCAN_IAST_SCAN_PROBING_BATCH_SIZE)).thenReturn(1); + nrMock.when(NewRelic.getAgent().getConfig().getValue(INRSettingsKey.SECURITY_POLICY_PROTECTION_MODE_ENABLE)).thenReturn(false); + nrMock.when(NewRelic.getAgent().getConfig().getValue(INRSettingsKey.SECURITY_POLICY_PROTECTION_MODE_IP_BLOCKING_ENABLE)).thenReturn(false); + nrMock.when(NewRelic.getAgent().getConfig().getValue(INRSettingsKey.SECURITY_POLICY_PROTECTION_MODE_IP_BLOCKING_ATTACKER_IP_BLOCKING)).thenReturn(false); + nrMock.when(NewRelic.getAgent().getConfig().getValue(INRSettingsKey.SECURITY_POLICY_PROTECTION_MODE_IP_BLOCKING_IP_DETECT_VIA_XFF)).thenReturn(false); + nrMock.when(NewRelic.getAgent().getConfig().getValue(INRSettingsKey.SECURITY_POLICY_PROTECTION_MODE_API_BLOCKING_ENABLE)).thenReturn(false); + nrMock.when(NewRelic.getAgent().getConfig().getValue(INRSettingsKey.SECURITY_POLICY_PROTECTION_MODE_API_BLOCKING_PROTECT_ALL_APIS)).thenReturn(false); + nrMock.when(NewRelic.getAgent().getConfig().getValue(INRSettingsKey.SECURITY_POLICY_PROTECTION_MODE_API_BLOCKING_PROTECT_KNOWN_VULNERABLE_APIS)).thenReturn(false); + nrMock.when(NewRelic.getAgent().getConfig().getValue(INRSettingsKey.SECURITY_POLICY_PROTECTION_MODE_API_BLOCKING_PROTECT_ATTACKED_APIS)).thenReturn(false); + + Assert.assertFalse(AgentUtils.getInstance().applyPolicyOverrideIfApplicable()); + Assert.assertFalse(AgentUtils.getInstance().isPolicyOverridden()); + + AgentPolicy policy = AgentUtils.getInstance().getAgentPolicy(); + Assert.assertTrue(policy.getVulnerabilityScan().getEnabled()); + Assert.assertTrue(policy.getVulnerabilityScan().getIastScan().getEnabled()); +// Assert.assertEquals(5, policy.getVulnerabilityScan().getIastScan().getProbing().getInterval().intValue()); +// Assert.assertEquals(50, policy.getVulnerabilityScan().getIastScan().getProbing().getBatchSize().intValue()); +// Assert.assertFalse(policy.getProtectionMode().getEnabled()); +// Assert.assertFalse(policy.getProtectionMode().getIpBlocking().getEnabled()); +// Assert.assertFalse(policy.getProtectionMode().getIpBlocking().getAttackerIpBlocking()); +// Assert.assertFalse(policy.getProtectionMode().getIpBlocking().getIpDetectViaXFF()); +// Assert.assertFalse(policy.getProtectionMode().getApiBlocking().getProtectAllApis()); +// Assert.assertFalse(policy.getProtectionMode().getApiBlocking().getProtectKnownVulnerableApis()); +// Assert.assertFalse(policy.getProtectionMode().getApiBlocking().getProtectAttackedApis()); + + nrMock.reset(); + nrMock.clearInvocations(); + } + } + @Test + public void applyPolicyOverrideIfApplicable3(){ +// try (MockedStatic nrMock = Mockito.mockStatic(NewRelic.class, Answers.RETURNS_DEEP_STUBS)){ +// nrMock.when(NewRelic.getAgent().getConfig().getValue(eq(INRSettingsKey.SECURITY_POLICY_ENFORCE), any())).thenReturn(true); +// nrMock.when(NewRelic.getAgent().getConfig().getValue(INRSettingsKey.SECURITY_POLICY_VULNERABILITY_SCAN_ENABLE)).thenReturn(true); +// nrMock.when(NewRelic.getAgent().getConfig().getValue(INRSettingsKey.SECURITY_POLICY_VULNERABILITY_SCAN_IAST_SCAN_ENABLE)).thenReturn(true); +// nrMock.when(NewRelic.getAgent().getConfig().getValue(INRSettingsKey.SECURITY_POLICY_VULNERABILITY_SCAN_IAST_SCAN_PROBING_INTERVAL)).thenReturn(10); +// nrMock.when(NewRelic.getAgent().getConfig().getValue(INRSettingsKey.SECURITY_POLICY_VULNERABILITY_SCAN_IAST_SCAN_PROBING_BATCH_SIZE)).thenReturn(10); +// nrMock.when(NewRelic.getAgent().getConfig().getValue(INRSettingsKey.SECURITY_POLICY_PROTECTION_MODE_ENABLE)).thenReturn(true); +// nrMock.when(NewRelic.getAgent().getConfig().getValue(INRSettingsKey.SECURITY_POLICY_PROTECTION_MODE_IP_BLOCKING_ENABLE)).thenReturn(true); +// nrMock.when(NewRelic.getAgent().getConfig().getValue(INRSettingsKey.SECURITY_POLICY_PROTECTION_MODE_IP_BLOCKING_ATTACKER_IP_BLOCKING)).thenReturn(true); +// nrMock.when(NewRelic.getAgent().getConfig().getValue(INRSettingsKey.SECURITY_POLICY_PROTECTION_MODE_IP_BLOCKING_IP_DETECT_VIA_XFF)).thenReturn(true); +// nrMock.when(NewRelic.getAgent().getConfig().getValue(INRSettingsKey.SECURITY_POLICY_PROTECTION_MODE_API_BLOCKING_ENABLE)).thenReturn(true); +// nrMock.when(NewRelic.getAgent().getConfig().getValue(INRSettingsKey.SECURITY_POLICY_PROTECTION_MODE_API_BLOCKING_PROTECT_ALL_APIS)).thenReturn(true); +// nrMock.when(NewRelic.getAgent().getConfig().getValue(INRSettingsKey.SECURITY_POLICY_PROTECTION_MODE_API_BLOCKING_PROTECT_KNOWN_VULNERABLE_APIS)).thenReturn(true); +// nrMock.when(NewRelic.getAgent().getConfig().getValue(INRSettingsKey.SECURITY_POLICY_PROTECTION_MODE_API_BLOCKING_PROTECT_ATTACKED_APIS)).thenReturn(true); +// +// Assert.assertFalse(AgentUtils.getInstance().applyPolicyOverrideIfApplicable()); +// Assert.assertTrue(AgentUtils.getInstance().isPolicyOverridden()); +// +// AgentPolicy policy = AgentUtils.getInstance().getAgentPolicy(); +// Assert.assertTrue(policy.getVulnerabilityScan().getEnabled()); +// Assert.assertTrue(policy.getVulnerabilityScan().getIastScan().getEnabled()); +// Assert.assertEquals(10, policy.getVulnerabilityScan().getIastScan().getProbing().getInterval().intValue()); +// Assert.assertEquals(10, policy.getVulnerabilityScan().getIastScan().getProbing().getBatchSize().intValue()); +// Assert.assertTrue(policy.getProtectionMode().getEnabled()); +// Assert.assertTrue(policy.getProtectionMode().getIpBlocking().getEnabled()); +// Assert.assertTrue(policy.getProtectionMode().getIpBlocking().getAttackerIpBlocking()); +// Assert.assertTrue(policy.getProtectionMode().getIpBlocking().getIpDetectViaXFF()); +// Assert.assertTrue(policy.getProtectionMode().getApiBlocking().getProtectAllApis()); +// Assert.assertTrue(policy.getProtectionMode().getApiBlocking().getProtectKnownVulnerableApis()); +// Assert.assertTrue(policy.getProtectionMode().getApiBlocking().getProtectAttackedApis()); +// +// nrMock.reset(); +// nrMock.clearInvocations(); +// } + } + + @Test + public void applyPolicy() { +// Assert.assertTrue(AgentUtils.applyPolicy(new AgentPolicy())); + } +} diff --git a/newrelic-security-agent/src/test/java/com/newrelic/agent/security/instrumentator/utils/CallbackUtilsTest.java b/newrelic-security-agent/src/test/java/com/newrelic/agent/security/instrumentator/utils/CallbackUtilsTest.java new file mode 100644 index 000000000..64b6fc028 --- /dev/null +++ b/newrelic-security-agent/src/test/java/com/newrelic/agent/security/instrumentator/utils/CallbackUtilsTest.java @@ -0,0 +1,109 @@ +package com.newrelic.agent.security.instrumentator.utils; + +import com.newrelic.api.agent.security.schema.HttpRequest; +import com.newrelic.api.agent.security.schema.HttpResponse; +import com.newrelic.api.agent.security.schema.StringUtils; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +public class CallbackUtilsTest { + + @Test + public void checkForReflectedXSSTest() { + HashSet expected = new HashSet<>(); + expected.add(""); + Assert.assertEquals(expected, CallbackUtils.checkForReflectedXSS(new HttpRequest(), new HttpResponse())); + } + + @Test + public void checkForReflectedXSS1Test() { + HashSet expected = new HashSet<>(); + expected.add(""); + Assert.assertEquals(expected, CallbackUtils.checkForReflectedXSS(new HttpRequest(), new HttpResponse())); + } + + @Test + public void checkForReflectedXSS2Test() { + HashSet expected = new HashSet<>(); + expected.add(""); + Assert.assertEquals(expected, CallbackUtils.checkForReflectedXSS(new HttpRequest(), new HttpResponse())); + } + + @Test + public void checkForReflectedXSS3Test() { + HashSet expected = new HashSet<>(); + expected.add(""); + HttpRequest request = new HttpRequest(); request.getHeaders().put("key","%3Cscript%3Ehello%3C%2Fscript%3E"); + request.setContentType("application/x-www-form-urlencoded"); + request.getBody().append("script%3D%3Cscript%3Ehello%3C%2Fscript%3E"); + + HttpResponse response = new HttpResponse(); response.getHeaders().put("key","%3Cscript%3Ehello%3C%2Fscript%3E"); + response.setResponseContentType("application/x-www-form-urlencoded"); + response.getResponseBody().append("script%3D%3Cscript%3Ehello%3C%2Fscript%3E"); + Assert.assertEquals(expected, CallbackUtils.checkForReflectedXSS(request, response)); + } + + @Test + public void checkForReflectedXSS_BodyJsonTest() { + HttpRequest request = new HttpRequest(); request.getHeaders().put("key","%3Cscript%3Ehello%3C%2Fscript%3E"); + request.setContentType("application/json"); + request.getBody().append("{\"script\":\"\"}"); + + HttpResponse response = new HttpResponse(); response.getHeaders().put("key","%3Cscript%3Ehello%3C%2Fscript%3E"); + response.setResponseContentType("application/xml"); + response.getResponseBody().append("{\"script\":\"\"}"); + Assert.assertEquals(Collections.singleton("'\\''"); + + HttpResponse response = new HttpResponse(); response.getHeaders().put("key","%3Cscript%3Ehello%3C%2Fscript%3E"); + response.setResponseContentType("application/xml"); + response.getResponseBody().append("'\\'''\\''"); + Assert.assertEquals(Collections.singleton(""); + Set expected = new HashSet<>(); + expected.add(""); + Set expected = new HashSet<>(); + expected.add("