Skip to content

Commit

Permalink
Merge branch 'develop' into fix/insecure_cookie_issue
Browse files Browse the repository at this point in the history
  • Loading branch information
monu-k2io committed Oct 26, 2023
2 parents 8908b92 + b68e000 commit b3c2879
Show file tree
Hide file tree
Showing 60 changed files with 3,752 additions and 103 deletions.
33 changes: 33 additions & 0 deletions .github/workflows/snyk-vulnerability-scan.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Snyk Vulnerability Scan

on:
workflow_dispatch:
schedule:
- cron: '00 15 * * 1'
push:
branches:
- main

jobs:
security:
runs-on: ubuntu-latest
steps:
- name: Checkout Java Agent
uses: actions/checkout@v3
with:
ref: 'main'

- name: Set gradle.properties Workaround
shell: bash
run: |
echo "jdk8=/tmp" >> gradle.properties
echo "jdk11=/tmp" >> gradle.properties
echo "jdk17=/tmp" >> gradle.properties
- name: Run Snyk to check for vulnerabilities
uses: snyk/actions/gradle@master
env:
SNYK_TOKEN: ${{ secrets.JAVA_AGENT_SNYK_TOKEN }}
with:
command: monitor
args: --all-sub-projects --org=java-agent --configuration-matching='(includeInJar)|(shadowIntoJar)'
15 changes: 15 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,21 @@ 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.0.6-public-preview] - 2023-10-17
### Changes
- Cassandra DB v3.0+ Support: The Security agent now supports Cassandra DB version 3.0 and above
- HttpClient v5.0+ Support: The Security agent now also supports HttpClient version 5.0 and above
- Support for std-out logging
- Added feature for Daily log rollover
- Support for logger config: log_file_count and log_limit_in_kbytes
- Relocating all our instrumentation packages under the package com.newrelic.agent.security.instrumentation.*
- Package Refactoring for Unit Tests: Move packaging for all UTs to com.nr.agent.security.instrumentation.*
- Set default value for low severity instrumentation to false

### Fixes
- Fixed ClassNotFoundException for IOStreamHelper class with Glassfish
- Updated PostgreSQL UTs with Embedded Server instead of test container

## [1.0.5-public-preview] - 2023-08-29
### Changes
- [INSTRUMENTATION] Support for Apache log4j 3.0.0-alpha1 (new version released on 21 June 2023)
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.0.5
agentVersion=1.0.6
jsonVersion=1.1.0
# Updated exposed NR APM API version.
nrAPIVersion=8.3.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,7 @@ public interface SecurityIntrospector {

void setK2TracingData(String value);

void setK2ParentId(String value);

void clear();
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ protected void after() {

@Override
public void shutdown() {
try {
// to prevent socket.io: broken pipe error for async calls
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
server.shutdown();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
class HttpTestServerImpl extends NanoHTTPD implements HttpTestServer {
private final int port;

private Map<String, String> headers = new HashMap<>();
private static Map<String, String> headers = new HashMap<>();

public HttpTestServerImpl() throws IOException {
this(getRandomPort());
Expand Down Expand Up @@ -83,7 +83,7 @@ private Response serveNonDispatcher(IHTTPSession session) {
private Response serveInternal(IHTTPSession session) {
NewRelic.addCustomParameter("server.port", this.port);
final Map<String, String> incomingHeaders = session.getHeaders();
headers = incomingHeaders;
headers.putAll(incomingHeaders);

if (incomingHeaders.containsKey(SLEEP_MS_HEADER_KEY)) {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.newrelic.agent.security.introspec.SecurityIntrospector;
import com.newrelic.api.agent.security.Agent;
import com.newrelic.api.agent.security.NewRelicSecurity;
import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper;
import com.newrelic.api.agent.security.instrumentation.helpers.JdbcHelper;
import com.newrelic.api.agent.security.schema.AbstractOperation;
import com.newrelic.api.agent.security.schema.HttpRequest;
Expand Down Expand Up @@ -108,6 +109,11 @@ public void setK2TracingData(String value) {
NewRelicSecurity.getAgent().getSecurityMetaData().setTracingHeaderValue(value);
}

@Override
public void setK2ParentId(String value) {
NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(GenericHelper.CSEC_PARENT_ID, value);
}

@Override
public void setRequestInputStreamHash(int hashCode) {
NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(REQUEST_INPUTSTREAM_HASH, Collections.singleton(hashCode));
Expand Down
1 change: 1 addition & 0 deletions instrumentation-security/cassandra-datastax-3/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target/
24 changes: 24 additions & 0 deletions instrumentation-security/cassandra-datastax-3/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
dependencies {
implementation(project(":newrelic-security-api"))
implementation("com.newrelic.agent.java:newrelic-api:${nrAPIVersion}")
implementation("com.newrelic.agent.java:newrelic-weaver-api:${nrAPIVersion}")
implementation("com.datastax.cassandra:cassandra-driver-core:3.2.0")

testImplementation("org.cassandraunit:cassandra-unit:3.1.1.0")
testImplementation("com.github.jbellis:jamm:0.3.2")
}

jar {
manifest { attributes 'Implementation-Title': 'com.newrelic.instrumentation.security.cassandra-datastax-3' }
}

verifyInstrumentation {
passesOnly 'com.datastax.cassandra:cassandra-driver-core:[3.0.0,4.0.0)'
excludeRegex ".*(rc|beta|alpha).*"
excludeRegex('com.datastax.cassandra:cassandra-driver-core:2.*')
}

site {
title 'Cassandra'
type 'Datastore'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.datastax.driver.core;

import com.newrelic.agent.security.instrumentation.cassandra3.CassandraUtils;
import com.newrelic.api.agent.security.NewRelicSecurity;
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;

@Weave(type = MatchType.ExactClass, originalName = "com.datastax.driver.core.SessionManager")
abstract class SessionManager_Instrumentation {
abstract Configuration configuration();

public ResultSetFuture executeAsync(Statement statement) {
boolean isLockAcquired = CassandraUtils.acquireLockIfPossible(statement.hashCode());
ResultSetFuture result;
AbstractOperation cqlOperation = null;

try {
result = Weaver.callOriginal();
if(statement instanceof StatementWrapper){
statement = ((StatementWrapper) statement).getWrappedStatement();
}

if(isLockAcquired){
cqlOperation = CassandraUtils.preProcessSecurityHook(statement, configuration(), this.getClass().getName());
if(cqlOperation != null){
NewRelicSecurity.getAgent().registerOperation(cqlOperation);
}
}
} finally {
if(isLockAcquired){
CassandraUtils.releaseLock(statement.hashCode());
}
}
CassandraUtils.registerExitOperation(isLockAcquired, cqlOperation);
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.datastax.driver.core;

import com.newrelic.agent.security.instrumentation.cassandra3.CassandraUtils;
import com.newrelic.api.agent.security.NewRelicSecurity;
import com.newrelic.api.agent.security.schema.VulnerabilityCaseType;
import com.newrelic.api.agent.security.schema.operation.SQLOperation;
import com.newrelic.api.agent.weaver.MatchType;
import com.newrelic.api.agent.weaver.Weave;

import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;

@Weave(type= MatchType.ExactClass, originalName = "com.datastax.driver.core.SimpleStatement")
public abstract class SimpleStatement_Instrumentation {

public SimpleStatement_Instrumentation(String query, Object... values) {
boolean isLockAcquired = CassandraUtils.acquireLockIfPossible(hashCode());

try{
if(isLockAcquired){
SQLOperation cqlOperation = new SQLOperation(this.getClass().getName(), CassandraUtils.METHOD_EXECUTE_ASYNC);
cqlOperation.setQuery(query);
cqlOperation.setCaseType(VulnerabilityCaseType.NOSQL_DB_COMMAND);
cqlOperation.setDbName(CassandraUtils.EVENT_CATEGORY);
if (values != null){
cqlOperation.setParams(setParams(values));
}
NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(
CassandraUtils.NR_SEC_CUSTOM_ATTRIB_CQL_STMT + hashCode(), cqlOperation);
}
} finally {
if(isLockAcquired){
CassandraUtils.releaseLock(hashCode());
}
}
}

public SimpleStatement_Instrumentation(String query, Map<String, Object> values){
boolean isLockAcquired = CassandraUtils.acquireLockIfPossible(hashCode());

try{
if(isLockAcquired){
SQLOperation cqlOperation = new SQLOperation(this.getClass().getName(), CassandraUtils.METHOD_EXECUTE_ASYNC);
cqlOperation.setQuery(query);
cqlOperation.setCaseType(VulnerabilityCaseType.NOSQL_DB_COMMAND);
cqlOperation.setDbName(CassandraUtils.EVENT_CATEGORY);
cqlOperation.setParams(setParams(values));
NewRelicSecurity.getAgent().getSecurityMetaData().addCustomAttribute(
CassandraUtils.NR_SEC_CUSTOM_ATTRIB_CQL_STMT + hashCode(), cqlOperation);
}
} finally {
if(isLockAcquired){
CassandraUtils.releaseLock(hashCode());
}
}
}
private Map<String, String> setParams(Object... values) {
Map<String, String> params = new HashMap<>();
for(int i = 0; i < values.length; i++){
if(!(values[i] instanceof ByteBuffer)){
params.put(String.valueOf(i), String.valueOf(values[i]));
}
}
return params;
}
private Map<String, String> setParams(Map<String, Object> values) {
Map<String, String> params = new HashMap<>();
for( Map.Entry<String, Object> namedVal: values.entrySet()) {
if(!(namedVal.getValue() instanceof ByteBuffer)){
params.put(namedVal.getKey(), String.valueOf(namedVal.getValue()));
}
}
return params;
}
}
Loading

0 comments on commit b3c2879

Please sign in to comment.