diff --git a/AGENTS.md b/AGENTS.md index 02e44f69a3..f7d31fe162 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -9,6 +9,9 @@ This is the entry point for AI guidance in Apache Fory. Read this file first, th - `.agents/docs-and-formatting.md`: documentation, specification, and markdown rules. - `.agents/ci-and-pr.md`: CI triage, PR expectations, and commit conventions. - `.agents/testing/integration-tests.md`: `integration_tests/` prerequisites, regeneration rules, and commands. +- `docs/security/index.md`: security model index. +- `docs/security/threat-model.md`: project-level trust boundaries, non-goals, + and downstream responsibilities. - `docs/security/deserialization.md`: security boundaries for untrusted deserialization classification. - `.agents/languages/java.md` - `.agents/languages/csharp.md` @@ -177,3 +180,11 @@ This is the entry point for AI guidance in Apache Fory. Read this file first, th - PR titles must follow Conventional Commits; `.github/workflows/pr-lint.yml` enforces this. - Performance changes should use the `perf` type and include benchmark data. - See `.agents/ci-and-pr.md` for GitHub CLI triage commands and commit message examples. + +## Security + +Security models start at `docs/security/index.md`. Read +`docs/security/threat-model.md` for project-level trust boundaries, non-goals, +and downstream responsibilities. For untrusted deserialization, read +`docs/security/deserialization.md` before reporting or changing allocation, +stream filling, skip, reference, metadata, or policy validation behavior. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000..321a1673ae --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,31 @@ + + +# Security Policy + +## Reporting a Vulnerability + +`apache/fory` follows the [Apache Software Foundation security process](https://www.apache.org/security/). Please report suspected +vulnerabilities privately to `security@apache.org`; do not open public +GitHub issues or pull requests for security reports. + +## Security Models + +Apache Fory security models are documented under +[docs/security](docs/security/index.md). Start with the +[project threat model](docs/security/threat-model.md); for detailed untrusted +deserialization classification rules, see the +[deserialization security model](docs/security/deserialization.md). diff --git a/docs/README.md b/docs/README.md index 27500ed942..15d0393362 100644 --- a/docs/README.md +++ b/docs/README.md @@ -10,7 +10,8 @@ [Kotlin](guide/kotlin/index.md) guides. - For row format, see the [row format spec](specification/row_format_spec.md). - For using Apache Fory™ with GraalVM native image, see [graalvm support](guide/java/graalvm-support.md) doc. -- For deserialization security boundaries, see the [security model](security/deserialization.md). +- For security models and deserialization boundaries, see the + [security docs](security/index.md). ## Fory IDL Schema diff --git a/docs/security/deserialization.md b/docs/security/deserialization.md index 390b1855b4..8ad54789e7 100644 --- a/docs/security/deserialization.md +++ b/docs/security/deserialization.md @@ -1,6 +1,6 @@ --- title: Deserialization Security Model -sidebar_position: 2 +sidebar_position: 3 --- This document defines the security model for Apache Fory deserialization. It is @@ -52,6 +52,41 @@ Fory security boundaries do not include: shape, unless rejecting other shapes is an explicit owner policy or protects one of the boundaries above. +## Type And Class Policy + +Type, class, function, method, registration, and deserialization policies are +security boundaries when they are intended to restrict what untrusted bytes may +materialize. + +For untrusted data, a bypass is security-relevant when encoded bytes can +materialize a type, function, method, class, or dynamic object that the active +Fory policy should reject. This includes bypasses of class or type +registration, allow-list checkers, strict-mode checks, or language-specific +deserialization policies. + +Disabling registration or dynamic-type checks for trusted data is a caller +configuration choice. That choice only removes the arbitrary-type materialization +claim provided by that policy; it does not remove Fory's runtime-safety, +resource, cleanup, retained-state, or no-progress-loop requirements for +untrusted deserialization paths. + +Fory is not a sandbox for application-owned types. If a registered type or +serializer is allowed by the active policy, the application owns whether that +type's construction, hooks, setters, finalizers, or other logic is safe for the +application's trust boundary. + +## Depth And Progress + +Deserialization paths that recurse through objects, metadata, containers, or +references should enforce the runtime's configured depth limit before crafted +nesting can exhaust the call stack or bypass cleanup. A malformed input that +exceeds the configured depth should fail the root operation instead of +continuing unbounded recursion. + +Loops that consume encoded data should guarantee byte progress, logical +progress, or a terminal error. Inputs that can keep a reader in a no-progress +loop are security-relevant even when they do not allocate memory. + ## Security Invariants Deserialization code must prevent the following outcomes for untrusted input: diff --git a/docs/security/index.md b/docs/security/index.md index c75b583538..66f8cc7e59 100644 --- a/docs/security/index.md +++ b/docs/security/index.md @@ -3,9 +3,9 @@ title: Security sidebar_position: 1 --- -This directory documents Apache Fory security models and security invariants. -It is not a vulnerability disclosure area and does not list CVE details, -exploit samples, issue timelines, or implementation history. +This directory documents Apache Fory security models and security invariants. It +is not a vulnerability disclosure area and does not list CVE details, exploit +samples, issue timelines, or implementation history. Security model documents describe how Fory should classify and prevent security risks while preserving the performance characteristics expected from Fory @@ -13,4 +13,10 @@ serialization runtimes. ## Models -- [Deserialization Security Model](deserialization.md) +- [Threat Model](threat-model.md): project-level trust boundaries, non-goals, + and downstream responsibilities. +- [Deserialization Security Model](deserialization.md): concrete rules for + classifying and preventing untrusted deserialization risks. + +For vulnerability reporting, see the repository +[security policy](../../SECURITY.md). diff --git a/docs/security/threat-model.md b/docs/security/threat-model.md new file mode 100644 index 0000000000..5fea135056 --- /dev/null +++ b/docs/security/threat-model.md @@ -0,0 +1,95 @@ +--- +title: Threat Model +sidebar_position: 2 +--- + +This document describes Apache Fory's project-level security boundaries and +non-goals. It is the high-level entry point for Fory security models; concrete +untrusted deserialization classification rules live in the +[deserialization security model](deserialization.md). + +Fory is an in-process serialization library. Applications link Fory into their +own process, configure serializers and type policies, and call Fory APIs to +serialize application-owned objects or deserialize encoded Fory data. Fory does +not provide a standalone network service, daemon, authentication system, or +transport protocol. + +Fory can generate service companions for application-provided gRPC runtimes. +Those companions provide Fory serialization for request and response objects; +the application and gRPC stack still own listeners, channels, credentials, +authentication, authorization, deadlines, retries, and transport lifecycle. + +## Trust Boundaries + +Fory's primary security boundary is encoded bytes or streams passed to +deserialization APIs from untrusted or partially trusted sources. The embedding +application owns where those bytes come from and which Fory configuration, +registered types, schemas, and policies are used to read them. + +The adversary model for untrusted deserialization is a sender that can craft +encoded bytes or stream behavior presented to a Fory read API. It does not assume +the sender can change the embedding application's Fory configuration, registered +type set, `TypeChecker` or equivalent allow-list policy, schema definitions, +classloader, or other active policy objects unless the application itself exposes +those controls. + +Fory security boundaries include: + +- Runtime safety, including avoiding crashes, panics, undefined behavior, and + out-of-bounds memory access. +- Resource ownership, including memory, CPU progress, stream buffers, native + allocations, callbacks, and retained read-side state. +- Explicit Fory policy checks, such as class, type, function, method, + registration, or deserialization policies that restrict what may be + materialized. +- Cleanup boundaries, where state created during a failed root operation must + not leak into later operations. + +Runtime serializer code generation and JIT compilation are not paths for +executing encoded input. They operate on types and schemas after the active +registration check, `TypeChecker`, schema check, or policy check has accepted the +type surface. When class registration is disabled, `TypeChecker` or an +equivalent allow-list policy is the relevant gate. Generated serializer code is +derived from checked type descriptors rather than from attacker-controlled byte +contents. + +The [deserialization security model](deserialization.md) defines how to +classify these boundaries for untrusted deserialization paths. + +## Non-Goals + +Fory does not provide: + +- Encoded-data authenticity, integrity, confidentiality, signing, MACs, or + encryption. +- Transport security or protection for bytes while they are stored or moved + outside Fory, including transport security for generated service companions. +- Application-level authorization or validation for the business meaning of a + successfully deserialized value. +- A sandbox for user-registered classes, functions, constructors, setters, + finalizers, or other application-owned logic. + +Applications that receive Fory data from untrusted sources should authenticate +or integrity-check those bytes before passing them to Fory when authenticity or +tamper resistance matters. + +## Downstream Responsibilities + +Applications are responsible for: + +- Choosing whether a byte source is trusted enough for the configured + deserialization mode. +- Keeping class or type registration enabled for untrusted data unless another + explicit Fory policy owns the accepted type surface. +- Registering only types and serializers that are safe for the application's + trust boundary. +- Configuring depth and resource limits for the largest data shape the + application intends to accept. +- Treating cross-language peers and schemas as part of the application's trust + relationship. + +Disabling registration or using dynamic deserialization on trusted data is a +configuration choice. For untrusted data, bypassing an explicit Fory policy, +crashing, leaking resources, retaining attacker-controlled state, or allocating +disproportionately remains security-relevant as described in the +[deserialization security model](deserialization.md).