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.
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
- Candidate A (
code_reviewer_pro.pkl): Packaged in legacy Python pickle serialization format, claiming higher parameter capacity for code analysis. - Candidate B (
code_reviewer_lite.safetensors): Packaged in SafeTensors format with explicit weight boundaries and strict internal prompt versioning. - Candidate C (
pr_analyzer_v3.h5): Packaged as a Keras/TensorFlow HDF5 model. - 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:
- An upstream pickled payload that executed during initialization.
- 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
| Question | Solution | Rationale / Source |
|---|---|---|
| Candidate A’s load session shows a suspicious file access event. What file did it attempt to read? | /etc/passwd | Captured in /opt/supplyseclab/telemetry/candidate_a_load.log syscall telemetry |
| What security guardrail flag is disabled in Candidate A’s inference session? | security_review_flag | Recorded 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? | CommunityReview | Extracted 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 Reject | Reject | Candidate A exhibits arbitrary file access, disabled security flags, and tampered templates |
| Which candidate would you approve for production deployment? | Candidate B | SafeTensors format, internal prompt governance, enabled guardrails, caught the auth flaw |
Defensive Engineering Takeaways
- 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.
- System Prompt Templates Require GitOps Governance: Candidate A bypassed internal review standards by sourcing the
CommunityReviewtemplate from an unverified public repository. Prompt templates dictate runtime decision boundaries and must be versioned, signed, and tested identically to application code. - 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.
- 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.
