Skip to content

Commit

Permalink
Merge pull request #288 from newrelic/release/v1.4.0
Browse files Browse the repository at this point in the history
CSEC Java Agent Release Target 1.4.0
  • Loading branch information
lovesh-ap authored Jun 24, 2024
2 parents c66c1ef + e402cd0 commit 76aeff3
Show file tree
Hide file tree
Showing 42 changed files with 3,602 additions and 37 deletions.
21 changes: 21 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,27 @@ 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.4.0] - 2024-6-24
### Changes
- Json Version bump to 1.2.3 due to [NR-254157](https://new-relic.atlassian.net/browse/NR-254157) implementation.
- [PR-260](https://github.com/newrelic/csec-java-agent/pull/260) SpyMemcached Support : The security agent now also supports SpyMemcached Version 2.12.0 and above. [NR-171576](https://new-relic.atlassian.net/browse/NR-171576)
- [PR-241](https://github.com/newrelic/csec-java-agent/pull/241) Vertx-Web Support : The security agent now also supports Vertx-Web Version 3.2.0 and above. [NR-254180](https://new-relic.atlassian.net/browse/NR-254180), [NR-254181](https://new-relic.atlassian.net/browse/NR-254181), [NR-254182](https://new-relic.atlassian.net/browse/NR-254182)
- [PR-245](https://github.com/newrelic/csec-java-agent/pull/245) Vert.x-Core Support : The security agent now also supports Vert.x-Core Version 3.3.0 and above. [NR-254146](https://new-relic.atlassian.net/browse/NR-254146), [NR-254156](https://new-relic.atlassian.net/browse/NR-254156)
- [PR-254](https://github.com/newrelic/csec-java-agent/pull/254) API Endpoint detection support for Netty Reactor Server. [NR-267158](https://new-relic.atlassian.net/browse/NR-267158)
- [PR-269](https://github.com/newrelic/csec-java-agent/pull/269), [PR-261](https://github.com/newrelic/csec-java-agent/pull/261) Functionality to report NPE, Uncaught exceptions And 5xx Errors. [NR-273711](https://new-relic.atlassian.net/browse/NR-273711), [NR-277763](https://new-relic.atlassian.net/browse/NR-277763)
- [PR-267](https://github.com/newrelic/csec-java-agent/pull/267) Implement Fallback mechanism for route detection of an incoming request [NR-273607](https://new-relic.atlassian.net/issues/NR-273607)
- [PR-256](https://github.com/newrelic/csec-java-agent/pull/256), [PR-259](https://github.com/newrelic/csec-java-agent/pull/259), [PR-258](https://github.com/newrelic/csec-java-agent/pull/258) Feature to detect route of an incoming request for Jax-RS and Spring Framework. [NR-265913](https://new-relic.atlassian.net/browse/NR-265913), [NR-261653](https://new-relic.atlassian.net/browse/NR-261653), [NR-273605](https://new-relic.atlassian.net/browse/NR-273605)
- [PR-126](https://github.com/newrelic/csec-java-agent/pull/126), [PR-127](https://github.com/newrelic/csec-java-agent/pull/127), [PR-128](https://github.com/newrelic/csec-java-agent/pull/128), [PR-129](https://github.com/newrelic/csec-java-agent/pull/129) Jedis Support : The security agent now also supports Jedis Version 1.4.0 and above. [NR-174176](https://new-relic.atlassian.net/browse/NR-174176)
- [PR-287](https://github.com/newrelic/csec-java-agent/pull/287) Support for Proxy Settings for Connecting to the Security Engine, with known limitation of missing Authentication capabilities.
### Fixes
- [PR-255](https://github.com/newrelic/csec-java-agent/pull/255) Handle InvalidPathException thrown by Paths.get method [NR-262452](https://new-relic.atlassian.net/browse/)
- [PR-216](https://github.com/newrelic/csec-java-agent/pull/216) Extract Server Configuration to resolve IAST localhost connection with application for Glassfish Server. [NR-223808](https://new-relic.atlassian.net/browse/NR-223808)
- [PR-214](https://github.com/newrelic/csec-java-agent/pull/214) Extract Server Configuration to resolve IAST localhost connection with application for Weblogic Server. [NR-223809](https://new-relic.atlassian.net/browse/NR-223809)
- [PR-242](https://github.com/newrelic/csec-java-agent/pull/242) Fix for User Class detection in Play Framework [NR-264101](https://new-relic.atlassian.net/browse/NR-264101)
- [PR-268](https://github.com/newrelic/csec-java-agent/pull/268) Fix for Play Framework Application Crash. [NR-273623](https://new-relic.atlassian.net/browse/NR-273623)
- [PR-271](https://github.com/newrelic/csec-java-agent/pull/271) Remove hard dependency of Newrelic API. [NR-278213](https://new-relic.atlassian.net/browse/NR-278213)
- [PR-272](https://github.com/newrelic/csec-java-agent/pull/272) Fix for missing File Vulnerability as Event was not generated by CSEC Java Agent. [NR-278211](https://new-relic.atlassian.net/browse/NR-278211)

## [1.3.0] - 2024-5-16
### Changes
- [PR-186](https://github.com/newrelic/csec-java-agent/pull/186) Feature to detect API Endpoint of the Application [NR-222163](https://new-relic.atlassian.net/browse/NR-222163)
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ The agent automatically instruments the following frameworks.
- Spray HTTP 1.3.1 to latest (with scala 2.11 and above)
- Netty Server 4.0.0.Final to latest
- Netty Reactor Server 0.7.0.RELEASE to latest
- Vertx web 3.2.0 to latest

** IAST for **gRPC** requires the dependency [protobuf-java-util](https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java-util) for IAST request replay.

Expand Down Expand Up @@ -75,6 +76,7 @@ The agent automatically instruments the following HTTP clients and messaging ser
- Akka Client 10.0 to latest (with scala 2.11 and above)
- Spray Can Client 1.3.1 to latest (with scala 2.11 and above)
- Spring WebClient 5.0.0.RELEASE to latest
- Vertx Core 3.3.0 to latest

### Datastores

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.3.1
agentVersion=1.4.0
jsonVersion=1.2.3
# Updated exposed NR APM API version.
nrAPIVersion=8.12.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,16 @@ public void testAPIEndpoint() {
Iterator<ApplicationURLMapping> mapping = mappings.iterator();
String path = "/users";

Assert.assertTrue(mapping.hasNext());
assertMapping("*", "/customers/orders/*", CustomerLocatorResource.class.getName(), mapping.next());

Assert.assertTrue(mapping.hasNext());
assertMapping("POST", path, handler, mapping.next());

Assert.assertTrue(mapping.hasNext());
assertMapping("GET", path, handler, mapping.next());

Assert.assertTrue(mapping.hasNext());
assertMapping("PUT", path, handler, mapping.next());

Assert.assertTrue(mapping.hasNext());
assertMapping("GET", path +"/count", handler, mapping.next());

while (mapping.hasNext()){
ApplicationURLMapping urlMapping = mapping.next();
if (urlMapping.getPath().equals("/customers/orders/*")){
assertMapping("*", "/customers/orders/*", CustomerLocatorResource.class.getName(), urlMapping);
} else if (urlMapping.getPath().equals(path +"/count")){
assertMapping("GET", path +"/count", handler, urlMapping);
} else {
assertMapping(urlMapping.getMethod(), path, handler, urlMapping);
}
}
}

private void assertMapping(String method, String path, String handler, ApplicationURLMapping actualMapping) {
Expand Down
27 changes: 27 additions & 0 deletions instrumentation-security/glassfish/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
dependencies {
implementation(project(":newrelic-security-api"))
implementation("com.newrelic.agent.java:newrelic-api:${nrAPIVersion}")
implementation("com.newrelic.agent.java:newrelic-weaver-api:${nrAPIVersion}")

implementation("jakarta.servlet:jakarta.servlet-api:4.0.4")
implementation("org.glassfish.main.web:web-core:5.1.0")
implementation("org.eclipse.persistence:javax.persistence:2.2.1")
}

jar {
manifest { attributes 'Implementation-Title': 'com.newrelic.instrumentation.security.glassfish' }
}

verifyInstrumentation {
// maven-metadata.xml for this artifact only shows the latest version.
// This is the file that's read when trying to resolve a range of versions, such as [3.0,6.0).
// Therefore, range-based versions will not work here.
passes 'org.glassfish.main.web:web-core:[3.1.2,)'
excludeRegex 'org.glassfish.main.web:web-core:.*(RC|M)[0-9]*$'
}

site {
title 'Glassfish'
type 'Appserver'
versionOverride '[3.0,6.0)'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
*
* * Copyright 2020 New Relic Corporation. All rights reserved.
* * SPDX-License-Identifier: Apache-2.0
*
*/

package org.apache.catalina.connector;

import com.newrelic.api.agent.security.NewRelicSecurity;
import com.newrelic.api.agent.weaver.MatchType;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.Weaver;

@Weave(type = MatchType.ExactClass, originalName = "org.apache.catalina.connector.Connector")
public abstract class Connector_Instrumentation {

public void start() {

NewRelicSecurity.getAgent().setApplicationConnectionConfig(getPort(), getScheme());
Weaver.callOriginal();
}

public abstract int getPort();

public abstract String getScheme();
}
23 changes: 23 additions & 0 deletions instrumentation-security/jedis-1.4.0/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
jar {
manifest { attributes 'Implementation-Title': 'com.newrelic.instrumentation.security.jedis-1.4.0' }
}

dependencies {
implementation(project(":newrelic-security-api"))
implementation("com.newrelic.agent.java:newrelic-api:${nrAPIVersion}")
implementation("com.newrelic.agent.java:newrelic-weaver-api:${nrAPIVersion}")
implementation("redis.clients:jedis:1.4.0")
testImplementation('org.testcontainers:testcontainers:1.17.1')
}

verifyInstrumentation {
passesOnly 'redis.clients:jedis:[1.4.0,3.0.0)'
exclude 'redis.clients:jedis:2.7.1'
exclude 'redis.clients:jedis:2.7.2'
excludeRegex 'redis.clients:jedis:.*-(m|rc|RC)[0-9]*'
}

site {
title 'Jedis'
type 'Datastore'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.newrelic.agent.security.instrumentation.jedis_1_4_0;

import com.newrelic.api.agent.security.NewRelicSecurity;
import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper;
import com.newrelic.api.agent.security.schema.AbstractOperation;
import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException;
import com.newrelic.api.agent.security.schema.operation.RedisOperation;

import java.util.List;

public class JedisHelper {
public static final String NR_SEC_LOCK_ATTRIB_NAME = "JEDIS_OPERATION_LOCK_";
public static AbstractOperation preprocessSecurityHook(String command, List<Object> args, String klass, String method) {
try {
if (!NewRelicSecurity.isHookProcessingActive() || NewRelicSecurity.getAgent().getSecurityMetaData().getRequest().isEmpty()){
return null;
}
RedisOperation operation = new RedisOperation(klass, method, command, args);
NewRelicSecurity.getAgent().registerOperation(operation);
return operation;
} catch (Throwable e) {
e.printStackTrace();
if (e instanceof NewRelicSecurityException) {
throw e;
}
}
return null;
}

public static void registerExitOperation(boolean isProcessingAllowed, AbstractOperation operation) {
try {
if (operation == null || !isProcessingAllowed || !NewRelicSecurity.isHookProcessingActive() ||
NewRelicSecurity.getAgent().getSecurityMetaData().getRequest().isEmpty()) {
return;
}
NewRelicSecurity.getAgent().registerExitEvent(operation);
} catch (Throwable ignored){}
}

public static void releaseLock(int hashCode) {
try {
GenericHelper.releaseLock(NR_SEC_LOCK_ATTRIB_NAME, hashCode);
} catch (Throwable ignored) {}
}

public static boolean acquireLockIfPossible(int hashCode) {
try {
return GenericHelper.acquireLockIfPossible(NR_SEC_LOCK_ATTRIB_NAME, hashCode);
} catch (Throwable ignored) {}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package redis.clients.jedis;

import com.newrelic.agent.security.instrumentation.jedis_1_4_0.JedisHelper;
import com.newrelic.api.agent.security.NewRelicSecurity;
import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper;
import com.newrelic.api.agent.security.schema.AbstractOperation;
import com.newrelic.api.agent.weaver.MatchType;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.Weaver;

import java.util.ArrayList;
import java.util.List;

@Weave(type = MatchType.BaseClass, originalName = "redis.clients.jedis.Connection")
public abstract class Connection_Instrumentation {
protected Connection sendCommand(final Protocol.Command cmd, final byte[]... args) {
boolean isLockAcquired = JedisHelper.acquireLockIfPossible(cmd.hashCode());
AbstractOperation operation = null;
if(isLockAcquired && args != null) {
List<Object> argList = new ArrayList<>();
for (byte[] arg : args) {
Object dataByBytes = NewRelicSecurity.getAgent()
.getSecurityMetaData()
.getCustomAttribute(GenericHelper.NR_SEC_CUSTOM_SPRING_REDIS_ATTR + arg.hashCode(), Object.class);

if (dataByBytes != null) {
argList.add(dataByBytes);
} else {
argList.add(new String(arg));
}
}
operation = JedisHelper.preprocessSecurityHook(cmd.name(), argList, this.getClass().getName(), "sendCommand");
}
Connection returnValue = null;
try {
returnValue = Weaver.callOriginal();
} finally {
if (isLockAcquired) {
JedisHelper.releaseLock(cmd.hashCode());
}
}
JedisHelper.registerExitOperation(isLockAcquired, operation);
return returnValue;
}
}
Loading

0 comments on commit 76aeff3

Please sign in to comment.