feat(exfiltration): add data exfiltration / DLP injector (#313) - #323
feat(exfiltration): add data exfiltration / DLP injector (#313)#323SamuelHassine wants to merge 8 commits into
Conversation
Simulates data exfiltration over DNS tunneling, HTTPS upload and cloud storage upload with random payloads to exercise egress filtering and DLP. Wires the injector into the CircleCI build, publish and test matrices.
There was a problem hiding this comment.
Pull request overview
Adds a new Data Exfiltration / DLP injector to the Python monorepo, intended to exercise egress filtering and DLP controls by simulating exfiltration over DNS tunneling, HTTPS upload, and cloud storage upload using random (non-sensitive) payloads. It also wires the new injector into the existing CircleCI matrices so it is tested and built like the other injectors.
Changes:
- Introduce the
exfiltration/injector module (contracts, config loader, executor, Docker packaging, samples, and metadata). - Add unit tests covering contract generation and executor behaviors (DNS/HTTPS/cloud, with socket/requests mocked).
- Extend CircleCI matrices to include
exfiltrationintest,build_docker_images, andpublish_images.
Reviewed changes
Copilot reviewed 17 out of 20 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| exfiltration/test/test_exfiltration.py | Adds unit tests for contracts and executor egress behaviors (mocked). |
| exfiltration/test/init.py | Marks test package (empty init). |
| exfiltration/README.md | Documents injector purpose, contract behaviors, dev workflow, and icon requirements. |
| exfiltration/pyproject.toml | Defines new injector package metadata/deps, tooling config, and icon path. |
| exfiltration/manifest-metadata.json | Adds integration catalog metadata for the exfiltration injector container. |
| exfiltration/exfiltration_injector/openaev_exfiltration.py | Main injector entrypoint: config loading, icon loading, dispatch, callbacks. |
| exfiltration/exfiltration_injector/img/README.md | Documents required icon asset placement and constraints. |
| exfiltration/exfiltration_injector/helpers/exfiltration_executor.py | Implements DNS/HTTPS/cloud simulated exfiltration with random payloads. |
| exfiltration/exfiltration_injector/helpers/init.py | Marks helpers package. |
| exfiltration/exfiltration_injector/contracts_exfiltration.py | Adds three contracts (DNS/HTTPS/cloud) and expectations under Data Exfiltration domain. |
| exfiltration/exfiltration_injector/configuration/injector_config_override.py | Injector config overrides (id/name/icon path). |
| exfiltration/exfiltration_injector/configuration/config_loader.py | Builds daemon config hints including injector type, contracts, icon filepath. |
| exfiltration/exfiltration_injector/configuration/init.py | Marks configuration package. |
| exfiltration/exfiltration_injector/init.py | Adds package init and version constant. |
| exfiltration/Dockerfile | Builds/runs the injector container, including injector_common build context. |
| exfiltration/docker-compose.yml | Adds a compose service for local container runs. |
| exfiltration/config.yml.sample | Adds sample YAML config for local runs. |
| exfiltration/.env.sample | Adds sample environment variable config for docker-compose runs. |
| exfiltration/.dockerignore | Defines docker ignore rules for the injector build context. |
| .circleci/config.yml | Adds exfiltration to CI test/build/publish matrices. |
Adds coverage for __init__, process_message dispatch and start to satisfy the codecov patch gate.
…load (#313) - Commit the icon PNG the injector loads at startup so the container no longer crashes with FileNotFoundError; drop the img placeholder README. - Fail fast with a clear error when a required contract field (dns_domain, https_url, cloud_url) is missing, so misconfiguration reports ERROR instead of a false PREVENTION success. - Cap the DNS tunneling payload to 4 KB to keep query volume reasonable (larger sizes remain available for the HTTPS and cloud paths). - Include the target URL in cloud upload outputs for parity with the HTTPS and DNS paths. - Cover the new behaviors with unit tests.
Review and fix summaryReviewed the full changed files (not just the diff) with a senior-reviewer lens. The injector is well structured and consistent with the sibling injectors (config loader, contracts, executor, Docker / CI wiring), and the "a blocked egress is still a completed inject" model is correct for DETECTION / PREVENTION scoring. Pushed 496970a to address four issues (the first two are the important ones):
Added unit tests for each of the new behaviors. Verification
Remaining
|
_size() accepted arbitrary integers from inject_content and passed them straight to os.urandom(size_kb * 1024), so a large size_kb could drive excessive memory allocation / OOM in the injector container. Derive MIN_SIZE_KB / MAX_SIZE_KB from the contract SIZE_CHOICES and clamp the parsed value to that range (minimum 1). Covered by new unit tests.
The CI ensure_formatting job runs `isort --profile black --check .` from the repository root, where exfiltration_injector is not on the known_local_folder list and is therefore treated as a third-party import. Re-sort the touched files to match that ordering so the repo-root check passes.
Review and fix summary (second pass)Re-ran the full review-and-fix workflow. Prioritised the newly landed review comment and also did an independent senior-reviewer read of the full changed files (not just the diff). New review comment addressed
Independent re-review
Follow-up commit
Verification
Remaining
|
…313) The RUN conditional used the bash-only [[ ... ]] test, but the Alpine runner shell is ash (POSIX sh), where [[ is not a builtin. Switch to the POSIX [ ... ] test with the variable quoted, matching the ai-redteam Dockerfile, so the branch-override step is portable across shells.
Review and fix summary (final pass)Re-ran the full review-and-fix workflow: independent senior-reviewer read of the full changed files (not just the diff) - contracts, config loader, executor, injector lifecycle, tests, and Docker / CI wiring. Change in this pass
Independent re-review
Verification
Remaining
|
#313) The injector was added to the CircleCI test / build_docker_images / publish_images matrices, but the file was re-saved with CRLF line endings while origin/main uses LF. That turned a 3-line change into a whole-file 290/290 rewrite, breaking git blame and mixing EOL styles. Convert the file back to LF so the diff reflects only the three real matrix additions and the CI config stays consistent with the rest of the repo (all other files in the PR are LF).
Review and fix summaryRan the full review-and-fix workflow: independent senior-reviewer read of the full changed files (not just the diff) - contracts, config loader, executor, injector lifecycle, tests, Dockerfile and CI wiring - plus addressed the remaining open review comment. New finding fixed this pass (not caught by the bots)
Review comment addressed
Independent re-review
Verification
Remaining
|
Summary
Adds the data exfiltration / DLP injector, which exercises egress filtering and DLP controls by simulating data exfiltration from the injector container over three channels: DNS tunneling, HTTPS upload and cloud storage upload. Payloads are random bytes, so nothing sensitive ever leaves the environment. A blocked attempt is a valid outcome (prevention worked) and is reported as a completed inject; the DETECTION / PREVENTION expectations are scored by the relevant collectors.
Also wires CI:
exfiltrationis added to the CircleCIbuild_docker_images,publish_imagesandtestmatrices.Contracts
Notes
dns_domain/https_url/cloud_urlreportsexecution_status=ERRORinstead of a false PREVENTION success.size_kbcannot drive an oversizedos.urandomallocation in the container.[ ... ]test (not the bash-only[[ ... ]]), so it is portable on the Alpineashshell, matching the ai-redteam Dockerfile..circleci/config.ymlis kept with LF line endings, matching origin/main and the rest of the repo, so the diff shows only the three real matrix additions rather than a whole-file CRLF rewrite.Test plan
--profile black --check .) / black / flake8 clean (CIensure_formatting+lintergreen).python -m unittest- contracts + executor + injector lifecycle + size parsing, with socket / requests mocked (17 tests, CITest exfiltrationgreen).build_docker_images-exfiltration(green).Closes #313