-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #116 from newrelic/feature/ning-http-client-1.0
Support for Ning async http client 1.0.x
- Loading branch information
Showing
7 changed files
with
588 additions
and
0 deletions.
There are no files selected for viewing
19 changes: 19 additions & 0 deletions
19
instrumentation-security/ning-async-http-client-1.0.0/build.gradle
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
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.ning:async-http-client:1.0.0") | ||
} | ||
|
||
jar { | ||
manifest { attributes 'Implementation-Title': 'com.newrelic.instrumentation.security.ning-async-http-client-1.0.0' } | ||
} | ||
|
||
verifyInstrumentation { | ||
passesOnly 'com.ning:async-http-client:[1.0,1.1)' | ||
} | ||
|
||
site { | ||
title 'Ning AsyncHttpClient' | ||
type 'Messaging' | ||
} |
85 changes: 85 additions & 0 deletions
85
...0/src/main/java/com/newrelic/agent/security/instrumentation/ning/http_1_0/NingHelper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package com.newrelic.agent.security.instrumentation.ning.http_1_0; | ||
|
||
import com.newrelic.api.agent.security.NewRelicSecurity; | ||
import com.newrelic.api.agent.security.instrumentation.helpers.GenericHelper; | ||
import com.newrelic.api.agent.security.instrumentation.helpers.ServletHelper; | ||
import com.newrelic.api.agent.security.schema.AbstractOperation; | ||
import com.newrelic.api.agent.security.schema.SecurityMetaData; | ||
import com.newrelic.api.agent.security.schema.StringUtils; | ||
import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException; | ||
import com.newrelic.api.agent.security.schema.operation.SSRFOperation; | ||
import com.newrelic.api.agent.security.utils.SSRFUtils; | ||
import com.ning.http.client.Request; | ||
|
||
import java.net.URI; | ||
import java.net.URISyntaxException; | ||
|
||
public class NingHelper { | ||
public static final String METHOD_NAME_EXECUTE = "execute"; | ||
public static final String NR_SEC_CUSTOM_ATTRIB_NAME = "SSRF_OPERATION_LOCK_NING-"; | ||
|
||
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 AbstractOperation preprocessSecurityHook(Request request, String uri, String methodName, String className) { | ||
try { | ||
SecurityMetaData securityMetaData = NewRelicSecurity.getAgent().getSecurityMetaData(); | ||
if (!NewRelicSecurity.isHookProcessingActive() || securityMetaData.getRequest().isEmpty() | ||
) { | ||
return null; | ||
} | ||
|
||
// Add Security IAST header | ||
String iastHeader = NewRelicSecurity.getAgent().getSecurityMetaData().getFuzzRequestIdentifier().getRaw(); | ||
if (iastHeader != null && !iastHeader.trim().isEmpty()) { | ||
request.getHeaders().add(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID, iastHeader); | ||
} | ||
|
||
String csecParaentId = securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, String.class); | ||
if(StringUtils.isNotBlank(csecParaentId)){ | ||
request.getHeaders().add(GenericHelper.CSEC_PARENT_ID, csecParaentId); | ||
} | ||
|
||
SSRFOperation operation = new SSRFOperation(uri, className, methodName); | ||
try { | ||
NewRelicSecurity.getAgent().registerOperation(operation); | ||
} finally { | ||
if (operation.getApiID() != null && !operation.getApiID().trim().isEmpty() && | ||
operation.getExecutionId() != null && !operation.getExecutionId().trim().isEmpty()) { | ||
// Add Security distributed tracing header | ||
request.getHeaders().add(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER, SSRFUtils.generateTracingHeaderValue(securityMetaData.getTracingHeaderValue(), operation.getApiID(), operation.getExecutionId(), NewRelicSecurity.getAgent().getAgentUUID())); | ||
} | ||
} | ||
return operation; | ||
} catch (Throwable e) { | ||
if (e instanceof NewRelicSecurityException) { | ||
e.printStackTrace(); | ||
throw e; | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
public static void releaseLock(int hashCode) { | ||
try { | ||
GenericHelper.releaseLock(NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); | ||
} catch (Throwable ignored) { | ||
} | ||
} | ||
|
||
public static boolean acquireLockIfPossible(int hashCode) { | ||
try { | ||
return GenericHelper.acquireLockIfPossible(NR_SEC_CUSTOM_ATTRIB_NAME, hashCode); | ||
} catch (Throwable ignored) { | ||
} | ||
return false; | ||
} | ||
} |
47 changes: 47 additions & 0 deletions
47
...tp-client-1.0.0/src/main/java/com/ning/http/client/AsyncHttpProvider_Instrumentation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package com.ning.http.client; | ||
|
||
import com.newrelic.agent.security.instrumentation.ning.http_1_0.NingHelper; | ||
import com.newrelic.api.agent.NewRelic; | ||
import com.newrelic.api.agent.Segment; | ||
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.io.IOException; | ||
import java.net.URI; | ||
import java.net.URISyntaxException; | ||
import java.util.concurrent.Future; | ||
|
||
@Weave(type = MatchType.Interface, originalName = "com.ning.http.client.AsyncHttpProvider") | ||
public class AsyncHttpProvider_Instrumentation { | ||
|
||
public <T> Future<T> execute(Request request, AsyncHandler<T> handler) throws IOException { | ||
boolean isLockAcquired = NingHelper.acquireLockIfPossible(this.hashCode()); | ||
AbstractOperation operation = null; | ||
URI uri = null; | ||
Future<T> returnObj = null; | ||
|
||
try { | ||
uri = new URI(request.getUrl()); | ||
String scheme = uri.getScheme(); | ||
|
||
if (isLockAcquired && (scheme == null || scheme.equals("http") || scheme.equals("https"))) { | ||
operation = NingHelper.preprocessSecurityHook(request, uri.toString(), NingHelper.METHOD_NAME_EXECUTE, this.getClass().getName()); | ||
} | ||
} catch (URISyntaxException uriSyntaxException) { | ||
// Instrumentation won't work and normal execution will continue | ||
} | ||
|
||
try { | ||
returnObj = Weaver.callOriginal(); | ||
} finally { | ||
if (isLockAcquired) { | ||
NingHelper.releaseLock(this.hashCode()); | ||
} | ||
} | ||
NingHelper.registerExitOperation(isLockAcquired, operation); | ||
|
||
return returnObj; | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
...p-client-1.0.0/src/main/java/com/ning/http/client/RequestBuilderBase_Instrumentation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/* | ||
* | ||
* * Copyright 2020 New Relic Corporation. All rights reserved. | ||
* * SPDX-License-Identifier: Apache-2.0 | ||
* | ||
*/ | ||
|
||
package com.ning.http.client; | ||
|
||
import com.newrelic.api.agent.weaver.Weave; | ||
|
||
@Weave(originalName = "com.ning.http.client.RequestBuilderBase") | ||
abstract class RequestBuilderBase_Instrumentation { | ||
|
||
@Weave(originalName = "com.ning.http.client.RequestBuilderBase$RequestImpl") | ||
private abstract static class RequestImpl_Instrumentation { | ||
private Headers headers; | ||
|
||
// Added this instrumentation to return modifiable headers instead | ||
public Headers getHeaders() { | ||
return headers; | ||
} | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
instrumentation-security/ning-async-http-client-1.0.0/src/main/java/play/CorePlugin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package play; | ||
|
||
import com.newrelic.api.agent.weaver.SkipIfPresent; | ||
|
||
/** | ||
* Play v1 instrumentation is implemented using its own set of pointcuts that don't work well with our async APIs. This | ||
* class is present in Play v1 but not v2, and will cause this module NOT to load if the customer is using Play v1. | ||
*/ | ||
@SkipIfPresent | ||
public class CorePlugin { | ||
} |
Oops, something went wrong.