GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • java.evolved
  • ←
  • →

This view

  • Original page
  • New address

GeezerVison is showing javaevolved.dev — SecurityManager checks to explicit authorization | java.evolved

Home / Security / SecurityManager checks to explicit authorization
Security Advanced

SecurityManager checks to explicit authorization

  • 🐛 Report a code issue
  • 🌐 Report a translation issue
  • 💡 Suggest a new pattern

Replace disabled SecurityManager checks with explicit application authorization and deployment isolation.

Security Migration
Code Comparison
✕ JDK 23 and earlier
SecurityManager manager = System.getSecurityManager();
if (manager != null) {
    manager.checkRead(path.toString());
}
return Files.readString(path);
✓ JDK 24+
// Untrusted users must not be able to modify this tree
Path root = allowedRoot.toRealPath();
Path resolved = root.resolve(requested)
    .normalize()
    .toRealPath();
if (!resolved.startsWith(root)) {
    throw new SecurityException(
        "Path is outside the allowed root");
}
return Files.readString(resolved);
Share 𝕏
See a problem with this code? Let us know.
Why the modern way wins
🔍

Explicit policy

Authorization is visible and testable in application logic.

🛡️

Real isolation

Process, container, and operating-system boundaries protect the whole application.

🚫

Required migration

Removes checks that can no longer enforce policy on JDK 24 and later.

Old Approach
SecurityManager checks
Modern Approach
Explicit authorization
Since JDK
24
Difficulty
Advanced
JDK Support
SecurityManager checks to explicit authorization
Available

Required on JDK 24 and later, where JEP 486 permanently disables the Security Manager.

How it works

JEP 486 permanently disabled the Security Manager in JDK 24, so checks through System.getSecurityManager() can enforce policy only on JDK 23 and earlier. Applications must authorize access explicitly in domain logic; resolving real filesystem paths prevents existing symbolic links from escaping an allowed root when untrusted users cannot modify that tree concurrently. For attacker-writable trees, use race-resistant, handle-relative access such as SecureDirectoryStream. Use process, container, or operating-system boundaries for isolation. JDK 24 retains the deprecated API temporarily, but it cannot be enabled and is not replaced by another in-process sandbox.

Related Documentation
Permanently Disable the Security Manager (JEP 486) ↗ SecureDirectoryStream ↗
Proof
View proof source ↗
Related patterns
I/O Beginner

Reading files

Java 8
StringBuilder sb = new StringBuilder();
try (BufferedReader br =
    new BufferedReader(
        new FileReader("data.txt"))) {
    String line;
    while ((line = br.readLine()) != null)
        sb.append(line).append("\n");
}
String content = sb.toString();
Java 11+
String content =
    Files.readString(Path.of("data.txt"));
Hover to see modern ➜
JDK 11+ →
I/O Advanced

Deserialization filters

Java 8
// Dangerous: accepts any class
ObjectInputStream ois =
    new ObjectInputStream(input);
Object obj = ois.readObject();
// deserialization attacks possible!
Java 9+
ObjectInputFilter filter =
    ObjectInputFilter.Config
    .createFilter(
        "com.myapp.*;!*"
    );
ois.setObjectInputFilter(filter);
Object obj = ois.readObject();
Hover to see modern ➜
JDK 9+ →
Security Intermediate

TLS 1.3 by default

Java 8
SSLContext ctx =
    SSLContext.getInstance("TLSv1.2");
ctx.init(null, trustManagers, null);
SSLSocketFactory factory =
    ctx.getSocketFactory();
// Must specify protocol version
Java 11+
// TLS 1.3 is the default!
var client = HttpClient.newBuilder()
    .sslContext(SSLContext.getDefault())
    .build();
// Already using TLS 1.3
Hover to see modern ➜
JDK 11+ →
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.