Skip to main content

Free 30-min security demo  — We'll scan your real code and show live findings, no commitment Book Now

Offensive360
DevSecOps

Jenkins Pipeline Security: How to Safely Manage CI/CD Pipelines

Jenkins interacts with multiple servers and components, making security crucial. This guide covers the most common Jenkins vulnerabilities and 13 best practices to secure your CI/CD pipeline.

Offensive360 Security Research Team — min read
Jenkins CI/CD pipeline security DevSecOps access control

Jenkins is one of the most widely deployed CI/CD platforms in the world — and one of the most targeted. Because Jenkins interacts with source repositories, build servers, deployment environments, and production secrets, a compromised Jenkins instance can mean a compromised entire software supply chain.

Why Jenkins Security Matters

Jenkins typically holds:

  • Source code access credentials
  • Deployment keys and cloud provider credentials
  • Environment secrets and API tokens
  • Access to production systems

A single misconfigured plugin or overly permissive access policy can expose all of this. The Jenkins security advisories page lists dozens of plugin vulnerabilities discovered each year.

Vulnerable Plugins Highlighted in 2022

The Jenkins security team issued advisories covering several widely-used plugins:

  • Active Directory Plugin — transmitted credentials in plain text, exposing domain credentials to network sniffers
  • Badge Plugin — XSS vulnerability allowing stored script injection in build badges
  • Git Plugin — arbitrary file read vulnerability
  • Pipeline: Shared Groovy Libraries — allowed sandbox bypass and arbitrary code execution
  • Script Security Plugin — multiple sandbox escape vulnerabilities

Keep plugins updated and remove any that are unused or unmaintained.

13 Security Best Practices

1. Never Build on the Controller

Run builds on agents, not the Jenkins controller. The controller has access to all credentials and configuration — running untrusted build code there is a serious risk.

// Always specify an agent, never use `agent none` on the controller
pipeline {
    agent { label 'build-agent' }
    stages { ... }
}

2. Implement Access Control

Jenkins has two layers of access control: security realm (authentication) and authorization strategy (what authenticated users can do). Both must be configured.

3. Use Matrix-Based Authorization

The Project-based Matrix Authorization Strategy gives you fine-grained control:

- Admins: full access
- Developers: read/build their own jobs
- QA: read + test trigger
- Ops: deploy-specific jobs only

4. Sanitize Environment Variables

Build scripts frequently log environment variables. Ensure secrets are stored as Jenkins credentials and accessed via the credentials() binding — never passed as plain environment variables.

// WRONG: Secret visible in build logs
environment {
    API_KEY = "supersecret123"
}

// CORRECT: Masked credential
environment {
    API_KEY = credentials('my-api-key-credential-id')
}

5. Enable CSRF Protection

Jenkins has built-in CSRF protection via crumb tokens. Ensure it’s enabled in Manage Jenkins → Configure Global Security → CSRF Protection.

6. Use the Script Security Plugin

All Groovy scripts in pipelines run in a sandbox by default. Review and minimize the scripts that require sandbox escapes (approved scripts).

7. Restrict the Groovy Sandbox Escape List

Scripts approved to run outside the sandbox have full JVM access. Audit your approved scripts list regularly and remove approvals that are no longer needed.

8. Enable Audit Logging

Use the Audit Trail plugin to log all configuration changes, credential accesses, and build triggers. This is essential for incident investigation.

9. Rotate Credentials Regularly

Integrate with a secrets manager (HashiCorp Vault, AWS Secrets Manager) rather than storing long-lived credentials in Jenkins. Rotate them on a schedule.

10. Scan Dependencies in the Pipeline

Add dependency scanning as a required pipeline stage:

stage('Security Scan') {
    steps {
        sh 'mvn dependency-check:check'
        // or npm audit, cargo audit, etc.
    }
}

11. Pin Plugin Versions

Use the Plugin Installation Manager Tool to lock your plugin versions in a plugins.txt file. Uncontrolled automatic plugin updates can introduce regressions and vulnerabilities.

12. Network Isolation

Jenkins agents should not have direct access to production systems. Use deployment pipelines that communicate through controlled channels rather than giving agents direct network access.

13. Add SAST to Every Pipeline

Integrate static application security testing as a mandatory step before merge or deployment. A broken security scan should block the build.

stage('SAST') {
    steps {
        // Scan and fail the build if critical findings are detected
        sh 'offensive360-scan --fail-on critical'
    }
}

Incident Response for Compromised Jenkins

If you suspect a Jenkins compromise:

  1. Immediately revoke all stored credentials
  2. Rotate all service account passwords and API keys Jenkins had access to
  3. Review recent build logs for unauthorized commands
  4. Check for unauthorized job creation or configuration changes in the audit trail
  5. Rebuild the controller from a known-good state

Summary

Jenkins security is a layered problem: plugin vulnerabilities, access control misconfigurations, and insecure pipeline practices each contribute to the attack surface. Address all three layers, integrate SAST into every pipeline, and treat your CI/CD infrastructure as production infrastructure — because it effectively is.

Offensive360 Security Research Team

Application Security Research

Find vulnerabilities before attackers do

Run Offensive360 SAST and DAST against your applications and get a full vulnerability report in minutes.