Back to skill

Security audit

Jenkins Executor Skill

Security checks for vulnerabilities and agentic risk

Overview

This Jenkins skill mostly does what it claims, but it handles Jenkins credentials unsafely and exposes high-impact build trigger/stop actions without clear safeguards.

Review before installing. Use a least-privilege Jenkins API token, do not store real credentials in the packaged config.json, require HTTPS, and avoid granting this skill access to production deploy or release jobs unless you add explicit approvals or job allowlists.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
__init__.py:15
Finding

Jenkins Credentials Stored in a Plaintext Project Configuration File

Content
View full analysis

Vulnerability Details

File Location: __init__.py:15-25; related configuration in config.json:1-5
Vulnerability Type: Plaintext sensitive credential storage
Risk Level: High

Vulnerable Code

python
# 加载配置文件
config_path = Path(__file__).parent / "config.json"
with open(config_path, "r", encoding="utf-8") as f:
    self.config = json.load(f)

# 连接 Jenkins
self.jenkins = Jenkins(
    baseurl=self.config["base_url"],
    username=self.config["username"],
    password=self.config["api_token"],
    timeout=30
)

The corresponding tracked configuration structure is:

json
{
  "base_url": "Jenkins地址",
  "username": "用户名",
  "api_token": "授权码"
}

Technical Analysis

The implementation loads the Jenkins username and API token directly from config.json inside the project directory. This conflicts with SKILL.md, which states that JENKINS_URL, JENKINS_USER, and JENKINS_TOKEN should be supplied through environment variables.

Although the audited file contains placeholders rather than an active secret, the implemented configuration flow requires users to replace those placeholders with credentials. This makes it likely that operational tokens will be included in source-control commits, packaged skill archives, backups, container images, or filesystem snapshots. File permissions are not restricted or validated.

Attack Path

  1. A user replaces the placeholders in config.json with a working Jenkins username and API token.
  2. The project directory is committed, archived, copied, backed up, or exposed to another local account.
  3. An attacker reads config.json and extracts the Jenkins endpoint and credentials.
  4. The attacker authenticates directly to Jenkins using the stolen token.
  5. The attacker exercises all permissions granted to the compromised Jenkins account, potentially including reading job data and logs, triggering parameterized builds, or stopp ...[truncated 747 chars]
Remediation
View remediation

Remediation Suggestions

  • Remove username and api_token from tracked configuration files.
  • Load JENKINS_URL, JENKINS_USER, and JENKINS_TOKEN from environment variables or a dedicated secrets manager.
  • Keep only a non-sensitive example file such as config.example.json.
  • Add the operational configuration file to .gitignore if a local file must remain supported.
  • Fail initialization when required credentials are absent instead of falling back to embedded values.
  • Restrict filesystem permissions on any unavoidable local secret file to the service account only.
  • Add secret scanning to pre-commit hooks and CI.
  • Rotate any Jenkins token that has previously been stored in or committed through config.json.
  • Assign the Jenkins account only the minimum permissions needed by the skill.

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:35
Finding

Jenkins Basic Authentication Credentials Can Be Sent over Unencrypted HTTP

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:35-41; URL consumed by __init__.py:21-26
Vulnerability Type: Cleartext transmission of authentication credentials
Risk Level: High

Vulnerable Documentation and Code

SKILL.md explicitly provides an HTTP endpoint as its configuration example and states that HTTP Basic Authentication is used:

text
- JENKINS_URL:Jenkins 地址(例如 http://192.168.1.100:8080)
- JENKINS_USER:Jenkins 登录用户名
- JENKINS_TOKEN:Jenkins 用户 Token(密码也可,但不推荐)

## 接口说明
所有功能通过 Jenkins REST API 实现,使用 HTTP Basic Auth 鉴权,支持 Jenkins 2.250+ 所有版本。

The implementation accepts the configured URL without enforcing HTTPS:

python
self.jenkins = Jenkins(
    baseurl=self.config["base_url"],
    username=self.config["username"],
    password=self.config["api_token"],
    timeout=30
)

Technical Analysis

HTTP Basic Authentication encodes credentials but does not encrypt them. When base_url uses http://, the Jenkins username and API token, API requests, build parameters, responses, and console output can cross the network without transport encryption.

The code performs no URL-scheme validation and does not reject insecure Jenkins endpoints. The documented HTTP example increases the likelihood that users will deploy the skill with cleartext transport.

An attacker able to observe or manipulate traffic between the skill and Jenkins could recover credentials, read sensitive build data, replay authenticated requests, or alter traffic.

Attack Path

  1. An operator follows the documented example and configures an http:// Jenkins endpoint.
  2. The skill initializes and authenticates to Jenkins using Basic Authentication.
  3. An attacker with access to the same network, a compromised gateway, a malicious proxy, or another suitable interception position captures the HTTP traffic.
  4. The attacker decodes the Basic Authentication value and recovers the Jenkins username ...[truncated 799 chars]
Remediation
View remediation

Remediation Suggestions

  • Replace the documented endpoint with an https:// example.
  • Validate base_url during initialization and reject http:// URLs by default.
  • Permit cleartext HTTP only through an explicit development-only override accompanied by a prominent warning.
  • Keep TLS certificate verification enabled and use a properly trusted internal certificate authority where applicable.
  • Do not disable certificate validation to accommodate self-signed certificates; configure the appropriate CA bundle instead.
  • Rotate Jenkins tokens if they have ever been transmitted over an untrusted cleartext connection.
  • Consider network-level restrictions so Jenkins is reachable only from approved service identities and hosts.

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Unbounded Third-Party Dependency Versions Create Supply-Chain Risk

Content
View full analysis

Vulnerability Details

File Location: requirements.txt:1-3
Vulnerability Type: Unpinned and unbounded dependencies
Risk Level: Medium

Vulnerable Code

text
openclaw-sdk>=1.0.0
jenkinsapi>=0.3.13
python-dotenv>=1.0.0

Technical Analysis

Every dependency uses only a minimum-version constraint. Consequently, future releases with arbitrary major-version changes remain eligible during installation. The project does not include a lock file, hashes, or upper bounds that would make dependency resolution reproducible.

If a future eligible release is compromised, malicious, or incompatible, a fresh installation can automatically select it without any change to this project. Python packages can execute code during installation and when imported. In this project, openclaw.sdk and jenkinsapi.jenkins are directly imported at runtime.

python-dotenv is declared but is not used by the reviewed implementation, unnecessarily increasing the dependency and supply-chain surface.

No evidence was found that the currently named packages are malicious. The finding concerns the unsafe dependency-resolution policy rather than a confirmed malicious package.

Attack Path

  1. A future version of a declared dependency is compromised, maliciously published, or contains an exploitable regression.
  2. Because the requirement has no upper bound or exact pin, the new release satisfies the >= constraint.
  3. A deployment or build environment performs a fresh dependency resolution.
  4. The package installer selects and installs the affected release.
  5. Malicious or vulnerable code executes during installation, import, or skill operation with the privileges of the installing or running account.

Impact Assessment

A compromised dependency can potentially execute arbitrary Python code under the skill process identity. Depending on deployment privileges, this could expose Jenkins credentials, alter A ...[truncated 314 chars]

Remediation
View remediation

Remediation Suggestions

  • Pin dependencies to versions that have been reviewed and tested.
  • Generate and commit a lock file appropriate to the deployment workflow.
  • Use hash verification, such as pip requirements containing --hash entries with --require-hashes.
  • Resolve packages only from an approved and authenticated package index.
  • Introduce controlled dependency-update automation with security review and testing.
  • Scan resolved dependencies for known vulnerabilities during CI.
  • Remove python-dotenv unless the implementation is changed to use it.
  • Run package installation and the skill itself with minimum operating-system privileges.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (12)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

整体上,该技能的核心功能与 Jenkins 管理相关,主要方向一致,没有发现明显越权或无关的隐藏能力。代码实现了列出任务、触发构建、查询状态、读取日志、停止构建,和描述大体吻合。但存在重要表述偏差:get_build_log() 使用 build.get_console()[-3000:],明确只返回日志末尾 3000 字符,不是“构建日志全文获取”;get_build_status() 只是单次拉取最新构建状态,没有实时订阅、轮询机制或流式更新,因此“实时查询”表述偏强;“全生命周期管理”也略有夸大,因为并未包含创建/更新/删除任务、历史构建管理等更完整生命周期操作。因此应判定为描述与实际行为存在一定不匹配。

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
75% confidence
Finding

The skill uses 'file_read' capability that is not listed in its permissions. This may indicate deceptive intent or missing permission declarations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill advertises force-stopping active Jenkins builds without any explicit warning, confirmation requirement, or guardrail around the destructive effect. In CI/CD environments, aborting builds can disrupt deployments, invalidate test pipelines, or leave systems in inconsistent states, especially if invoked by an automated agent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill exposes a direct build-trigger action that can start arbitrary Jenkins jobs immediately with caller-supplied parameters, without any confirmation, allowlist, or policy check. In a CI/CD context, triggering the wrong job can deploy code, run privileged automation, or execute destructive pipeline stages, making accidental or prompt-influenced misuse realistic.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The stop operation performs an immediate destructive action against a running build with no confirmation or safety guard. In Jenkins environments, stopping builds can interrupt releases, leave environments in inconsistent states, or cancel security/testing workflows, so exposing this as a single-step tool materially increases operational risk.

Content

No source excerpt is available for this finding.

Lp4

Low
Category
MCP Least Privilege
Confidence
65% confidence
Finding

Declared permissions with no matching code capability may indicate removed functionality or pre-staging for future abuse.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill instructs users to provide Jenkins credentials and use HTTP Basic Auth but does not warn about secure storage, transmission, and exposure risks for sensitive authentication data. In a network-enabled skill, this increases the chance of accidental credential leakage through logs, misconfiguration, or use over insecure HTTP endpoints.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

Docstrings, tool descriptions, and returned messages are consistently written in Chinese, and the file does not offer any language selection or indicate that the skill is region-specific. This can violate language/locale policy when a skill forces a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency is specified with a lower-bound range only, which allows future unreviewed versions to be installed and makes builds non-reproducible. In a network-enabled CI/CD skill that can trigger Jenkins actions, dependency drift or a compromised upstream release could materially affect integrity of automation behavior.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
openclaw-sdk>=1.0.0
jenkinsapi>=0.3.13
python-dotenv>=1.0.0

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

Using an unpinned jenkinsapi version permits installation of any newer release satisfying the constraint, which weakens reproducibility and increases supply-chain risk. Because this skill manages Jenkins jobs and builds, a malicious or breaking upstream package version could directly affect build execution, credentials handling, or CI/CD operations.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
openclaw-sdk>=1.0.0
jenkinsapi>=0.3.13
python-dotenv>=1.0.0

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

The unpinned python-dotenv requirement allows an unknown version to be installed, leaving exposure to vulnerable or unreviewed releases and making the environment difficult to audit. Since this package commonly handles local configuration files and environment values, version ambiguity is especially risky when combined with known advisories.

Content

Scanner excerpt · requirements.txt (reported line 3)May include surrounding context.

text
openclaw-sdk>=1.0.0
jenkinsapi>=0.3.13
python-dotenv>=1.0.0

Unverifiable Dependency: python-dotenv has 2 known advisory(ies) (CVE-2026-28684 (python-dotenv: Symlink following in set_key allows arbitrary file overwrite via ); CVE-2026-28684 (python-dotenv reads key-value pairs from a .env file and can set them as environ)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
91% confidence
Finding

The manifest does not pin python-dotenv, so it is impossible to determine whether installation will resolve to a release affected by known advisories. In a Jenkins automation context, configuration-file and environment-variable handling can influence secrets and filesystem state, so an affected version could increase risk of file overwrite or unsafe environment processing.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.