Skip to content
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

[JENKINS-68404] Add ScriptUsageListener to track Groovy scripts #72

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ Will log the cause of a build. Defaults to true.
Will log usage of credentials as long as they are consumed through the https://plugins.jenkins.io/credentials/[Credentials plugin].
Defaults to true.

=== Log Groovy script usage

Will log potentially dangerous groovy scripts, for example from the script console. Defaults to true.

=== About the client IP-address appearing in the logs
====
The plugin uses a method that cannot guarantee that the actual IP of the client is captured.
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/hudson/plugins/audit_trail/AuditTrailPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ public class AuditTrailPlugin extends GlobalConfiguration {
private static final Logger LOGGER = Logger.getLogger(AuditTrailPlugin.class.getName());
private boolean logBuildCause = true;
private boolean logCredentialsUsage = true;

private boolean logScriptUsage = true;

private List<AuditLogger> loggers = new ArrayList<>();

private transient String log;
Expand Down Expand Up @@ -117,6 +120,8 @@ public boolean shouldLogBuildCause() {

public boolean shouldLogCredentialsUsage() { return logCredentialsUsage; }

public boolean getLogScriptUsage() { return logScriptUsage; }

public List<AuditLogger> getLoggers() { return loggers; }

public AuditTrailPlugin() {
Expand Down Expand Up @@ -165,6 +170,11 @@ public void setLogCredentialsUsage(boolean logCredentialsUsage) {
save();
}

@DataBoundSetter
public void setLogScriptUsage(boolean logScriptUsage) {
this.logScriptUsage = logScriptUsage;
save();
}
private void updateFilterPattern() {
try {
AuditTrailFilter.setPattern(pattern);
Expand Down
54 changes: 54 additions & 0 deletions src/main/java/hudson/plugins/audit_trail/ScriptUsageListener.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package hudson.plugins.audit_trail;

import hudson.Extension;
import jenkins.model.Jenkins;
import jenkins.model.ScriptListener;
import org.kohsuke.stapler.StaplerRequest;

import javax.inject.Inject;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* Log when a (privileged) Groovy script is executed.
*
* @see Jenkins#_doScript(StaplerRequest, org.kohsuke.stapler.StaplerResponse, javax.servlet.RequestDispatcher, hudson.remoting.VirtualChannel, hudson.security.ACL)
* @see hudson.cli.GroovyCommand#run()
* @see hudson.cli.GroovyshCommand#run()
* @see org.jenkinsci.plugins.scriptsecurity.scripts.ScriptApproval#using(String, org.jenkinsci.plugins.scriptsecurity.scripts.Language, String)
*
* @author Jan Meiswinkel
*/
@Extension
public class ScriptUsageListener implements ScriptListener {
private static final Logger LOGGER = Logger.getLogger(ScriptUsageListener.class.getName());

@Inject
AuditTrailPlugin configuration;

/**
* Called when a (privileged) groovy script is executed.
*
* @see Jenkins#_doScript(StaplerRequest, org.kohsuke.stapler.StaplerResponse, javax.servlet.RequestDispatcher, hudson.remoting.VirtualChannel, hudson.security.ACL)
* @param script The script to be executed.
* @param origin Descriptive identifier of the origin that is responsible for executing the script (Console, Run, ...).
*/
@Override
public void onScript(String script, String origin) {
if (!configuration.getLogScriptUsage()) {
return;
}
StringBuilder builder = new StringBuilder();
builder.append("A groovy script was executed. Origin: ");
builder.append(origin);
builder.append("\nThe executed script: \n");
builder.append(script);
String log = builder.toString();
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "Detected groovy script usage, details: {0}", new Object[]{log});
}
for (AuditLogger logger : configuration.getLoggers()) {
logger.log(log);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
<f:entry title="${%Log credentials usage}">
<f:checkbox name="logCredentialsUsage" checked="${descriptor.logCredentialsUsage}"/>
</f:entry>
<f:entry title="${%Log Groovy scripts}" field="logScriptUsage">
<f:checkbox name="logScriptUsage" checked="${descriptor.logScriptUsage}"/>
meiswjn marked this conversation as resolved.
Show resolved Hide resolved
</f:entry>
</f:advanced>
</f:section>
</j:jelly>
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@

Log\ how\ each\ build\ is\ triggered=Aufzeichnen, wodurch die jeweiligen Builds angesto\u00DFen wurden.
Log\ credentials\ usage=Aufzeichnen, welche Objekte auf Credentials zugreifen.
Log\ Groovy\ scripts=Groovy Skripte aufzeichnen.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<div>
When this option is enabled, Groovy scripts that run with privileged rights are logged. This includes the script console, CLI and Runs using scripts outside the sandbox.
</div>