Back to skill

Security audit

mlops-engineer

Security checks for vulnerabilities and agentic risk

Overview

This is a documentation-style MLOps skill with purpose-aligned examples, but users should harden the sample pipelines before running them in real environments.

Install is acceptable if you treat the included code as illustrative. Before running or adapting it, pin dependencies and action versions, avoid latest container tags, prefer short-lived cloud credentials, and never deserialize untrusted Joblib or pickle artifacts.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
references/examples.md:190
Finding

Unsafe deserialization of pipeline data and model artifacts

Content
View full analysis

Vulnerability Details

File Location: references/examples.md, lines 190 and 222-223
Vulnerability Type: Unsafe pickle-compatible deserialization
Risk Level: High

Vulnerable Code

python
# Load processed data
data = joblib.load(processed_data_path)
X_train, y_train = data['X_train'], data['y_train']
python
# Load data and model
data = joblib.load(processed_data_path)
model = joblib.load(model_path)

X_test, y_test = data['X_test'], data['y_test']

Technical Analysis

joblib.load() uses Python's pickle-compatible deserialization mechanism. Pickle-compatible artifacts can define object-reconstruction behavior that invokes arbitrary Python callables during loading. Consequently, loading an artifact is effectively a code-execution operation rather than a passive data-parsing operation.

The training and evaluation components load the files identified by processed_data_path and model_path without verifying an immutable digest, cryptographic signature, trusted origin, ownership, or artifact-store authorization. If an attacker can create or replace either artifact, malicious instructions embedded in it execute before the code accesses the expected data or model fields.

This is particularly significant in an MLOps environment because pipeline components commonly have access to artifact repositories, MLflow credentials, service-account tokens, cloud metadata, internal endpoints, and subsequent pipeline stages.

Attack Path

  1. An attacker obtains write access to the pipeline artifact store, compromises an upstream producer, or causes an untrusted artifact path to be supplied to the component.
  2. The attacker creates a malicious pickle-compatible Joblib artifact containing an object whose reconstruction routine executes attacker-selected Python code.
  3. The artifact is stored where the pipeline expects the processed dataset or model.
  4. The training or evaluation component ca ...[truncated 1079 chars]
Remediation
View remediation

Remediation Suggestions

  1. Do not deserialize untrusted data with Joblib, pickle, cloudpickle, or similar executable formats.
  2. Store datasets in non-executable formats such as Parquet or Arrow, and use a constrained model format such as ONNX, SafeTensors, or another format suitable for the model type.
  3. If Joblib is unavoidable, accept artifacts only from a dedicated repository with strict producer and consumer access controls.
  4. Sign artifacts during production and verify their signatures and immutable cryptographic digests before loading.
  5. Bind artifact identities to pipeline-run metadata so that arbitrary paths cannot be substituted.
  6. Run deserialization in an isolated, non-privileged container with a read-only filesystem, no unnecessary secrets, restricted egress, dropped Linux capabilities, and a narrowly scoped service account.
  7. Record artifact provenance and reject artifacts whose producer, digest, model version, or pipeline run cannot be verified.
  8. Treat checksum validation as an integrity mechanism only when the expected checksum comes from an authenticated, independently protected source.

T08 · Insecure Dependencies

Error
Location
references/examples.md:570
Finding

Mutable and unpinned CI/CD dependencies permit supply-chain substitution

Content
View full analysis

Vulnerability Details

File Location: references/examples.md, lines 570-691
Vulnerability Type: Unpinned GitHub Actions, Python packages, and container image
Risk Level: High

Vulnerable Code

yaml
- uses: actions/checkout@v3

- name: Set up Python
  uses: actions/setup-python@v4
  with:
    python-version: ${{ env.PYTHON_VERSION }}

- name: Install dependencies
  run: |
    pip install -r requirements.txt
    pip install great-expectations pandas-profiling

- name: Upload data profile
  uses: actions/upload-artifact@v3
yaml
- uses: actions/checkout@v3

- name: Set up Python
  uses: actions/setup-python@v4
  with:
    python-version: ${{ env.PYTHON_VERSION }}

- name: Install dependencies
  run: pip install -r requirements.txt
yaml
- uses: actions/checkout@v3

- name: Configure AWS credentials
  uses: aws-actions/configure-aws-credentials@v2
  with:
    aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
    aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    aws-region: us-west-2
yaml
containers:
- name: model-server
  image: mlmodel:latest

Technical Analysis

The workflow references GitHub Actions through mutable major-version tags such as @v2, @v3, and @v4 rather than immutable commit SHAs. The Python installation command explicitly resolves great-expectations and pandas-profiling without versions or package hashes. The contents of the referenced requirements.txt are not included in the audited project, so its pinning and integrity cannot be verified. The Kubernetes deployment also uses the mutable mlmodel:latest tag.

Mutable references allow different code to be resolved at different times without a reviewed change to this project. If an upstream account, package release, action tag, package index, image registry, or image tag is compromised or altered, CI runners or Kubernetes nodes can retr ...[truncated 2416 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin every GitHub Action to a reviewed full commit SHA rather than a mutable major-version tag.
  2. Use an automated dependency-update process to propose reviewed SHA changes while preserving immutability.
  3. Lock Python dependencies to exact versions and cryptographic hashes, for example through a generated lock file and pip install --require-hashes.
  4. Configure trusted package indexes explicitly and disable unintended fallback indexes to reduce dependency-confusion exposure.
  5. Generate and review a software bill of materials and continuously scan dependencies for known vulnerabilities and provenance issues.
  6. Build container images in a controlled pipeline and reference them by immutable digest, such as mlmodel@sha256:..., rather than mlmodel:latest.
  7. Sign container images and enforce signature and provenance verification through Kubernetes admission controls.
  8. Replace long-lived AWS access keys with GitHub OpenID Connect and a narrowly scoped, short-lived IAM role.
  9. Apply least-privilege GitHub workflow permissions and isolate jobs that receive production credentials from jobs that install or execute broad dependency sets.
  10. Restrict Kubernetes workload service accounts, egress, Linux capabilities, writable filesystems, and access to secrets to reduce the impact of a substituted image.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (2)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This markdown file contains code examples that write artifacts to disk and log model artifacts/metadata to an MLflow tracking server, which can persist user or system data outside the current process. The surrounding markdown provides no warning that running these examples will create files locally and may send experiment data to a configured tracking endpoint.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The example starts MLflow runs, logs model data, compiles a pipeline to ml_pipeline.yaml, and submits a run to a Kubeflow endpoint at http://localhost:8080. Because this is a markdown example file, the skill description should warn that executing the sample will create files and interact with external services that may retain uploaded data and metadata.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.