Skip to content

Commit

Permalink
Merge pull request #252 from newrelic/release/v1.3.0
Browse files Browse the repository at this point in the history
Release CSEC Java Agent Version 1.3.0
  • Loading branch information
lovesh-ap authored May 17, 2024
2 parents 11ac210 + a280632 commit 132cf79
Show file tree
Hide file tree
Showing 269 changed files with 6,676 additions and 396 deletions.
29 changes: 29 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,35 @@ 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.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)
- [PR-132](https://github.com/newrelic/csec-java-agent/pull/132) JCache Support : The security agent now also supports jCache 1.0.0 and above [NR-175383](https://new-relic.atlassian.net/browse/NR-175383)
- [PR-193](https://github.com/newrelic/csec-java-agent/pull/193) Spray HTTP Server Support : The security agent now also supports Spray HTTP Server version 1.3.1 and above (with scala 2.11 and above) [NR-230246](https://new-relic.atlassian.net/browse/NR-230246), [NR-230248](https://new-relic.atlassian.net/browse/NR-230248)
- [PR-195](https://github.com/newrelic/csec-java-agent/pull/195) Spray Can Server Support : The security agent now also supports Spray Can Server version 1.3.1 and above (with scala 2.11 and above) [NR-230246](https://new-relic.atlassian.net/browse/NR-230246), [NR-230248](https://new-relic.atlassian.net/browse/NR-230248)
- [PR-194](https://github.com/newrelic/csec-java-agent/pull/194) Spray Client Support : The security agent now also supports Spray Client version 1.3.1 and above (with scala 2.11 and above) [NR-230243](https://new-relic.atlassian.net/browse/NR-230243), [NR-230245](https://new-relic.atlassian.net/browse/NR-230245)
- [PR-202](https://github.com/newrelic/csec-java-agent/pull/202) Netty Server support : The security agent now also supports Netty Server version 4.0.0.Final and above. [NR-234864](https://new-relic.atlassian.net/browse/NR-234864)
- [PR-220](https://github.com/newrelic/csec-java-agent/pull/220) Netty Reactor Server support : The security agent now also supports Netty Reactor Server version 0.7.0.RELEASE and above. [NR-249812](https://new-relic.atlassian.net/browse/NR-249812)
- [PR-239](https://github.com/newrelic/csec-java-agent/pull/239) Spring WebClient Support : The security agent now also supports Spring WebClient version 5.0.0.RELEASE and above. [NR-258894](https://new-relic.atlassian.net/browse/NR-258894), [NR-258895](https://new-relic.atlassian.net/browse/NR-258895)
- [PR-219](https://github.com/newrelic/csec-java-agent/pull/219) Enable functionality to scan NewRelic applications using `security.is_home_app` config, default value is false
- [PR-217](https://github.com/newrelic/csec-java-agent/pull/217) Revamp user class detection technique, use server level endpoints. [NR-211161](https://new-relic.atlassian.net/browse/NR-211161)
- Resin Support : The security agent now also supports resin server [NR-171577](https://new-relic.atlassian.net/browse/NR-171577)
- Anorm Support : The security agent now also supports Anorm Datastore version 2.0 to 2.5 [NR-171575](https://new-relic.atlassian.net/browse/NR-171575)

### Fixes
- [PR-202](https://github.com/newrelic/csec-java-agent/pull/202) Extract Server Configuration to resolve IAST localhost connection with application for Netty server. [NR-238324](https://new-relic.atlassian.net/browse/NR-238324)
- [PR-237](https://github.com/newrelic/csec-java-agent/pull/237) Fix for Correct User Class Detection in Sun-Net-HttpServer [NR-254564](https://new-relic.atlassian.net/browse/NR-254564)
- [PR-243](https://github.com/newrelic/csec-java-agent/pull/243) Improvement in fallback mechanism for NR_CSEC_HOME [NR-260723](https://new-relic.atlassian.net/browse/NR-260723)
- [PR-248](https://github.com/newrelic/csec-java-agent/pull/248) Fix for Regression in File Integrity Event Generation [NR-267172](https://new-relic.atlassian.net/browse/NR-267172)
- [PR-249](https://github.com/newrelic/csec-java-agent/pull/249), [PR-244](https://github.com/newrelic/csec-java-agent/pull/244) Improvements in IAST Replay [NR-267169](https://new-relic.atlassian.net/browse/NR-267169), [NR-265208](https://new-relic.atlassian.net/browse/NR-265208)
- [PR-235](https://github.com/newrelic/csec-java-agent/pull/235) Fix for NullPointerException observed in JDBC-GENERIC [NR-232657](https://new-relic.atlassian.net/browse/NR-232657)
- [PR-226](https://github.com/newrelic/csec-java-agent/pull/226) Fix for NoClassDefFoundError observed in JAVAX-JNDI Instrumentation [NR-254566](https://new-relic.atlassian.net/browse/NR-254566)
- [PR-225](https://github.com/newrelic/csec-java-agent/pull/225) Fix for FileAlreadyExistException observed in IAST Replay [NR-254565](https://new-relic.atlassian.net/browse/NR-254565)
- [PR-222](https://github.com/newrelic/csec-java-agent/pull/222) Exclude Milestone Release for Jax-RS, due to release of version 4.0.0-M2 on 9th March 2024 [NR-256459](https://new-relic.atlassian.net/browse/NR-256459)
- [PR-232](https://github.com/newrelic/csec-java-agent/pull/232) Exclude Latest Release version 12.7.0 for mssql-jdbc released on 08th April 2024 [NR-256461](https://new-relic.atlassian.net/browse/NR-256461)
- [PR-247](https://github.com/newrelic/csec-java-agent/pull/247) Exclude Latest Release version 1.7.14 for Rhino-JS-Engine released on 29th April 2024 [NR-265206](https://new-relic.atlassian.net/browse/NR-265206)
- [PR-219](https://github.com/newrelic/csec-java-agent/pull/219) Fixed an issue where lambda functions were causing class circularity errors [NR-239192](https://new-relic.atlassian.net/browse/NR-239192)

## [1.2.1] - 2024-4-19
### Fixes
- [NR-259467](https://new-relic.atlassian.net/browse/NR-259467) Fix issue of nested event generation from CSEC's agent itself [PR-230](https://github.com/newrelic/csec-java-agent/pull/230)
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ The agent automatically instruments the following frameworks.
- Mule ESB 3.6 to 3.9.x
- gRPC 1.4.0 to latest**
- Jersey 2.0 to latest
- Akka Server 10.0 to latest (with scala 2.11 and above)
- Spray Can 1.3.1 to latest (with scala 2.11 and above)
- Akka HTTP Server 10.0 to latest (with scala 2.11 and above)
- 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

** 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 @@ -66,6 +72,9 @@ The agent automatically instruments the following HTTP clients and messaging ser
- Xalan XPATH 2.1.0 to latest
- Async Http Client from 2.0 to latest
- Ning Async HTTP Client 1.0.0 to latest
- 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

### 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.2.1
agentVersion=1.3.0
jsonVersion=1.2.1
# Updated exposed NR APM API version.
nrAPIVersion=8.4.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.newrelic.api.agent.Token;
import com.newrelic.api.agent.security.NewRelicSecurity;
import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper;
import com.newrelic.api.agent.security.instrumentation.helpers.ICsecApiConstants;
import com.newrelic.api.agent.security.instrumentation.helpers.LowSeverityHelper;
import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper;
import com.newrelic.api.agent.security.schema.AgentMetaData;
Expand Down Expand Up @@ -61,7 +62,7 @@ public static boolean acquireServletLockIfPossible() {
public static void postProcessHttpRequest(Boolean isServletLockAcquired, StringBuilder responseBody, String contentType, String className, String methodName, Token token) {
try {
token.linkAndExpire();
if(!isServletLockAcquired || !NewRelicSecurity.isHookProcessingActive()){
if(!isServletLockAcquired || !NewRelicSecurity.isHookProcessingActive() || Boolean.TRUE.equals(NewRelicSecurity.getAgent().getSecurityMetaData().getCustomAttribute("RXSS_PROCESSED", Boolean.class))){
return;
}
NewRelicSecurity.getAgent().getSecurityMetaData().getResponse().setResponseContentType(contentType);
Expand Down Expand Up @@ -123,7 +124,7 @@ public static void preProcessHttpRequest (Boolean isServletLockAcquired, HttpReq
try {
queryString = httpRequest.getUri().rawQueryString().get();
} catch (NoSuchElementException ignored) {
// ignore NoSuchElementException there is no value present in rawQueryString
// ignore NoSuchElementException there is no value present in rawQueryString
} finally {
if (queryString != null && !queryString.trim().isEmpty()) {
securityRequest.setUrl(securityRequest.getUrl() + QUESTION_MARK + queryString);
Expand Down Expand Up @@ -180,6 +181,9 @@ public static void processHttpRequestHeader(HttpRequest request, com.newrelic.ap
} else if(GenericHelper.CSEC_PARENT_ID.equals(headerKey)) {
NewRelicSecurity.getAgent().getSecurityMetaData()
.addCustomAttribute(GenericHelper.CSEC_PARENT_ID, request.getHeader(headerKey).get().value());
} else if (ICsecApiConstants.NR_CSEC_JAVA_HEAD_REQUEST.equals(headerKey)) {
NewRelicSecurity.getAgent().getSecurityMetaData()
.addCustomAttribute(ICsecApiConstants.NR_CSEC_JAVA_HEAD_REQUEST, true);
}
String headerFullValue = nextHeader.value();
if (headerFullValue != null && !headerFullValue.trim().isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.newrelic.api.agent.Token;
import com.newrelic.api.agent.security.NewRelicSecurity;
import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper;
import com.newrelic.api.agent.security.instrumentation.helpers.ICsecApiConstants;
import com.newrelic.api.agent.security.instrumentation.helpers.LowSeverityHelper;
import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper;
import com.newrelic.api.agent.security.schema.AgentMetaData;
Expand Down Expand Up @@ -183,6 +184,9 @@ public static void processHttpRequestHeader(HttpRequest request, com.newrelic.ap
} else if(GenericHelper.CSEC_PARENT_ID.equals(headerKey)) {
NewRelicSecurity.getAgent().getSecurityMetaData()
.addCustomAttribute(GenericHelper.CSEC_PARENT_ID, request.getHeader(headerKey).get().value());
} else if (ICsecApiConstants.NR_CSEC_JAVA_HEAD_REQUEST.equals(headerKey)) {
NewRelicSecurity.getAgent().getSecurityMetaData()
.addCustomAttribute(ICsecApiConstants.NR_CSEC_JAVA_HEAD_REQUEST, true);
}
String headerFullValue = nextHeader.value();
if (headerFullValue != null && !headerFullValue.trim().isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.newrelic.api.agent.Token;
import com.newrelic.api.agent.security.NewRelicSecurity;
import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper;
import com.newrelic.api.agent.security.instrumentation.helpers.ICsecApiConstants;
import com.newrelic.api.agent.security.instrumentation.helpers.LowSeverityHelper;
import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper;
import com.newrelic.api.agent.security.schema.AgentMetaData;
Expand Down Expand Up @@ -183,6 +184,9 @@ public static void processHttpRequestHeader(HttpRequest request, com.newrelic.ap
} else if(GenericHelper.CSEC_PARENT_ID.equals(headerKey)) {
NewRelicSecurity.getAgent().getSecurityMetaData()
.addCustomAttribute(GenericHelper.CSEC_PARENT_ID, request.getHeader(headerKey).get().value());
} else if (ICsecApiConstants.NR_CSEC_JAVA_HEAD_REQUEST.equals(headerKey)) {
NewRelicSecurity.getAgent().getSecurityMetaData()
.addCustomAttribute(ICsecApiConstants.NR_CSEC_JAVA_HEAD_REQUEST, true);
}
String headerFullValue = nextHeader.value();
if (headerFullValue != null && !headerFullValue.trim().isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.newrelic.api.agent.Token;
import com.newrelic.api.agent.security.NewRelicSecurity;
import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper;
import com.newrelic.api.agent.security.instrumentation.helpers.ICsecApiConstants;
import com.newrelic.api.agent.security.instrumentation.helpers.LowSeverityHelper;
import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper;
import com.newrelic.api.agent.security.schema.AgentMetaData;
Expand Down Expand Up @@ -193,6 +194,9 @@ public static void processHttpRequestHeader(HttpRequest request, com.newrelic.ap
} else if(GenericHelper.CSEC_PARENT_ID.equals(headerKey)) {
NewRelicSecurity.getAgent().getSecurityMetaData()
.addCustomAttribute(GenericHelper.CSEC_PARENT_ID, request.getHeader(headerKey).get().value());
} else if (ICsecApiConstants.NR_CSEC_JAVA_HEAD_REQUEST.equals(headerKey)) {
NewRelicSecurity.getAgent().getSecurityMetaData()
.addCustomAttribute(ICsecApiConstants.NR_CSEC_JAVA_HEAD_REQUEST, true);
}
String headerFullValue = nextHeader.value();
if (headerFullValue != null && !headerFullValue.trim().isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.nr.instrumentation.security.apache.struts2;
package com.newrelic.agent.security.instrumentation.apache.struts2;

import com.newrelic.api.agent.security.schema.ApplicationURLMapping;
import com.newrelic.api.agent.security.instrumentation.helpers.*;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import com.newrelic.api.agent.weaver.MatchType;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.Weaver;
import com.nr.instrumentation.security.apache.struts2.StrutsHelper;
import com.newrelic.agent.security.instrumentation.apache.struts2.StrutsHelper;
import java.util.List;

@Weave(type = MatchType.Interface, originalName = "com.opensymphony.xwork2.config.Configuration")
Expand Down
22 changes: 22 additions & 0 deletions instrumentation-security/apache-tomcat-10/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
dependencies {
implementation(project(":newrelic-security-api"))
implementation("com.newrelic.agent.java:newrelic-weaver-api:${nrAPIVersion}")
implementation("com.newrelic.agent.java:newrelic-api:${nrAPIVersion}")
implementation("org.apache.tomcat.embed:tomcat-embed-core:10.0.0")
implementation("org.apache.tomcat:tomcat-juli:10.0.0")
}

jar {
manifest { attributes 'Implementation-Title': 'com.newrelic.instrumentation.security.apache-tomcat-10' }
}

verifyInstrumentation {
passesOnly('org.apache.tomcat.embed:tomcat-embed-core:[10.0.0-M1,)')
fails('org.apache.tomcat.embed:tomcat-embed-core:[7.0.0,10.0.0-M1)')
excludeRegex '.*-(b|gfa|beta|RC)[0-9]*'
}

site {
title 'Tomcat'
type 'Appserver'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.newrelic.agent.security.instrumentation.apache.tomcat10;

import com.newrelic.api.agent.security.NewRelicSecurity;
import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper;
import com.newrelic.api.agent.security.instrumentation.helpers.URLMappingsHelper;
import com.newrelic.api.agent.security.schema.ApplicationURLMapping;
import com.newrelic.api.agent.security.utils.logging.LogLevel;

import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletRegistration;
import java.util.Collection;
import java.util.Map;

public class HttpServletHelper {
private static final String EMPTY = "";
private static final String WILDCARD = "*";
private static final String SEPARATOR = "/";
public static final String APACHE_TOMCAT_10 = "APACHE-TOMCAT-10";

public static void gatherURLMappings(ServletContext servletContext) {
try {
Map<String, ? extends ServletRegistration> servletRegistrations = servletContext.getServletRegistrations();
getJSPMappings(servletContext, SEPARATOR);

for (ServletRegistration servletRegistration : servletRegistrations.values()) {
for (String mapping : servletRegistration.getMappings()) {
String path = (mapping.startsWith(SEPARATOR) ? EMPTY : SEPARATOR) + mapping;
URLMappingsHelper.addApplicationURLMapping(new ApplicationURLMapping(WILDCARD, path, servletRegistration.getClassName()));
}
}
} catch (Exception e){
NewRelicSecurity.getAgent().log(LogLevel.WARNING, String.format(GenericHelper.ERROR_WHILE_GETTING_APP_ENDPOINTS, APACHE_TOMCAT_10, e.getMessage()), e, HttpServletHelper.class.getName());
}
}

private static void getJSPMappings(ServletContext servletContext, String dir) {
try {
if(dir.endsWith(SEPARATOR)){
Collection<String> resourcePaths = servletContext.getResourcePaths(dir);
for (String path : resourcePaths) {
if(path.endsWith(SEPARATOR)) {
getJSPMappings(servletContext, path);
}
else if(path.endsWith(".jsp") || path.endsWith(".jspx") || path.endsWith(".JSP") || path.endsWith(".JSPX")) {
URLMappingsHelper.addApplicationURLMapping(new ApplicationURLMapping(WILDCARD, (path.startsWith(SEPARATOR) ? EMPTY : SEPARATOR) + path));
}
}
}
} catch (Exception e){
NewRelicSecurity.getAgent().log(LogLevel.WARNING, String.format(GenericHelper.ERROR_WHILE_GETTING_APP_ENDPOINTS, APACHE_TOMCAT_10, e.getMessage()), e, HttpServletHelper.class.getName());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.newrelic.agent.security.instrumentation.apache.tomcat10;

import com.newrelic.api.agent.weaver.MatchType;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.Weaver;
import org.apache.catalina.LifecycleException;

import jakarta.servlet.ServletContext;

@Weave(type = MatchType.ExactClass, originalName = "org.apache.catalina.core.StandardContext")
public abstract class StandardContext_Instrumentation {

public abstract ServletContext getServletContext();

protected synchronized void startInternal() throws LifecycleException {
try {
Weaver.callOriginal();
} finally {
HttpServletHelper.gatherURLMappings(getServletContext());
}
}
}
Loading

0 comments on commit 132cf79

Please sign in to comment.