High-performance encoded exfiltration detection for MCP Gateway
Project description
Encoded Exfiltration Detection (Rust)
High-performance encoded exfiltration detection for ContextForge and MCP Gateway.
Features
- Detects suspicious encoded payloads in prompt args, tool outputs, and resource content
- Scans common exfil encodings:
- base64
- base64url
- hex
- percent-encoding
- escaped hex
- Scores candidates using decoded length, entropy, printable ratio, sensitive keywords, and egress hints
- Optional redaction instead of hard blocking
- Recursive scanning of nested dicts, lists, and JSON-like string payloads
- Allowlist regex support for known-safe encoded strings
- Decode-depth and recursion-depth guardrails
Build
make install
Runtime Requirements
This plugin depends on cpex>=0.1.0,<0.2 and imports hook models from cpex.framework. The compiled Rust extension is mandatory; there is no Python fallback implementation.
Usage
The plugin scans these hooks:
prompt_pre_fetchtool_post_invokeresource_post_fetch
Typical uses:
- block suspicious encoded payloads before they leave the gateway
- redact encoded secrets or staged exfil fragments from tool results
- surface findings metadata for review and tuning
Detection Model
Each candidate encoded segment is decoded and scored. The detector looks for combinations of:
- sufficient decoded length
- suspicious entropy
- printable decoded content
- sensitive markers such as
password,secret,token,authorization, orprivate key - egress hints such as
curl,wget,webhook,upload,socket, orpastebin
The plugin can also inspect JSON strings recursively so encoded content nested inside serialized blobs is still visible to the detector.
Configuration
Important settings include:
enabled: per-encoding enable flagsmin_encoded_lengthmin_decoded_lengthmin_entropymin_printable_ratiomin_suspicion_scoremax_scan_string_lengthmax_findings_per_valueredactredaction_textblock_on_detectionmin_findings_to_blockallowlist_patternsextra_sensitive_keywordsextra_egress_hintsmax_decode_depthmax_recursion_depthparse_json_strings
Returned Metadata
prompt_pre_fetch, tool_post_invoke, and resource_post_fetch accept an optional extensions parameter carrying OpenTelemetry trace context. When a trace context is present (via extensions.request.trace_id) and at least one detection occurred, the plugin emits operational metrics on result.metadata["encoded_exfil_detection"] with the following schema:
result.metadata["encoded_exfil_detection"] = {
"total_detections": 2, # int — total number of findings in this call
"encoding_types": ["base64", "hex"], # list[str] — distinct encoding names, sorted, deduped
"redacted": True, # bool — present only when the redact branch fired
}
redacted is only included when redact=true is configured and the payload was actually rewritten in this call; it is omitted otherwise (its absence means "not redacted this call", not "false").
Gating: Metrics are only emitted when a valid trace_id is present in the trace context (extensions.request.trace_id) and the scan produced at least one detection. No trace context, or a clean payload, means no result.metadata write at all, regardless of any config flag — this keeps the untraced/clean path byte-for-byte identical to before metrics existed.
Security Note (S1): The plugin never includes raw finding content, matched/decoded payload text, or per-finding path/score detail in result.metadata. Only the total count and the distinct encoding names are reported.
Blocking responses use the ENCODED_EXFIL_DETECTED violation code.
Migration Note
Version 0.3.6 is a breaking change for any existing consumer reading detection metadata:
- The old flat
result.metadatakeys —encoded_exfil_count,encoded_exfil_findings,encoded_exfil_redacted, andimplementation— have been removed entirely. There is no compatibility shim; code reading those keys will silently stop receiving data. (These keys were already dropped at the gateway before this change, since the gateway's metadata sanitizer treats each top-levelresult.metadatakey as a plugin namespace expecting a dict value, andencoded_exfil_count/implementationare scalars — so this migration removes a write that was already dead-on-arrival downstream.) - Detection metrics are now emitted on
result.metadata["encoded_exfil_detection"]instead, with keystotal_detections,encoding_types, and (conditionally)redacted— see Returned Metadata above for the full schema. prompt_pre_fetch,tool_post_invoke, andresource_post_fetchnow accept a new optionalextensionsparameter carrying OpenTelemetry trace context. Emission toresult.metadata["encoded_exfil_detection"]is gated onextensions.request.trace_idbeing present and valid, and requires at least one detection — if no trace context is supplied, or the payload is clean, no metrics are written at all, regardless of any config flag.- Consumers that previously read
result.metadata["encoded_exfil_count"]/result.metadata["encoded_exfil_findings"]/result.metadata["encoded_exfil_redacted"]unconditionally must migrate to readingresult.metadata["encoded_exfil_detection"]and must pass atrace_idviaextensionsto receive metrics. - The
include_detection_detailsconfig flag no longer has any influence overresult.metadata(it never leaks per-finding detail into metrics regardless of its value); it continues to affect only theexamplesfield ofPluginViolation.detailson the blocking path, which is unaffected by this migration.
Security Notes
- Guardrails reject Rust-incompatible allowlist regexes at engine initialization time (during plugin construction). Features such as lookaround and backreferences are not supported.
- Scan and recursion caps exist to keep detection bounded on large payloads.
- Detailed findings can be reduced or sanitized before metadata emission depending on configuration.
Testing
make ci
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cpex_encoded_exfil_detection-0.3.6.tar.gz.
File metadata
- Download URL: cpex_encoded_exfil_detection-0.3.6.tar.gz
- Upload date:
- Size: 41.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
54bb2a178afccde6cbd582c3f53a7ba24367904fd2bc43283cb97c6846f72850
|
|
| MD5 |
7e02b1c5353733cd657c71b6e91700bc
|
|
| BLAKE2b-256 |
04bf3a1151425e4d46cfaea66bd1d963a02ef2b535c5d1e17eebd53784c9349c
|
Provenance
The following attestation bundles were made for cpex_encoded_exfil_detection-0.3.6.tar.gz:
Publisher:
release-rust-python-package.yaml on IBM/cpex-plugins
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cpex_encoded_exfil_detection-0.3.6.tar.gz -
Subject digest:
54bb2a178afccde6cbd582c3f53a7ba24367904fd2bc43283cb97c6846f72850 - Sigstore transparency entry: 2168151650
- Sigstore integration time:
-
Permalink:
IBM/cpex-plugins@b9279eeea5bc0cf410f3949ea5a30ede0f736049 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/IBM
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-rust-python-package.yaml@b9279eeea5bc0cf410f3949ea5a30ede0f736049 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file cpex_encoded_exfil_detection-0.3.6-cp311-abi3-win_amd64.whl.
File metadata
- Download URL: cpex_encoded_exfil_detection-0.3.6-cp311-abi3-win_amd64.whl
- Upload date:
- Size: 747.3 kB
- Tags: CPython 3.11+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0cfd361db9e424009ed819ab30ee8bcb217a740a2c0c37dea769a8583dd25e1f
|
|
| MD5 |
1fc72e25478401c0b9e224dde5d30e48
|
|
| BLAKE2b-256 |
363274d54f545883403156fff7aba9c49e70a0602a2c6d2e343794e9627b692a
|
Provenance
The following attestation bundles were made for cpex_encoded_exfil_detection-0.3.6-cp311-abi3-win_amd64.whl:
Publisher:
release-rust-python-package.yaml on IBM/cpex-plugins
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cpex_encoded_exfil_detection-0.3.6-cp311-abi3-win_amd64.whl -
Subject digest:
0cfd361db9e424009ed819ab30ee8bcb217a740a2c0c37dea769a8583dd25e1f - Sigstore transparency entry: 2168151775
- Sigstore integration time:
-
Permalink:
IBM/cpex-plugins@b9279eeea5bc0cf410f3949ea5a30ede0f736049 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/IBM
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-rust-python-package.yaml@b9279eeea5bc0cf410f3949ea5a30ede0f736049 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 822.6 kB
- Tags: CPython 3.11+, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e9d2f6a8d89c9e6b76f5b844c2113be96993d4ab4590207c91c8cdcc400154ec
|
|
| MD5 |
70b5cbb4589676d863392402579c5c5b
|
|
| BLAKE2b-256 |
a25552178e4110a58cce610c5d8dc541baa01e8d317efdc64e62685125f7a130
|
Provenance
The following attestation bundles were made for cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_x86_64.whl:
Publisher:
release-rust-python-package.yaml on IBM/cpex-plugins
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_x86_64.whl -
Subject digest:
e9d2f6a8d89c9e6b76f5b844c2113be96993d4ab4590207c91c8cdcc400154ec - Sigstore transparency entry: 2168151710
- Sigstore integration time:
-
Permalink:
IBM/cpex-plugins@b9279eeea5bc0cf410f3949ea5a30ede0f736049 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/IBM
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-rust-python-package.yaml@b9279eeea5bc0cf410f3949ea5a30ede0f736049 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_s390x.whl.
File metadata
- Download URL: cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_s390x.whl
- Upload date:
- Size: 860.0 kB
- Tags: CPython 3.11+, manylinux: glibc 2.34+ s390x
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4727e67944accf66b468392dac07c2049e17b7249f327dfa876d7fca81434058
|
|
| MD5 |
d07319089d2865dda86f757ff0fb29a3
|
|
| BLAKE2b-256 |
639ef49ae77b4846e8982bc3a1d60fcf7340cd0f0628e841874163ce3b5c1da9
|
Provenance
The following attestation bundles were made for cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_s390x.whl:
Publisher:
release-rust-python-package.yaml on IBM/cpex-plugins
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_s390x.whl -
Subject digest:
4727e67944accf66b468392dac07c2049e17b7249f327dfa876d7fca81434058 - Sigstore transparency entry: 2168151695
- Sigstore integration time:
-
Permalink:
IBM/cpex-plugins@b9279eeea5bc0cf410f3949ea5a30ede0f736049 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/IBM
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-rust-python-package.yaml@b9279eeea5bc0cf410f3949ea5a30ede0f736049 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_ppc64le.whl.
File metadata
- Download URL: cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_ppc64le.whl
- Upload date:
- Size: 846.7 kB
- Tags: CPython 3.11+, manylinux: glibc 2.34+ ppc64le
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4b22cf1e56ad159e8c0d5a3bfe821b8e87c63f2c7f8a926d76eb126cf52ede2e
|
|
| MD5 |
a49b21c4d0af8422948688825deda4da
|
|
| BLAKE2b-256 |
8e6277a91d54c4fec19ae350c42fe92ab63e3228e679fa5fccb83a9b35e3ee27
|
Provenance
The following attestation bundles were made for cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_ppc64le.whl:
Publisher:
release-rust-python-package.yaml on IBM/cpex-plugins
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_ppc64le.whl -
Subject digest:
4b22cf1e56ad159e8c0d5a3bfe821b8e87c63f2c7f8a926d76eb126cf52ede2e - Sigstore transparency entry: 2168151760
- Sigstore integration time:
-
Permalink:
IBM/cpex-plugins@b9279eeea5bc0cf410f3949ea5a30ede0f736049 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/IBM
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-rust-python-package.yaml@b9279eeea5bc0cf410f3949ea5a30ede0f736049 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_aarch64.whl.
File metadata
- Download URL: cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_aarch64.whl
- Upload date:
- Size: 769.7 kB
- Tags: CPython 3.11+, manylinux: glibc 2.34+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b4626f40879f92940bd08d0a06a0bb278c185237a64543355b3bb8b8e8724151
|
|
| MD5 |
d2e68b53a276c0fccd2b095738e89b65
|
|
| BLAKE2b-256 |
ec68d4e06cce1cffb90bac80c55121a30f2ffe4dbfa488a7289aa9b82aba25fd
|
Provenance
The following attestation bundles were made for cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_aarch64.whl:
Publisher:
release-rust-python-package.yaml on IBM/cpex-plugins
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_aarch64.whl -
Subject digest:
b4626f40879f92940bd08d0a06a0bb278c185237a64543355b3bb8b8e8724151 - Sigstore transparency entry: 2168151746
- Sigstore integration time:
-
Permalink:
IBM/cpex-plugins@b9279eeea5bc0cf410f3949ea5a30ede0f736049 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/IBM
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-rust-python-package.yaml@b9279eeea5bc0cf410f3949ea5a30ede0f736049 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file cpex_encoded_exfil_detection-0.3.6-cp311-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: cpex_encoded_exfil_detection-0.3.6-cp311-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 728.2 kB
- Tags: CPython 3.11+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
76a064b52289c6329f431919761d6b7356762dd94fb353765c83cb9757e392b6
|
|
| MD5 |
5a16b1d5427de5e804b5f8e0227c863f
|
|
| BLAKE2b-256 |
88f70515d2c18783dca4130506a07872ab375a8fef987a457a808c7963038425
|
Provenance
The following attestation bundles were made for cpex_encoded_exfil_detection-0.3.6-cp311-abi3-macosx_11_0_arm64.whl:
Publisher:
release-rust-python-package.yaml on IBM/cpex-plugins
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cpex_encoded_exfil_detection-0.3.6-cp311-abi3-macosx_11_0_arm64.whl -
Subject digest:
76a064b52289c6329f431919761d6b7356762dd94fb353765c83cb9757e392b6 - Sigstore transparency entry: 2168151675
- Sigstore integration time:
-
Permalink:
IBM/cpex-plugins@b9279eeea5bc0cf410f3949ea5a30ede0f736049 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/IBM
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-rust-python-package.yaml@b9279eeea5bc0cf410f3949ea5a30ede0f736049 -
Trigger Event:
workflow_dispatch
-
Statement type: