Callable is essentially an API of Jenkins through the controller/agent communication channel.
This lets Jenkins plugins execute complex computations on the other end of such a channel.
Care needs to be taken to prevent users able to control agent processes from exploiting this and sending a malicious
Callable to the controller for execution.
Follow the instructions in the Remoting Callables developer documentation to implement
CrumbExclusion is an extension point that allows excluding certain URLs from CSRF protection.
Wherever possible, do not use it to allow bypassing CSRF protection.
Since Jenkins 2.96, requests using Basic authentication providing an API token do not need to provide a CSRF token (crumb).
Most of the time, only unauthenticated requests (through
UnprotectedRootAction) when integrating with external systems will need to bypass CSRF protection.
CrumbExclusion need to only allow bypassing CSRF protection for the specific URLs that do not need it.
Make sure that the
When disabling CSRF protection for an endpoint receiving
POST requests, be sure to only allow performing safe actions, like informing Jenkins about events that are verified again afterwards anyway before actions are being taken.
If the URLs without CSRF protection are provided by an
UnprotectedRootAction, be sure to distinguish between authenticated and unauthenticated (anonymous) requests:
Do not allow additional access or act on objects only because the current user has permission to access them.
UnprotectedRootAction is a
RootAction that is available even to users without Overall/Read.
UnprotectedRootAction should be kept minimal to reduce the surface that is publicly exposed.
Be careful to not open up access to otherwise protected objects to users lacking otherwise necessary permissions to access them by having public fields or getters.
While many types check for permissions in
StaplerProxy#getTarget, many others do not, and permission checks are expected to be implemented in the getters granting access to navigate to these objects.
See the Stapler reference documentation for how requests are handled in Jenkins.
When exposing objects using the Jenkins remote API, be sure to check necessary permissions in
@Exported getters and only expose objects the current user has permission to know about and access.
Do not rely on permission checks in internal APIs to exist.
Permission checks done in
Other programs should generally be invoked using a
Launcher instance bound to the appropriate agent through its channel.
Runtime#exec and similar Java APIs is usually a bug and can in some cases constitute a security vulnerability:
While users with the permissions to configure and run jobs may be able to invoke arbitrary tools on those agents, they should not be able to run programs on the Jenkins controller.
|Most Jenkins instances archive artifacts on the Jenkins controller file system, so even possible constraints, such as for the command to exist on the controller’s file system, or not taking any arguments, is trivially bypassed.|
Plugins that integrate with external services may encounter problems establishing connections via HTTPS due to various SSL/TLS issues. An easy way to prevent issues due to misconfigurations is to override the hostname verifier (to not perform hostname validation) and/or trust manager (to accept all certificates).
This is a very unsafe behavior and must never be the default in plugins distributed by the Jenkins project. Ignoring SSL/TLS errors is only permitted if the following constraints are both followed:
Ignoring SSL/TLS errors is limited to the specific connections opened by the plugin.
Plugins should never cause SSL/TLS errors to be ignored for the entire Jenkins instance.
As a consequence, APIs like
HttpsURLConnection#setDefaultSSLSocketFactory must not be called by plugins.
The only exceptions to this rule are dedicated plugins with only this purpose, like skip-certificate-check.
Ignoring SSL/TLS problems for specific connections (e.g.
HttpsURLConnection#setSSLSocketFactory) is allowed, but users need to opt in to this behavior.
By default, SSL/TLS problems must not be ignored.
Ideally, users have fine-grained control over which connections should ignore errors. For example, if a plugin allows integrating with a set of several different remote services, ignoring SSL/TLS errors should be a per-service option, rather than a single global option.
Plugin developers need to be careful when working with user-provided content. This can take many forms, but common data formats are XML, JSON, and YAML, and are provided through potentially untrusted sources.
If you’re implementing form validation for a build step whose configuration is provided as XML, or a post-build step that processes a file in the workspace, be sure to treat the contents as not fully trusted.
Deserializing untrusted content can easily result in a remote code execution (RCE) vulnerability.
To prevent this, use
ObjectInputStreamEx and pass
This will integrate your deserialization mechanism with JEP-200.
Note that this may require adding a
hudson.remoting.ClassFilter to your plugin that allows deserializing further safe types.
Make sure to review these types for potentially unsafe
If at all possible, prefer serializing object graphs using types already approved.
Be sure to review the OWASP Cheat Sheet for XML External Entity prevention.
All content should be treated as untrusted except in very specific circumstances.
XMLUtils provides functionality to perform common XML operations safely.
When using jackson-databind, make sure to depend on 2.10.x or newer, and only use the "safe" replacement APIs to prevent deserialization vulnerabilities: Use
activateDefaultTyping instead of
See the documentation on polymorphic deserialization.
X-Stream is bundled with Jenkins.
Jenkins plugins generally should not use it directly, but only through
When processing YAML, be sure to look into the parser library’s security documentation. It needs to be configured to prevent the instantiation of arbitrary types.
When using SnakeYAML, make sure to never use the parameterless
new Yaml() constructor, but to pass a
SafeConstructor as argument (or otherwise restrict what can be deserialized).
Additionally, use at least version 1.26 to get denial-of-service protection ("billion laughs").
Consider depending on the SnakeYAML API Plugin instead of bundling SnakeYAML with your plugin.
Many Jenkins plugins allow the use of Groovy to extend their capabilities. For example, the Email Extension Plugin allows executing a script to determine whether an email should be sent.
All such functionality, if available to users without Overall/Administer, must integrate with Script Security Plugin.