-
Notifications
You must be signed in to change notification settings - Fork 147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add logic to remove default class_transformer.excludes when security … #1453
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,9 @@ | |
import java.util.Set; | ||
import java.util.regex.Pattern; | ||
|
||
import static com.newrelic.agent.config.SecurityAgentConfig.SECURITY_AGENT_CLASS_TRANSFORMER_EXCLUDES_TO_IGNORE; | ||
import static com.newrelic.agent.config.SecurityAgentConfig.shouldInitializeSecurityAgent; | ||
|
||
/** | ||
* This filter is used to skip certain classes during the classloading transform callback based on the class name. | ||
*/ | ||
|
@@ -38,8 +41,13 @@ public ClassNameFilter(IAgentLogger logger) { | |
} | ||
|
||
/** | ||
* Is the class excluded. | ||
* | ||
* Check if a class should be excluded from class transformation based on an excludes rule. | ||
* <p> | ||
* excludePatterns is a list of exclude rules merged together from user config and the default META-INF/excludes file. | ||
* Exclude rules are evaluated when determining whether to transform weaved classes in the InstrumentationContextManager | ||
* or pointcuts in the PointCutClassTransformer. | ||
* | ||
* @param className name of the class to check exclusion rule for | ||
* @return <code>true</code> if this is an excluded class, <code>false</code> if not | ||
*/ | ||
public boolean isExcluded(String className) { | ||
|
@@ -53,7 +61,7 @@ public boolean isExcluded(String className) { | |
|
||
/** | ||
* Is the class included. | ||
* | ||
* | ||
* @return <code>true</code> if this is an included class, <code>false</code> if not | ||
*/ | ||
public boolean isIncluded(String className) { | ||
|
@@ -79,6 +87,10 @@ public void addConfigClassFilters(AgentConfig config) { | |
for (String exclude : excludes) { | ||
sb.append("\n").append(exclude); | ||
addExclude(exclude); | ||
if (SECURITY_AGENT_CLASS_TRANSFORMER_EXCLUDES_TO_IGNORE.contains(exclude)) { | ||
logger.finer(exclude + " class_transformer exclude explicitly added by user config. The user configured exclude rule will" + | ||
" take precedence and will not be ignored due to the security agent being enabled."); | ||
} | ||
} | ||
logger.finer(sb.toString()); | ||
} | ||
|
@@ -89,7 +101,7 @@ public void addConfigClassFilters(AgentConfig config) { | |
} | ||
|
||
/** | ||
* Add excluded classes in the excludes file. | ||
* Add excluded classes in the META-INF/excludes file. | ||
*/ | ||
public void addExcludeFileClassFilters() { | ||
InputStream iStream = this.getClass().getResourceAsStream(EXCLUDES_FILE); | ||
|
@@ -112,15 +124,34 @@ public void addExcludeFileClassFilters() { | |
// ignore | ||
} | ||
} | ||
boolean ignoreExcludeForSecurityAgent = false; | ||
String formattedIgnoredExcludes = String.join(",", SECURITY_AGENT_CLASS_TRANSFORMER_EXCLUDES_TO_IGNORE); | ||
boolean shouldInitializeSecurityAgent = shouldInitializeSecurityAgent(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Only consider removing one of the default exclude rules if the |
||
|
||
for (String exclude : excludeList) { | ||
addExclude(exclude); | ||
ignoreExcludeForSecurityAgent = shouldInitializeSecurityAgent && SECURITY_AGENT_CLASS_TRANSFORMER_EXCLUDES_TO_IGNORE.contains(exclude); | ||
if (ignoreExcludeForSecurityAgent) { | ||
logger.finer("Ignored " + exclude + " class_transformer exclude defined in META-INF/excludes because the security agent is enabled. " + | ||
"This can be overridden by explicitly setting newrelic.config.class_transformer.excludes=" + formattedIgnoredExcludes + | ||
" or NEW_RELIC_CLASS_TRANSFORMER_EXCLUDES=" + formattedIgnoredExcludes); | ||
} else { | ||
addExclude(exclude); | ||
} | ||
} | ||
|
||
if (ignoreExcludeForSecurityAgent) { | ||
for (String exclude : SECURITY_AGENT_CLASS_TRANSFORMER_EXCLUDES_TO_IGNORE) { | ||
// Remove the default exclude rule if the security agent is enabled. If a user explicitly adds one of these exclude rules via agent config | ||
// then it will be added back to the list via ClassNameFilter.addConfigClassFilters, effectively taking precedence over this removal logic. | ||
excludeList.remove(exclude); | ||
} | ||
} | ||
logger.finer("Excludes initialized: " + excludeList); | ||
} | ||
|
||
/** | ||
* Include matching classes. | ||
* | ||
* | ||
* @param include either a class name or a regular expression | ||
*/ | ||
public void addInclude(String include) { | ||
|
@@ -133,7 +164,7 @@ public void addInclude(String include) { | |
|
||
/** | ||
* Include the given class. | ||
* | ||
* | ||
* @param className the name of the class to include | ||
*/ | ||
public void addIncludeClass(String className) { | ||
|
@@ -143,7 +174,7 @@ public void addIncludeClass(String className) { | |
|
||
/** | ||
* Include classes matching the regular expression. | ||
* | ||
* | ||
* @param regex a regular expression matching classes to include | ||
*/ | ||
public void addIncludeRegex(String regex) { | ||
|
@@ -155,7 +186,7 @@ public void addIncludeRegex(String regex) { | |
|
||
/** | ||
* Exclude matching classes. | ||
* | ||
* | ||
* @param exclude either a class name or a regular expression | ||
*/ | ||
public void addExclude(String exclude) { | ||
|
@@ -168,7 +199,7 @@ public void addExclude(String exclude) { | |
|
||
/** | ||
* Exclude the given class. | ||
* | ||
* | ||
* @param className the name of the class to exclude | ||
*/ | ||
public void addExcludeClass(String className) { | ||
|
@@ -178,7 +209,7 @@ public void addExcludeClass(String className) { | |
|
||
/** | ||
* Exclude classes matching the regular expression. | ||
* | ||
* | ||
* @param regex a regular expression matching classes to include | ||
*/ | ||
public void addExcludeRegex(String regex) { | ||
|
@@ -190,7 +221,7 @@ public void addExcludeRegex(String regex) { | |
|
||
/** | ||
* Create a regular expression for a class. | ||
* | ||
* | ||
* @return a regular expression that matches only the given class | ||
*/ | ||
private String classNameToRegex(String className) { | ||
|
@@ -199,7 +230,7 @@ private String classNameToRegex(String className) { | |
|
||
/** | ||
* Compile a regular expression. | ||
* | ||
* | ||
* @return a pattern or null if the regular expression could not be compiled | ||
*/ | ||
private Pattern regexToPattern(String regex) { | ||
|
@@ -214,7 +245,7 @@ private Pattern regexToPattern(String regex) { | |
|
||
/** | ||
* Is the argument a regular expression (rather than a class name). | ||
* | ||
* | ||
* @param value | ||
* @return <code>true</code> if this is a regular expression, <code>false</code> if not | ||
*/ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,7 +31,6 @@ | |
|
||
import java.lang.instrument.ClassFileTransformer; | ||
import java.lang.instrument.Instrumentation; | ||
import java.text.MessageFormat; | ||
import java.util.Map; | ||
import java.util.Set; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
|
@@ -220,11 +219,6 @@ public boolean shouldTransform(final String internalClassName, final ClassLoader | |
Agent.LOG.log(Level.FINEST, "Skipping transform of {0}. Classloader {1} is excluded.", internalClassName, classloader); | ||
return false; | ||
} | ||
if (internalClassName.startsWith("javax/crypto/")) { | ||
// crypto classes can cause class circularity errors if they get too far along in the class transformer | ||
Agent.LOG.finest(MessageFormat.format("Instrumentation skipped by ''javax crypto'' rule: {0}", internalClassName)); | ||
return false; | ||
} | ||
Comment on lines
-223
to
-227
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This exclude rule was moved to the |
||
if (classNameFilter.isIncluded(internalClassName)) { | ||
Agent.LOG.log(Level.FINEST, "Class {0} is explicitly included", internalClassName); | ||
return true; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the full set of default
class_transformer.exclude
rules that need to be ignored when the security agent is enabled. Should further exclude rules need to be treated the same in the future they can simply be added here and no other logic should need to be changed elsewhere in the agent codebase. Only new tests would need to be added toIncludeExcludeTest
.