Download the PHP package twarimitswe-aaron/gatekeeper-cdr without Composer

On this page you can find all versions of the php package twarimitswe-aaron/gatekeeper-cdr. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package gatekeeper-cdr

# ๐Ÿ›ก๏ธ Gatekeeper **A zero-trust Content Disarm and Reconstruction (CDR) engine written in pure, memory-safe Rust.** [![License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0) [![Rust Edition](https://img.shields.io/badge/Rust%20Edition-2024-orange)](https://doc.rust-lang.org/edition-guide/rust-2024/) [![Build](https://img.shields.io/badge/build-passing-brightgreen)](#) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md) > Strip every byte of hidden metadata, embedded exploits, steganographic payloads, and trailing attachments from incoming file streams โ€” and reconstruct a mathematically clean output from raw pixel data up.

Table of Contents


What is Gatekeeper?

Gatekeeper is a static library that accepts multi-format file byte streams, surgically removes all non-pixel content, and reconstructs an immaculate output binary from the raw colour matrix upward. It is designed to be embedded directly into application source repositories via native FFI bindings โ€” no infrastructure changes required.

It does not scrub files in place. The entire philosophy is:

Decode to naked pixels. Re-encode from zero. Share nothing with the original.


Why CDR?

A file that "looks" clean to a human viewer can carry:

Threat Vector Example
Steganographic payloads Data hidden in JPEG DCT coefficient LSBs
Exploit shellcode Embedded in APP0โ€“APP15 markers
Personal data leakage EXIF GPS coordinates, device serial numbers
Tracking fingerprints ICC profile unique identifiers
Polyglot containers Executable bytes after the EOI/IEND marker
C2 callbacks URLs encoded inside COM/XMP marker blocks

Classic AV scanning misses all of these. CDR eliminates the attack surface entirely by making it structurally impossible for the output to contain anything other than colour values.


Architecture

Memory Model

Gatekeeper enforces a strict zero-copy architecture at the format-detection layer:

The sniffer compares magic bytes using direct subslice equality (payload[..2] == JPEG_SOI). No intermediate buffers or Vec are constructed during format detection โ€” the comparison resolves in a single register-level load.

Typestate Pipeline

Every sanitizer enforces its stage transitions at compile time using Rust's typestate pattern with newtype tuple structs. Calling stages out of order is a compile error, not a runtime panic. Passing raw bytes to a save routine is also a compile error โ€” only SanitizedOutput is accepted.

Inside the crate, inner values are always extracted via the formal pattern:

Error Model

All errors are defined in src/errors.rs as a single CdrError enum backed by thiserror. No String allocations occur at any error variant โ€” every branch carries fixed-size typed data.

Dual-Output Contract

Every call to disarm() returns a DisarmResult containing two buffers:

Input buffer png_buffer Rationale
JPEG JPEG (q85, metadata stripped) Some(PNG) Two distinct representations
PNG PNG (lossless) None buffer IS already the lossless PNG
GIF GIF (extensions stripped) Some(PNG) Two distinct representations
WebP PNG (no Rust WebP encoder) None buffer IS already the lossless PNG
PDF PDF (actions stripped) None Not an image
Office Office/ZIP (active content stripped) None Not an image

Why is the sanitized file a different size?

Gatekeeper never scrubs bytes in place. Every image passes through:

The output shares zero bytes with the input. Size changes are normal and come from three separate causes:

1. Format change (often much larger โ€” expected)

What you compare Why it grows
JPEG in โ†’ png_buffer out Lossy JPEG discards information; lossless PNG stores every decoded pixel exactly. Typically 2โ€“5ร— larger. This is correct โ€” use buffer (JPEG) when size matters, png_buffer when you need a mathematically exact pixel guarantee.
GIF in โ†’ png_buffer out GIF is palette-indexed and LZW-compressed; the PNG companion is full RGBA lossless. Usually larger.
WebP in โ†’ buffer out No pure-Rust WebP encoder exists yet, so WebP is decoded to pixels and emitted as PNG.

2. Lossy generation loss (JPEG / GIF native buffer)

Path Behaviour
JPEG โ†’ JPEG (buffer) Fully decoded to RGB, then re-quantized at quality 85. This destroys steganographic DCT payloads. Size vs the original depends on the source quality: a q60 upload may grow; a q95 upload may shrink. Gatekeeper does not copy the original quantization tables โ€” that would preserve hidden data.
GIF โ†’ GIF (buffer) Re-quantized with NeuQuant into a fresh local palette. Extension/comment blocks are dropped (smaller), but LZW efficiency may differ from the hand-tuned original.

3. Re-compression of lossless formats (PNG native buffer)

PNG sanitization decodes pixels and writes a new PNG containing only IHDR + PLTE/tRNS (if needed) + IDAT + IEND. All metadata chunks (tEXt, iCCP, eXIf, trailing polyglot bytes) are removed โ€” which reduces size.

The remaining IDAT size depends on deflate level and PNG filter strategy:

Setting Effect
Compression::Best (zlib level 9) Strong deflate โ€” already used.
Adaptive Paeth filtering (per scanline) Critical for size. Without it, IDAT can be 2โ€“3ร— larger than the source even after metadata is stripped. Gatekeeper enables adaptive Paeth on every PNG encode path.

PNG outputs may still be slightly larger than files passed through slow offline optimizers (optipng -o7, Zopfli, brute-force filter search). Gatekeeper targets real-time sanitization, not maximum offline compression.

Quick reference: which buffer should I use?

Goal Use
Smallest image output buffer (native format: JPEG/GIF/PNG)
Exact pixel proof / zero-trust archive png_buffer when present, or buffer for PNG/WebP inputs
Compare size fairly Compare buffer to the same format as the input, not png_buffer to a JPEG

Size fields on DisarmResult

To log both outputs: result.buffer.len() and result.png_buffer.as_ref().map(|p| p.len()).


Enterprise Readiness Analysis

What Gatekeeper Already Does Right

Property Status Detail
Zero-copy format detection โœ… Magic bytes compared via direct slice equality, no allocations
Decompression-bomb guards โœ… Geometry + pixel-budget checks fire before any allocation
Typestate pipeline โœ… Stage transitions are compile errors, not runtime panics
Dual-output (native + PNG) โœ… Single call returns both the native format and a lossless PNG
No String on error paths โœ… Every CdrError variant carries typed structured data
Async streaming โœ… AsyncImageStream + disarm_bytes_async() via Tokio
Input size caps โœ… Hard limits enforced before any decoder work begins

Known Gaps vs. Enterprise CDR

Commercial CDR products (Glasswall, Votiro, OPSWAT MetaDefender) address the following that Gatekeeper does not yet:

Gap Impact Planned Fix
Double decode for JPEG dual-output 2ร— CPU cost per JPEG; highest-priority fix sanitize_jpeg_dual() โ€” decode once, encode to both JPEG and PNG from the same pixel buffer (Phase 12)
32 MiB hard input cap Blocks large document workflows CdrPolicy struct passed into disarm() with configurable limits (Phase 13)
No deterministic JPEG output Encoder version changes produce different bytes for the same input Use a fixed published quantization table instead of quality parameter
No audit receipt Cannot cryptographically prove a file was sanitized Return a Blake3 hash of the output buffer alongside the bytes
No policy engine One fixed set of limits for all callers CdrPolicy { max_bytes, jpeg_quality, allowed_formats, โ€ฆ }
WebP output is PNG Format change surprises callers expecting WebP back Add libwebp bindings via webp crate for true WebPโ†’WebP
GIF nearest-colour quantization Palette-heavy images shift colours visibly NeuQuant re-encode (done); Wu/median-cut optional

Is the Current Approach Production-Ready?

For embedded / edge deployments (IoT gateways, upload proxies, CI artifact scanning) โ€” yes. The architecture is sound: zero-copy parsing, compile-time stage enforcement, bomb guards, and dual-output with no wasted allocations.

For enterprise SaaS at scale (100k+ files/day), the single highest-impact change is eliminating the double decode for JPEG:

This single change halves CPU cost for all JPEG inputs. Everything else in the roadmap is additive.


Supported Formats

Format Detection Sanitize Native Output PNG Output Status
JPEG โœ… Magic + EOI check โœ… zune-jpeg decode โœ… JPEG (q85, metadata stripped) โœ… Lossless PNG Complete
PNG โœ… Magic + IHDR check โœ… png crate decode โœ… PNG (lossless, adaptive Paeth) โ€” (buffer IS the PNG) Complete
GIF โœ… Magic check โœ… gif crate decode โœ… GIF (NeuQuant re-indexed) โœ… Lossless RGBA PNG Complete
WebP โœ… RIFF+WEBP check โœ… image-webp decode โœ… PNG (no pure-Rust WebP encoder) โ€” (buffer IS the PNG) Complete
Office โœ… ZIP Magic check โœ… ZIP unwrap + active-content strip โœ… ZIP re-encode โ€” (not an image) Complete
PDF โœ… %PDF- check โœ… lopdf recursive strip โœ… PDF re-encode โ€” (not an image) Complete

Project Structure


Getting Started

Prerequisites

Build

This produces:

For a release (optimised) build:

Run Tests

Expected output:

Run the CLI Example

The examples/disarm_image.rs driver lets you test the full pipeline against any real file:

Sample output:


Using Gatekeeper as a Library

As a Rust Dependency

Add to your Cargo.toml:

Or for a local checkout:

API Reference

gatekeeper::disarm(payload: &[u8]) -> Result<SanitizedOutput, CdrError>

The primary entry point. Detects format, runs the full CDR pipeline, and returns a SanitizedOutput token โ€” a distinct type that can only be produced by a completed pipeline run.

To enforce that a save function only ever accepts sanitised data:

gatekeeper::sniff_format(payload: &[u8]) -> Result<FileFormat, CdrError>

Identify the format of a byte slice without modifying or decoding it. Useful for routing in larger pipelines.

gatekeeper::sanitizers::jpeg::sanitize_jpeg(input: &[u8]) -> Result<SanitizedOutput, CdrError>

Call the JPEG sanitizer directly, bypassing the format sniffer.


FFI Bindings (Planned)

The cdylib target is already compiled and emits a native shared library (.so / .dll / .dylib). The sections below show the planned import and usage API for each target language. These bindings do not exist yet โ€” they are the design target for Phases 7โ€“11.

Language Bridge / tool Install package Status
Node.js napi-rs npm install gatekeeper-cdr Phase 7 โ€” complete
Python PyO3 pip install gatekeeper-cdr Phase 8 โ€” complete
PHP ext-php-rs composer require gatekeeper/cdr Phase 9 โ€” complete
C / C++ Raw extern "C" Link libgatekeeper.so Phase 9 โ€” complete
Go CGo + extern "C" go get github.com/Twarimitswe-Aaron/gatekeeper-cdr/bindings/go Phase 10 โ€” complete
Java JNI via jni crate Maven / Gradle dependency Phase 11 โ€” pending Maven Central

Node.js (via napi-rs)


Python (via PyO3)


PHP (via ext-php-rs)


C / C++ (Raw FFI)


Go (via CGo)



Roadmap


Contributing

Gatekeeper is open-source under AGPLv3 and actively welcomes contributions. Please read the full guide before opening a PR:

๐Ÿ‘‰ CONTRIBUTING.md

Quick summary:

  1. Fork the repository
  2. Create a branch โ€” git checkout -b feat/png-sanitizer
  3. Write tests โ€” new code must include unit tests
  4. Check โ€” cargo test && cargo clippy && cargo fmt --check
  5. Open a PR against main using the PR template

For larger changes (new format support, architectural changes), please open an issue first to discuss the approach before writing code.


License

Gatekeeper is licensed under the GNU Affero General Public License v3.0 (AGPLv3).

This means:

See LICENSE for the full text.


Built with ๐Ÿฆ€ Rust ยท Licensed under AGPLv3 ยท Contributions welcome

All versions of gatekeeper-cdr with dependencies

PHP Build Version
Package Version
Requires php Version >=8.1
ext-ffi Version *
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package twarimitswe-aaron/gatekeeper-cdr contains the following files

Loading the files please wait ...