OSS lab: pin, install, prove, reset
Turn an eligible release into a repeatable synthetic environment with preserved versions, realistic controls, and an explicit reset recipe.
- 01Qualify release
- 02Freeze inputs
- 03Review installation
- 04Build fixtures
- 05Compare controls
- 06Reset and repeat
At each step: retain the control → record the observation → continue only while the next boundary is understood.
Used in these playbooks#
Start with a reproducibility contract#
Record repository, product edition, supported release, immutable commit, package locks, image digests, operating system, database, authentication mode, and enabled extensions. Keep tested, inferred, and unknown versions separate. A source tag does not identify the image running in a vendor deployment. Your initial output is a manifest plus a working baseline, before any vulnerability attempt.
Use a disposable VM for an unfamiliar project's build. Review its Dockerfiles, build backends, package lifecycle scripts, Makefiles, and downloaded installers first. Provide synthetic credentials and fixtures. Separate dependency preparation from validation; disable unnecessary external integration calls during validation. Preserve the installation instructions you followed and every deviation. This makes it possible to distinguish a supported insecure default from a flaw introduced by the research setup.
Freeze source without overwriting work#
These are adaptable local examples, not a claimed execution. Start with an existing reviewed clone at ./repo; create a fresh output directory. Substitute a real eligible release in the second command. A detached worktree allows a separate copy at that revision while sharing Git objects. Git worktrees.
mkdir -p ./evidence
git -C ./repo rev-parse --verify 'v1.2.3^{commit}'
git -C ./repo worktree add --detach ../lab-source v1.2.3
git -C ./lab-source rev-parse HEAD > ./evidence/source-commit.txt
git -C ./lab-source status --porcelain=v1 > ./evidence/source-status.txt
git -C ./lab-source submodule status --recursive > ./evidence/submodules.txt
Expected: a full commit identifier and an initially clean status file. A submodule entry is inventory, not confirmation its source has been obtained or reviewed. Save compiler/runtime/tool versions separately. Never silently replace a failing eligible release with current main.
Review the effective deployment#
Compose configuration can interpolate environment values, so use a synthetic lab environment and inspect output before sharing. Render first; check host mounts, image references, ports, capabilities, external volumes, privileged mode, and startup scripts. A project name alone does not isolate explicitly named shared volumes. Docker Compose config.
docker compose -p bounty-lab -f ./lab-source/compose.yaml config \
> ./evidence/compose-effective.yaml
docker compose -p bounty-lab -f ./lab-source/compose.yaml \
up -d --wait --wait-timeout 120
Run up only after review and required dependency preparation. --wait depends on declared health checks for application readiness; a running process alone is insufficient. Establish login, ordinary creation, retrieval, and a worker task through the real interface. Docker Compose up.
| Fixture | Normal operation | Boundary case |
|---|---|---|
| Tenant A and B | Each reads its own document | A requests B's synthetic document |
| Member and administrator | Administrator manages invitations | Member attempts the same operation |
| Import directory | Valid sample stays inside destination | Malformed sample attempts a harmless boundary crossing |
| Background worker | Queued operation completes once | Membership changes before job execution |
Preserve the failing and passing stories#
Example trace: member A requests an export, the route returns a job ID, and the worker reads a document owned by B. Capture the request, job record, worker resolution, synthetic output, and authorized B control. A direct call to the export helper explains the implementation but does not establish route reachability. Continue in source data flow and reuse the authorization matrix.
Diagnose setup failures before testing: a migration error invalidates database assumptions; disabled workers invalidate asynchronous conclusions; missing enterprise features limit edition claims. Record unresolved differences instead of compensating by disabling security controls.
Reset and report gate#
Prefer restoring a dedicated VM snapshot or documented fixture/database snapshot. Include queues, object storage, cache, local mail, and generated files in the reset recipe. Container restart is not state reset. Repeat the minimal reproduction after restoration; a result dependent on an earlier experiment is not yet isolated.
- Eligible revision, dependency locks, and deployment differences recorded.
- Normal user workflow and comparison account work.
- Required worker/integration fixtures are present.
- Synthetic evidence survives outside reset storage.
- Clean restoration reproduces the same boundary failure.
- Report distinguishes product behavior from lab-only configuration.
Vulnerability reverse references#
- Hard-coded product credentials — A reusable credential is embedded in source, history, a release, or a default configuration. Distinguish a shared built-in credential from an accidentally committed deployment credential when assigning the weakness.
- Unsafe object deserialization — Untrusted bytes reach a format that can instantiate behavior-bearing objects or invoke code, such as Python pickle, without a sufficient trust boundary.
- Predictable temporary files and unsafe creation — A component creates or reuses temporary files in a way that permits another local principal to precreate, replace, read, or redirect sensitive operations.
- Updater accepts an artifact outside its publisher trust policy — The real update decision accepts modified bytes or an unrelated publisher identity before activation.
- Untrusted model artifact reaches executable deserialization or custom code — An attacker-controlled artifact reaches a loader whose execution trust exceeds the uploader's intended data-only authority.
Nearby shared procedures#
Object, function, and property authorization · Authentication, recovery, federation, and session lifecycle · Trace input into queries, commands, and templates · Server-side fetching and network trust boundaries · Browser execution, cross-origin reads, and forged actions · Uploads, downloads, paths, archives, and XML · Workflow invariants, replay, idempotency, and races · REST, GraphQL, gRPC, WebSocket, and SSE permission parity