Threat model
Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.
Netty's role in a typical application consists of:
- An event loop group, managing multiple event loops.
- Each event loop managing multiple channels.
- Each channel has a pipeline of handles.
- The handlers process input data, and produce output data.
- Netty includes a suite of standard handles for HTTP parsing/encoding, compression, DNS, and TLS, among others.
- The data is moved in from/out of the network through buffers from Netty's memory allocators.
block-beta
    columns 1
    block:loops
        columns 5
        space:2
        evg("Event Loop Group")
        space:7
        ev1("Event Loop")
        space
        ev2("Event Loop")
        space
        ev3("Event Loop")
        c1[["channel"]]
        space
        c2[["channel"]]
        space
        c3[["channel"]]
        p1[/"pipeline"/]
        space
        p2[/"pipeline"/]
        space
        p3[/"pipeline"/]
    end
    block:pipeline
        columns 5
        space:2
        cp("Channel Pipeline")
        space:2
        h1[/"Head (I/O)"/]
        h2[/"TLS"/]
        h3[/"HTTP"/]
        h4[/"App Logic"/]
        h5[/"Tail (Errors)"/]
    end
    p1 --> h1
    h1-->h2
    h2-->h1
    h2-->h3
    h3-->h2
    h3-->h4
    h4-->h3
    h4-->h5
    style evg fill:none,stroke:none;
    style cp fill:none,stroke:none;
    Besides the prominent components above, Netty includes many other codecs; HTTP/2, HTTP/3, QUIC, DNS, JBoss Marshalling, MQTT, Protobuf, Redis, SMTP, SOCKS, STOMP, HAProxy, Memcache, JSON, XML, and length or delimiter based framing codecs. The event loops communicate with the operating system to perform I/O using various transports; epoll, kqueue, NIO, io_uring, most of which involve Netty-maintained native code. Lastly, Netty can make use of native TLS implementations, like BoringSSL, AWS-LC, and OpenSSL, which also involve native code.
Netty, as a framework, operates with two boundaries:
- The external boundary, where calls are made into the operating system to perform I/O and move data into and out of the system process.
- The internal boundary, where the application is integrating with Netty and calling Netty APIs in order the serve their networking use cases.
Data moving through the external boundary is generally untrusted, and must go through validation and authentication steps as appropriate for the application, before its processed by the application.
Data moving through the internal boundary is generally trusted, but validated where possible.
As a low-level networking API, we cannot stop integrators from sending arbitrary data on connections that are supposed to follow a specific protocol. However, we can, for instance, validate HTTP headers when these pass through our HTTP APIs.
Private key material. When Netty is configured to use TLS in either server mode, or in authenticated client mode, it must be able to present a certificate and either have access to the corresponding private key, or have access to a TPM/HSM has manages the private key.
The private key material is accessed either as files, as a KeyManager instance, or as an OpenSslAsyncPrivateKeyMethod callback.
These types cannot normally be sent to the network through standard channel methods, e.g. files must be sent as FileRegion objects, and thus accidental leakage of this information is prevented.
Application data. Applications can configure their pipelines to handle arbitrary protocols, including completely custom protocols, and not just HTTP with or without TLS.
Netty cannot tell what data is sensitive and what is not, or what data is intended for which peers. We can only encourage safe defaults, and design our APIs such that the easiest way to do something is also the safest way.
To this end, codecs should validate all inputs, and apply sane resource limits when decoding.
Resource limits include both limiting CPU expenditure relative to input size, i.e. preventing attacks like MadeYouReset, and memory consumption, i.e. zip-bombs.
When encoding, all outbound objects should be validated, to prevent injection or parser-desync attacks.
Netty also checks offset- and lifetime-bounds of every memory access through its ByteBuf type, ensuring memory safety of off-heap memory usage.
Some codecs rely on discouraged technologies, such as Java serialization. We've deprecated all APIs that are considered a security liability, and encourage downstream projects to read our deprecation warnings.
Tracking data provenance and access controls is, however, out of scope for Netty.
Process information. Netty does not expose or exfiltrate any information about the application process in any way. Netty make some JMX beans available, to expose metrics about its memory allocators for instance, but exposing these beans through the JMX metrics system is opt-in and requires intentional program code to make happen.
Netty also include some JFR events, but these do not include any application information, and they are also disabled by default. Note that JFR, when using its default profiles, will include a wide range of process information, and may not be safe to share publicly.
Dependencies.
Netty intentionally depend on as few other libraries as possible.
This limits our exposure to supply-chain attacks.
Our maven build tool binary is downloaded by mvnw over HTTPS and verified by a SHA-512 checksum.
The main dependencies involved are JCTools, BoringSSL, and BouncyCastle.
Our HTTP/3 and QUIC implementations depend on Quiche, by Cloudflare.
Our compression codecs pull in dependencies for their respective compression algorithms.
We rely on Dependabot for timely notification of security issues in these dependencies.
Network access.
Netty inherently involves accessing the network, which is what Netty is managing on behalf of the application.
Netty will only establish connections and perform I/O as instructed by the application.
Preventing unauthorized access is generally out of scope for Netty, since Netty don't know what rules to apply.
Applications that wish to guard against, e.g. Server-Side Request Forgery attacks, can install an IpSubnetFilter handler into their pipeline, to ensure that network communications are only directed to endpoints that are expected for a given application.
Netty Build Artifacts. As Netty is so widely used, and is a critical component of many application, it's important that people can trust the build artifacts we release.
To ensure these are trustworthy, a number of checks and mechanisms are in place:
- Pull requests from people not in the "Owner" github group are always reviewed before merging.
- All release builds are signed.
- The release process is fully automated and runs on GitHub Actions, and are manually triggered by a maintainer.
- Maven Central authenticates the publishing user account and validates the build artifacts, before the artifacts become public.
- Publishing access is protected by GitHub Secrets.