Skip to content

Commit

Permalink
Merge pull request #354 from newrelic/release/v1.5.1
Browse files Browse the repository at this point in the history
CSEC Java Agent Release Version 1.5.1
  • Loading branch information
lovesh-ap authored Nov 9, 2024
2 parents 3873293 + 0f57b2f commit 4b5b84c
Show file tree
Hide file tree
Showing 23 changed files with 1,462 additions and 23 deletions.
28 changes: 28 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,34 @@ Noteworthy changes to the agent are documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.5.1] - 2024-11-9
### New features
- [PR-350](https://github.com/newrelic/csec-java-agent/pull/350) IAST support for CI/CD.
Configuration via yaml:
```yaml
security:
# This configuration allows users to specify a unique test identifier when running IAST Scan with CI/CD
iast_test_identifier: 'run-id'

scan_controllers:
# This configuration allows users to the number of application instances for a specific entity where IAST analysis is performed.
scan_instance_count: 0 # Values are 1 or 0, 0 signifies run on all application instances
```
- [PR-297](https://github.com/newrelic/csec-java-agent/pull/297), [PR-294](https://github.com/newrelic/csec-java-agent/pull/294), [PR-337](https://github.com/newrelic/csec-java-agent/pull/337) Detect route of an incoming request for Sun-Net-Httpserver, Netty Reactor, Apache Struts2 and Grails Framework. [NR-277771](https://new-relic.atlassian.net/browse/NR-277771), [NR-283914](https://new-relic.atlassian.net/browse/NR-283914), [NR-313390](https://new-relic.atlassian.net/browse/NR-313390), [NR-313392](https://new-relic.atlassian.net/browse/NR-313392)
- [PR-297](https://github.com/newrelic/csec-java-agent/pull/297), [PR-298](https://github.com/newrelic/csec-java-agent/pull/298) HTTP Response Detection in sun-net-httpserver and mule server [NR-277771](https://new-relic.atlassian.net/browse/NR-277771), [NR-277770](https://new-relic.atlassian.net/browse/NR-277770)
- [PR-335](https://github.com/newrelic/csec-java-agent/pull/335) Added request URI to application runtime error event, enhancing error logging and debugging capabilities. [NR-315194](https://new-relic.atlassian.net/browse/NR-315194)
- [PR-342](https://github.com/newrelic/csec-java-agent/pull/342) Report APM's trace.id and span.id in all outgoing events. [NR-321827](https://new-relic.atlassian.net/browse/NR-321827)
- [PR-347](https://github.com/newrelic/csec-java-agent/pull/347) Limiting the supported version range for GraalVM.JS, due to the new version release on Sep 17, 2024. [NR-332546](https://new-relic.atlassian.net/browse/NR-332546)
- [PR-347](https://github.com/newrelic/csec-java-agent/pull/347) Limiting the supported version range for Lettuce, due to the new version release on Oct 31, 2024. [NR-332546](https://new-relic.atlassian.net/browse/NR-332546)
### Fixes
- [PR-340](https://github.com/newrelic/csec-java-agent/pull/340) Detect correct user class in GraphQL [NR-319863](https://new-relic.atlassian.net/browse/NR-319863)
- [PR-339](https://github.com/newrelic/csec-java-agent/pull/339) Fix minor bug with exclude_from_iast_scan.header while parsing of header. [NR-319858](https://new-relic.atlassian.net/browse/NR-319858)
### Deprecations
- Status File Used for Debugging: This feature has been deprecated. All debugging capabilities have been moved to either Init Logging or [Error Inbox](https://docs.newrelic.com/docs/errors-inbox/errors-inbox/) and will be removed in a future agent release. [NR-293966](https://new-relic.atlassian.net/browse/NR-293966)
## [1.5.0] - 2024-9-25
### New features
- Json Version bump to 1.2.9.
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# The agent version.
agentVersion=1.5.0
agentVersion=1.5.1
jsonVersion=1.2.9
# Updated exposed NR APM API version.
nrAPIVersion=8.12.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public static AbstractOperation recordMongoOperation(BsonDocument command, Strin
if (NewRelicSecurity.isHookProcessingActive() &&
!NewRelicSecurity.getAgent().getSecurityMetaData().getRequest().isEmpty() && command != null) {
operation = new NoSQLOperation(command.toJson(), typeOfOperation, klassName, methodName);
NewRelicSecurity.getAgent().getSecurityMetaData().getMetaData().setFromJumpRequiredInStackTrace(3);
NewRelicSecurity.getAgent().registerOperation(operation);
}
} catch (Throwable e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ public static AbstractOperation recordMongoOperation(BsonDocument command, Strin
if (NewRelicSecurity.isHookProcessingActive() &&
!NewRelicSecurity.getAgent().getSecurityMetaData().getRequest().isEmpty() && command != null) {
operation = new NoSQLOperation(command.toJson(), typeOfOperation, klassName, methodName);
NewRelicSecurity.getAgent().getSecurityMetaData().getMetaData().setFromJumpRequiredInStackTrace(3);
NewRelicSecurity.getAgent().registerOperation(operation);
}
} catch (Throwable e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public static AbstractOperation recordMongoOperation(BsonDocument command, Strin
if (NewRelicSecurity.isHookProcessingActive() &&
!NewRelicSecurity.getAgent().getSecurityMetaData().getRequest().isEmpty() && command != null) {
operation = new NoSQLOperation(command.toJson(), typeOfOperation, klassName, methodName);
NewRelicSecurity.getAgent().getSecurityMetaData().getMetaData().setFromJumpRequiredInStackTrace(3);
NewRelicSecurity.getAgent().registerOperation(operation);
}
} catch (Throwable e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public static AbstractOperation recordMongoOperation(BsonDocument command, Strin
if (NewRelicSecurity.isHookProcessingActive() &&
!NewRelicSecurity.getAgent().getSecurityMetaData().getRequest().isEmpty() && command != null) {
operation = new NoSQLOperation(command.toJson(), typeOfOperation, klassName, methodName);
NewRelicSecurity.getAgent().getSecurityMetaData().getMetaData().setFromJumpRequiredInStackTrace(3);
NewRelicSecurity.getAgent().registerOperation(operation);
}
} catch (Throwable e) {
Expand Down
8 changes: 8 additions & 0 deletions instrumentation-security/solr-4.0.0/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ dependencies {
implementation("org.apache.httpcomponents:httpclient:4.1.3") {
transitive = false
}

testImplementation("org.testcontainers:solr:1.20.1")
testImplementation('org.eclipse.jetty:jetty-client:9.4.46.v20220331')
testImplementation('org.eclipse.jetty.http2:http2-client:9.4.46.v20220331')
testImplementation('org.eclipse.jetty.http2:http2-http-client-transport:9.4.46.v20220331')
testImplementation("org.apache.httpcomponents:httpmime:4.1.3")
testImplementation("org.apache.zookeeper:zookeeper:3.9.2")
testImplementation("org.noggit:noggit:0.8")
}

jar {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
package com.nr.agent.instrumentation.solr4;

import com.newrelic.agent.security.introspec.InstrumentationTestConfig;
import com.newrelic.agent.security.introspec.SecurityInstrumentationTestRunner;
import com.newrelic.api.agent.security.schema.AbstractOperation;
import com.newrelic.api.agent.security.schema.operation.SolrDbOperation;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.client.solrj.request.UpdateRequest;
import org.apache.solr.common.SolrInputDocument;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.utility.DockerImageName;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

@RunWith(SecurityInstrumentationTestRunner.class)
@InstrumentationTestConfig(includePrefixes = "org.apache.solr")
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SolrTest {

private static GenericContainer<?> solrServer;

private static HttpSolrServer solr;

private static final String CORE = "myCore";

private static String url;

private static final HashMap<String, String> params = new HashMap<>();

@BeforeClass
public static void setup() throws InterruptedException, IOException, SolrServerException {
int PORT = SecurityInstrumentationTestRunner.getIntrospector().getRandomPort();
url = String.format("http://localhost:%s/solr/%s", PORT, CORE);

solrServer = new GenericContainer<>(DockerImageName.parse("solr:8"));
solrServer.setPortBindings(Collections.singletonList(PORT + ":8983"));
solrServer.start();
solrServer.execInContainer("solr", "start");
solrServer.execInContainer("solr", "create", "-c", CORE);

solr = new HttpSolrServer(url);

solr.add(getDocument("ish", 4, "abc"));
solr.add(getDocument("ish", 5, "abc"));
solr.add(getDocument("ish", 6, "abc"));
params.put("waitSearcher", "true");
params.put("commit", "true");
params.put("softCommit", "false");
}

@AfterClass
public static void tearDown() {
if (solrServer != null){
solrServer.stop();
solrServer.close();
}
}

private static SolrInputDocument getDocument(String name, int id, String city) {
SolrInputDocument document = new SolrInputDocument();
document.addField("id", id);
document.addField("name", name);
document.addField("Phone No", Collections.singletonList("9876543210"));
document.addField("City", city);
return document;
}

@Test
public void addDocumentTest() throws SolrServerException, IOException {
SolrInputDocument document = getDocument("Ishi", 1, "Pune");
solr.add(document);
solr.commit();
assertSolrOperation("POST", "/update", document);
}

@Test
public void addMultiDocumentsTest() throws SolrServerException, IOException {
SolrInputDocument document1 = getDocument("Harry", 2, "Hogwarts");
SolrInputDocument document2 = getDocument("Ron", 3, "Mumbai");
solr.add(document1);
solr.add(document2);
solr.commit();
assertSolrOperation("POST", "/update", document1, document2);
}

@Test
public void updateDocument1Test() throws SolrServerException, IOException {
SolrInputDocument document = getDocument("Ron", 3, "Hogwarts");
UpdateRequest request = new UpdateRequest();
request.setAction(UpdateRequest.ACTION.COMMIT, false, true);
request.add(document);
request.process(solr);
assertSolrOperation("POST", "/update", document);
}

@Test
public void updateDocument2Test() throws SolrServerException, IOException {
SolrInputDocument document = getDocument("Ron", 3, "Hogwarts");
UpdateRequest request = new UpdateRequest();
request.setAction(UpdateRequest.ACTION.COMMIT, false, true, false);
request.add(document);
solr.request(request);
assertSolrOperation("POST", "/update", document);
}

@Test
public void deleteDocument1Test() throws SolrServerException, IOException {
solr.deleteById("1");
assertSolrOperation("POST", "/update");
}

@Test
public void deleteDocument2Test() throws SolrServerException, IOException {
UpdateRequest request = new UpdateRequest();
request.deleteById("1");
request.process(solr);
assertSolrOperation("POST", "/update");
}

@Test
public void deleteDocument3Test() throws SolrServerException, IOException {
UpdateRequest request = new UpdateRequest();
request.deleteByQuery("City:abc");
request.process(solr);
assertSolrOperation("POST", "/update");
}

@Test
public void zQueryDataTest() throws SolrServerException, IOException {
SolrQuery query = new SolrQuery();
query.setQuery("*:*");
query.addField("*");

params.clear();
params.put("q", "*:*");
params.put("fl", "*");

solr.query(query);
assertSolrOperation("GET", "/select");
}

@Test
public void zQueryData2Test() throws SolrServerException, IOException {
SolrQuery query = new SolrQuery();
query.set("q", "City:abc");
query.addField("id");

solr.query(query);
params.clear();
params.put("q", "City:abc");
params.put("fl", "id");
assertSolrOperation("GET", "/select");
}

@Test
public void zQueryData3Test() throws SolrServerException, IOException {
SolrQuery query = new SolrQuery();
query.set("q", "id:1");
query.addField("*");
query.addFacetQuery("City");
solr.query(query);

params.clear();
params.put("q", "id:1");
params.put("fl", "*");
params.put("facet", "true");
params.put("facet.query", "City");
assertSolrOperation("GET", "/select");
}

@Test
public void pingTest() throws SolrServerException, IOException {
solr.ping();
assertSolrOperation("GET", "/admin/ping");
}


private void assertSolrOperation(String method, String path, SolrInputDocument... docs){
List<AbstractOperation> operations = SecurityInstrumentationTestRunner.getIntrospector().getOperations();
Assert.assertNotNull(operations);
int i = 0;
Assert.assertFalse(operations.isEmpty());
for (AbstractOperation op : operations) {
Assert.assertTrue(op instanceof SolrDbOperation);
SolrDbOperation operation = (SolrDbOperation) op;

// TODO: discuss collection definition in instrumentation
Assert.assertEquals("solr/"+ CORE, operation.getCollection());

Assert.assertEquals(method, operation.getMethod());
Assert.assertEquals(path, operation.getPath());
Assert.assertEquals(url, operation.getConnectionURL());
if (operation.getDocuments() != null && !operation.getDocuments().isEmpty()) {
Assert.assertEquals(docs[i].size(), ((SolrInputDocument)(operation.getDocuments().get(0))).size());
Assert.assertEquals(docs[i], operation.getDocuments().get(0));
++i;
}
if (operation.getParams() != null && !operation.getParams().isEmpty()) {
Assert.assertEquals(SolrTest.params.size(), operation.getParams().size());
Assert.assertEquals(SolrTest.params, operation.getParams());
}
}
}
}
8 changes: 8 additions & 0 deletions instrumentation-security/solr-5.0.0/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ dependencies {
implementation("org.apache.httpcomponents:httpclient:4.3.1") {
transitive = false
}

testImplementation("org.testcontainers:solr:1.20.1")
testImplementation('org.eclipse.jetty:jetty-client:9.4.46.v20220331')
testImplementation('org.eclipse.jetty.http2:http2-client:9.4.46.v20220331')
testImplementation('org.eclipse.jetty.http2:http2-http-client-transport:9.4.46.v20220331')
testImplementation("org.apache.httpcomponents:httpmime:4.1.3")
testImplementation("org.apache.zookeeper:zookeeper:3.9.2")
testImplementation("org.noggit:noggit:0.8")
}

jar {
Expand Down
Loading

0 comments on commit 4b5b84c

Please sign in to comment.