---
title: "Secure Java engineering"
chapter: "15"
---

# Secure Java engineering

Security starts with supported software, minimal input trust, safe dependencies,
and protected secrets.

## Patch and supply chain

Run a supported JDK and update security patches promptly. Pin and verify build
toolchains and dependencies. Generate an SBOM, scan artifacts, review
transitive dependencies, sign/prove releases, and keep rollback artifacts.

## Input and output

Validate size, type, range, encoding, and business rules. Use parameterized SQL,
safe output encoding, and allow-list validation for structured identifiers.
Avoid shell construction; use `ProcessBuilder` with separate arguments only
when a process is truly necessary.

## Deserialization and XML

Never deserialize untrusted native Java objects. Apply filters for legacy use.
Configure XML parsers to block external entities and unwanted external access.
Limit nested structures and decompression.

## Cryptography

Use standard high-level protocols and modern library/provider defaults.
Generate secrets with `SecureRandom`, use authenticated encryption, store keys
outside source code, rotate keys, and never invent a cryptographic algorithm.
Passwords need adaptive password hashing, not reversible encryption.

## Secrets and logs

Do not place secrets in command lines, source, images, stack traces, heap dumps,
or logs. Redact tokens and sensitive values. Zeroing a `char[]` can reduce
exposure but does not solve every copy in memory.

## Least privilege

Run as a non-root OS user, restrict filesystem/network access, minimize modules
and native libraries, and isolate high-risk parsing. The legacy Security
Manager is not a modern sandbox strategy.

## Feynman check

Treat every external byte as an unopened package. Check the sender, size, label,
and allowed contents before opening it in a restricted room.
