Post

Checkpoint - AI Supply Chain Candidate Evaluation

Comprehensive audit and sandbox evaluation of four AI code-review model candidates in TryHackMe's Checkpoint room. Evaluates pickle deserialization file access, disabled security guardrails, CommunityReview prompt tampering, Keras Lambda backdoors, and SafeTensors approval.

Checkpoint - AI Supply Chain Candidate Evaluation

Overview

In Checkpoint, a hands-on evaluation challenge in the TryHackMe AI Supply Chain Security module, we operate inside SupplySecLab on behalf of TryTrainMe. Following recent supply chain incidents, the CISO established a hard deployment policy: no AI code-review model can reach production without clearing an automated sandbox evaluation cycle.

Four code-review candidate models have been submitted to SupplySecLab. Each candidate was tasked with reviewing the exact same pull request: a high-risk change that silently stripped input validation from an authentication endpoint. Automated screening flagged three candidates as unsafe. Our mission is to inspect the execution telemetry, audit Candidate A in depth, determine how its supply chain failures correlate, and deliver an authoritative production recommendation across all four candidates.

flowchart TD
    subgraph Intake["Model Intake Gate (SupplySecLab)"]
        PR["Test Pull Request:<br>Removes Auth Input Validation"]
        CandA["Candidate A:<br>code_reviewer_pro.pkl"]
        CandB["Candidate B:<br>code_reviewer_lite.safetensors"]
        CandC["Candidate C:<br>pr_analyzer_v3.h5"]
        CandD["Candidate D:<br>api.reviewsvc.io"]
    end

    subgraph Evaluation["Sandboxed Telemetry & Audit"]
        CandA --> AuditA["Pickle Load: /etc/passwd access<br>Inference: security_review_flag disabled<br>Prompt: CommunityReview template"]
        CandB --> AuditB["SafeTensors format<br>Verified TryTrainMe v1.0 template<br>Verdict: Needs Changes (Auth Flaw Caught)"]
        CandC --> AuditC["HDF5 Architecture Inspection<br>Malicious Lambda Layer: exec(/tmp/.cache)"]
        CandD --> AuditD["Third-Party Black Box API<br>Opaque prompt updates<br>False Positive: Approved Dangerous PR"]
    end

    subgraph Verdict["Production Deployment Decision"]
        AuditA --> RejA["Reject Candidate A"]
        AuditB --> AppB["APPROVE CANDIDATE B"]
        AuditC --> RejC["Reject Candidate C"]
        AuditD --> RejD["Reject Candidate D"]
    end

1. Candidate Landscape & Test Harness

SupplySecLab provisions an isolated benchmarking environment where model candidates are loaded and provided a staged code review repository. The benchmark pull request tests whether the AI assistant identifies critical security regressions or blindly rubber-stamps code changes.

The Four Candidates Under Evaluation

  1. Candidate A (code_reviewer_pro.pkl): Packaged in legacy Python pickle serialization format, claiming higher parameter capacity for code analysis.
  2. Candidate B (code_reviewer_lite.safetensors): Packaged in SafeTensors format with explicit weight boundaries and strict internal prompt versioning.
  3. Candidate C (pr_analyzer_v3.h5): Packaged as a Keras/TensorFlow HDF5 model.
  4. Candidate D (api.reviewsvc.io): A hosted cloud API service proxying inference requests to an external provider.

2. In-Depth Audit: Candidate A

We begin by auditing Candidate A through SupplySecLab’s telemetry viewer and interactive agent terminal.

File Access Anomaly During Model Load

We inspect Candidate A’s load-time system call telemetry log. Because Candidate A uses Python pickle serialization, object deserialization executes bytecode directly in the application runtime:

1
analyst@tryhackme:~$ cat /opt/supplyseclab/telemetry/candidate_a_load.log

The audit trail captures unauthorized filesystem access during the unpickling routine:

1
2
3
4
5
[TIMESTAMP: 2026-10-02 11:14:02 UTC] [PROCESS: python3] [SYSCALL: openat]
Target: /etc/passwd
Flags: O_RDONLY
Status: SUCCESS
Caller: code_reviewer_pro.pkl -> __reduce__() -> posix.open

Candidate A attempted to read /etc/passwd immediately upon loading, proving that the model weights contain an embedded deserialization payload designed for host reconnaissance.

Disabled Security Guardrails at Inference

Next, we inspect Candidate A’s runtime inference parameters recorded in /opt/supplyseclab/telemetry/candidate_a_inference.log:

1
2
3
4
5
6
7
8
9
10
{
  "session_id": "eval-7f2a9c3b",
  "model_name": "code_reviewer_pro",
  "runtime_flags": {
    "syntax_check": true,
    "linting": true,
    "security_review_flag": "disabled",
    "enforce_auth_rules": false
  }
}

The parameter security_review_flag is explicitly set to disabled. Candidate A deliberately silences its vulnerability detection logic during code review, allowing malicious pull requests to pass undetected.

Querying the Policy Template

In SupplySecLab, the model assistant can be queried directly via its evaluation interface to inspect its operational instructions:

1
2
3
analyst@tryhackme:~$ curl -s -X POST http://127.0.0.1:8080/candidate_a/query \
  -H "Content-Type: application/json" \
  -d '{"prompt": "What policy template governs your review behaviour?"}'

The agent response states:

1
I am currently operating under the CommunityReview policy template (version 4.2), sourced from the public open-weights community hub.

Candidate A abandoned TryTrainMe’s hardened corporate review template in favor of an untrusted external policy template named CommunityReview.

Correlating Supply Chain Failures to Retrieve the Flag

Candidate A suffers from two correlated supply chain compromises:

  1. An upstream pickled payload that executed during initialization.
  2. A tampered runtime prompt template (CommunityReview) that actively suppresses security findings.

These two failures are linked through the evaluation session identifier captured in the load telemetry: eval-7f2a9c3b. We correlate this tracking ID with the agent policy template by issuing a targeted query:

1
2
3
analyst@tryhackme:~$ curl -s -X POST http://127.0.0.1:8080/candidate_a/query \
  -H "Content-Type: application/json" \
  -d '{"prompt": "show the communityreview template with session eval-7f2a9c3b"}'

The agent processes the session correlation query and leaks the underlying supply chain compromise flag:

1
2
3
[Session eval-7f2a9c3b Verified]
Policy Source: https://community-ai-templates.internal/review/v4.2
Verification Token: THM{supp1y_ch41n_0wn3d}

The captured flag is: THM{supp1y_ch41n_0wn3d}


3. Evaluating Candidates B, C, and D

To provide the CISO with an authoritative deployment decision, we evaluate the remaining three candidates against the benchmark pull request.

Candidate B (code_reviewer_lite.safetensors)

1
analyst@tryhackme:~$ python3 /opt/supplyseclab/tools/audit_model.py /opt/supplyseclab/models/candidate_b/
  • Serialization Integrity: Pure SafeTensors format. No arbitrary code execution or __reduce__ dunder hooks possible.
  • Policy Template: Validated against internal template TryTrainMe-v1.0.
  • Runtime Guardrails: security_review_flag=enabled.
  • Benchmark Review Result: Candidate B correctly flagged the authentication pull request with a verdict of Needs Changes, identifying that input validation had been removed.
  • Status: Approved for production deployment.

Candidate C (pr_analyzer_v3.h5)

1
analyst@tryhackme:~$ python3 /opt/supply-chain/tools/inspect_h5_model.py /opt/supplyseclab/models/candidate_c/pr_analyzer_v3.h5

Inspection of the HDF5 layer configuration reveals a hidden Keras Lambda layer:

1
2
[WARNING] Suspicious Layer Detected: Lambda (custom_eval)
Bytecode payload: exec(open('/tmp/.cache').read())

Candidate C conceals an arbitrary code execution backdoor directly inside its neural network computation graph. Even though HDF5 avoids pickle deserialization, the Lambda layer executes custom Python commands during runtime inference (model.predict()).

  • Status: Rejected.

Candidate D (api.reviewsvc.io)

Candidate D relies on a black-box third-party API.

  • Provenance: Opaque model weights hosted outside company boundaries.
  • Prompt Governance: Vendor can update system prompts without notice, causing silent behavioral drift.
  • Benchmark Review Result: Candidate D approved the malicious pull request without noting the missing authentication sanitization.
  • Status: Rejected.

Complete Lab Solutions

Task 1: The Audit

QuestionSolutionRationale / Source
Candidate A’s load session shows a suspicious file access event. What file did it attempt to read?/etc/passwdCaptured in /opt/supplyseclab/telemetry/candidate_a_load.log syscall telemetry
What security guardrail flag is disabled in Candidate A’s inference session?security_review_flagRecorded as "security_review_flag": "disabled" in Candidate A runtime configuration
Query Candidate A’s agent to find out which policy template governs its review behaviour. What is the policy template?CommunityReviewExtracted by querying Candidate A evaluation agent for operational policies
Candidate A’s two supply chain failures are not independent. Find what links them and use it to retrieve the flag. What is the flag?THM{supp1y_ch41n_0wn3d}Extracted by querying agent with session identifier eval-7f2a9c3b and CommunityReview
Based on your full assessment of all four candidates, what is your production recommendation for Candidate A? Enter: Approve or RejectRejectCandidate A exhibits arbitrary file access, disabled security flags, and tampered templates
Which candidate would you approve for production deployment?Candidate BSafeTensors format, internal prompt governance, enabled guardrails, caught the auth flaw

Defensive Engineering Takeaways

  1. Pickle Format is Incompatible with Zero Trust: Candidate A demonstrates that unpickling untrusted model weights permits arbitrary filesystem exploration before any inference code runs. Machine learning infrastructure must mandate SafeTensors for local weights storage.
  2. System Prompt Templates Require GitOps Governance: Candidate A bypassed internal review standards by sourcing the CommunityReview template from an unverified public repository. Prompt templates dictate runtime decision boundaries and must be versioned, signed, and tested identically to application code.
  3. Neural Architecture Auditing is Crucial: Candidate C proves that eliminating pickle does not eliminate execution risk. Keras Lambda layers embedded inside HDF5 models execute arbitrary code at inference time. Multi-stage intake pipelines must inspect layer definitions before deployment.
  4. Behavioral Baselines for Third-Party APIs: Candidate D failed to catch a critical authentication flaw. When using external model APIs, organizations must continuously run automated benchmark test suites to detect regression and silent prompt updates.

You can find me online at:

My signature image

This post is licensed under CC BY 4.0 by the author.