Skip to main content

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_fetch
  • tool_post_invoke
  • resource_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, or private key
  • egress hints such as curl, wget, webhook, upload, socket, or pastebin

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 flags
  • min_encoded_length
  • min_decoded_length
  • min_entropy
  • min_printable_ratio
  • min_suspicion_score
  • max_scan_string_length
  • max_findings_per_value
  • redact
  • redaction_text
  • block_on_detection
  • min_findings_to_block
  • allowlist_patterns
  • extra_sensitive_keywords
  • extra_egress_hints
  • max_decode_depth
  • max_recursion_depth
  • parse_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.metadata keys — encoded_exfil_count, encoded_exfil_findings, encoded_exfil_redacted, and implementation — 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-level result.metadata key as a plugin namespace expecting a dict value, and encoded_exfil_count/implementation are 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 keys total_detections, encoding_types, and (conditionally) redacted — see Returned Metadata above for the full schema.
  • prompt_pre_fetch, tool_post_invoke, and resource_post_fetch now accept a new optional extensions parameter carrying OpenTelemetry trace context. Emission to result.metadata["encoded_exfil_detection"] is gated on extensions.request.trace_id being 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 reading result.metadata["encoded_exfil_detection"] and must pass a trace_id via extensions to receive metrics.
  • The include_detection_details config flag no longer has any influence over result.metadata (it never leaks per-finding detail into metrics regardless of its value); it continues to affect only the examples field of PluginViolation.details on 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cpex_encoded_exfil_detection-0.3.6.tar.gz (41.6 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

cpex_encoded_exfil_detection-0.3.6-cp311-abi3-win_amd64.whl (747.3 kB view details)

Uploaded CPython 3.11+Windows x86-64

cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_x86_64.whl (822.6 kB view details)

Uploaded CPython 3.11+manylinux: glibc 2.34+ x86-64

cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_s390x.whl (860.0 kB view details)

Uploaded CPython 3.11+manylinux: glibc 2.34+ s390x

cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_ppc64le.whl (846.7 kB view details)

Uploaded CPython 3.11+manylinux: glibc 2.34+ ppc64le

cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_aarch64.whl (769.7 kB view details)

Uploaded CPython 3.11+manylinux: glibc 2.34+ ARM64

cpex_encoded_exfil_detection-0.3.6-cp311-abi3-macosx_11_0_arm64.whl (728.2 kB view details)

Uploaded CPython 3.11+macOS 11.0+ ARM64

File details

Details for the file cpex_encoded_exfil_detection-0.3.6.tar.gz.

File metadata

File hashes

Hashes for cpex_encoded_exfil_detection-0.3.6.tar.gz
Algorithm Hash digest
SHA256 54bb2a178afccde6cbd582c3f53a7ba24367904fd2bc43283cb97c6846f72850
MD5 7e02b1c5353733cd657c71b6e91700bc
BLAKE2b-256 04bf3a1151425e4d46cfaea66bd1d963a02ef2b535c5d1e17eebd53784c9349c

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cpex_encoded_exfil_detection-0.3.6-cp311-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for cpex_encoded_exfil_detection-0.3.6-cp311-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 0cfd361db9e424009ed819ab30ee8bcb217a740a2c0c37dea769a8583dd25e1f
MD5 1fc72e25478401c0b9e224dde5d30e48
BLAKE2b-256 363274d54f545883403156fff7aba9c49e70a0602a2c6d2e343794e9627b692a

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 e9d2f6a8d89c9e6b76f5b844c2113be96993d4ab4590207c91c8cdcc400154ec
MD5 70b5cbb4589676d863392402579c5c5b
BLAKE2b-256 a25552178e4110a58cce610c5d8dc541baa01e8d317efdc64e62685125f7a130

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_s390x.whl.

File metadata

File hashes

Hashes for cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_s390x.whl
Algorithm Hash digest
SHA256 4727e67944accf66b468392dac07c2049e17b7249f327dfa876d7fca81434058
MD5 d07319089d2865dda86f757ff0fb29a3
BLAKE2b-256 639ef49ae77b4846e8982bc3a1d60fcf7340cd0f0628e841874163ce3b5c1da9

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_ppc64le.whl.

File metadata

File hashes

Hashes for cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_ppc64le.whl
Algorithm Hash digest
SHA256 4b22cf1e56ad159e8c0d5a3bfe821b8e87c63f2c7f8a926d76eb126cf52ede2e
MD5 a49b21c4d0af8422948688825deda4da
BLAKE2b-256 8e6277a91d54c4fec19ae350c42fe92ab63e3228e679fa5fccb83a9b35e3ee27

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for cpex_encoded_exfil_detection-0.3.6-cp311-abi3-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 b4626f40879f92940bd08d0a06a0bb278c185237a64543355b3bb8b8e8724151
MD5 d2e68b53a276c0fccd2b095738e89b65
BLAKE2b-256 ec68d4e06cce1cffb90bac80c55121a30f2ffe4dbfa488a7289aa9b82aba25fd

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cpex_encoded_exfil_detection-0.3.6-cp311-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for cpex_encoded_exfil_detection-0.3.6-cp311-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 76a064b52289c6329f431919761d6b7356762dd94fb353765c83cb9757e392b6
MD5 5a16b1d5427de5e804b5f8e0227c863f
BLAKE2b-256 88f70515d2c18783dca4130506a07872ab375a8fef987a457a808c7963038425

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page