# How IPED Handles Security: Custom SecurityManager and Policy Sandbox

> Discover how IPED secures its runtime with a custom SecurityManager and Policy Sandbox, blocking network access by default while whitelisting essential hosts for safe operation.

- Repository: [Serviço de Perícias em Informática/IPED](https://github.com/sepinf-inc/IPED)
- Tags: internals
- Published: 2026-03-11

---

**IPED secures its runtime by installing a custom Java `SecurityManager` with a restrictive `Policy` that blocks all network access from HTML viewers while dynamically whitelisting specific hosts like MinIO storage.**

The `sepinf-inc/IPED` (Indexador e Processador de Evidências Digitais) is an open-source digital forensics platform designed to process and analyze digital evidence securely. Given that forensic examiners routinely handle potentially malicious HTML content and untrusted documents, IPED implements a robust security sandbox to prevent data exfiltration. This article explores the technical implementation of IPED's security model, examining how the engine configures a custom `Policy` and `SecurityManager` to restrict network permissions while preserving essential functionality.

## Bootstrap Security Initialization

During application startup, IPED configures its security sandbox in the `Configuration.loadConfigurables()` method located in [`iped-engine/src/main/java/iped/engine/config/Configuration.java`](https://github.com/sepinf-inc/IPED/blob/main/iped-engine/src/main/java/iped/engine/config/Configuration.java). After loading configuration files, the engine instantiates `DefaultPolicy`—a custom subclass of `java.security.Policy`—and installs it as the system-wide security policy.

If **MinIO** distributed storage is enabled, the bootstrap code dynamically extends the policy whitelist. It extracts the host and port from `MinIOConfig`, strips any protocol prefixes, and grants a restricted `SocketPermission` allowing only `connect,resolve` operations:

```java
// iped-engine/src/main/java/iped/engine/config/Configuration.java
// lines 228-240
DefaultPolicy policy = new DefaultPolicy();
MinIOConfig minIOConfig = configManager.findObject(MinIOConfig.class);
if (minIOConfig.isEnabled()) {
    String host = minIOConfig.getHostAndPort();
    if (host.startsWith("http://") || host.startsWith("https://")) {
        host = host.substring(host.indexOf("://") + 3);
    }
    policy.addAllowedPermission(new SocketPermission(host, "connect,resolve"));
}
Policy.setPolicy(policy);
System.setSecurityManager(new SecurityManager());

```

This initialization sequence ensures that the restrictive security model is active before any untrusted content is loaded, while still permitting necessary connections to external storage infrastructure.

## DefaultPolicy: Restricting HTML Viewer Network Access

The core security logic resides in [`DefaultPolicy.java`](https://github.com/sepinf-inc/IPED/blob/main/DefaultPolicy.java) within the viewers module ([`iped-viewers/iped-viewers-impl/src/main/java/iped/viewers/util/DefaultPolicy.java`](https://github.com/sepinf-inc/IPED/blob/main/iped-viewers/iped-viewers-impl/src/main/java/iped/viewers/util/DefaultPolicy.java)). This policy maintains a runtime-extensible whitelist of allowed permissions through the `addAllowedPermission()` method, while implementing strict denial rules for untrusted code sources.

### Blocking Malicious Network Calls

In the `implies(ProtectionDomain, Permission)` method, the policy evaluates every permission request against two criteria. First, it checks the dynamically managed whitelist. Then, it specifically identifies permissions originating from the HTML viewer component (`iped.viewers.HtmlViewer`). Any `SocketPermission` or `URLPermission` requested by the HTML viewer is explicitly denied, preventing malicious HTML content from initiating outbound connections or accessing arbitrary URLs:

```java
// iped-viewers/iped-viewers-impl/src/main/java/iped/viewers/util/DefaultPolicy.java
// lines 44-62
@Override
public boolean implies(ProtectionDomain domain, Permission perm) {
    // … whitelist handling …
    URI from = URLUtil.getURL(domain).toURI();
    if (from.equals(viewer) && (perm instanceof SocketPermission || perm instanceof URLPermission)) {
        return false;               // deny network access from HtmlViewer
    }
    return true;
}

```

This implementation creates an effective sandbox around the HTML rendering components, ensuring that evidence files cannot phone home or transfer data to external servers during examination.

## Debugging and Profiling Exceptions

The security policy includes specific accommodations for development and monitoring tools. In the `getPermissions(CodeSource)` method, the policy detects when code is being loaded by VisualVM or similar profiling tools through the RMI loader handler. When the stack trace contains `sun.rmi.server.LoaderHandler.loadClass`, the method returns an empty `Permissions` set, allowing the profiler to attach without triggering security exceptions:

```java
// iped-viewers/iped-viewers-impl/src/main/java/iped/viewers/util/DefaultPolicy.java
// lines 73-80
@Override
public PermissionCollection getPermissions(CodeSource codeSource) {
    Thread thread = Thread.currentThread();
    for (StackTraceElement e : thread.getStackTrace()) {
        if ("sun.rmi.server.LoaderHandler".equals(e.getClassName())
                && "loadClass".equals(e.getMethodName())) {
            return new Permissions(); // allow VisualVM
        }
    }
    return super.getPermissions(codeSource);
}

```

This exception ensures that forensic investigators can monitor application performance and debug issues without disabling the security sandbox entirely.

## Practical Security Management Examples

When extending IPED or integrating custom components, developers may need to interact with the security policy programmatically.

### Adding Runtime Permissions

To grant network access to a specific host for a custom plugin, cast the current policy to `DefaultPolicy` and add the permission:

```java
// Somewhere in a plugin or custom task
DefaultPolicy policy = (DefaultPolicy) Policy.getPolicy();
policy.addAllowedPermission(new SocketPermission("example.com:443", "connect,resolve"));

```

### Verifying Permission Grants

For debugging security configurations, you can programmatically check whether a specific permission would be granted to a particular code source:

```java
Policy policy = Policy.getPolicy();
Permission p = new SocketPermission("malicious.com:80", "connect");
boolean granted = policy.implies(Policy.getPolicy().getPermissions(
        new CodeSource(new URL("file:/some/Path"), (Certificate[]) null)), p);
System.out.println("Permission granted? " + granted); // will print false for HTML viewer

```

### Disabling Security (Trusted Environments Only)

In controlled, trusted environments where the security sandbox interferes with debugging, you can disable the `SecurityManager` entirely. **Warning:** This removes all network restrictions and exposes the system to potential data exfiltration from malicious content.

```java
// Early in the startup code, before any viewer is created
System.setSecurityManager(null);

```

## Key Implementation Files

The security architecture spans several critical files in the IPED repository:

- **[`DefaultPolicy.java`](https://github.com/sepinf-inc/IPED/blob/main/DefaultPolicy.java)** ([`iped-viewers/iped-viewers-impl/src/main/java/iped/viewers/util/DefaultPolicy.java`](https://github.com/sepinf-inc/IPED/blob/main/iped-viewers/iped-viewers-impl/src/main/java/iped/viewers/util/DefaultPolicy.java)): Implements the custom `Policy` class that blocks network access from HTML viewers and maintains the permission whitelist.
- **[`Configuration.java`](https://github.com/sepinf-inc/IPED/blob/main/Configuration.java)** ([`iped-engine/src/main/java/iped/engine/config/Configuration.java`](https://github.com/sepinf-inc/IPED/blob/main/iped-engine/src/main/java/iped/engine/config/Configuration.java)): Bootstraps the security system by instantiating `DefaultPolicy`, configuring MinIO permissions, and installing the `SecurityManager`.
- **[`MinIOConfig.java`](https://github.com/sepinf-inc/IPED/blob/main/MinIOConfig.java)** ([`iped-engine/src/main/java/iped/engine/config/MinIOConfig.java`](https://github.com/sepinf-inc/IPED/blob/main/iped-engine/src/main/java/iped/engine/config/MinIOConfig.java)): Provides storage configuration values used to dynamically whitelist MinIO hosts during security initialization.
- **[`MinIOTask.java`](https://github.com/sepinf-inc/IPED/blob/main/MinIOTask.java)** ([`iped-engine/src/main/java/iped/engine/task/MinIOTask.java`](https://github.com/sepinf-inc/IPED/blob/main/iped-engine/src/main/java/iped/engine/task/MinIOTask.java)): Example task that interacts with MinIO storage within the established security constraints.
- **[`HtmlViewer.java`](https://github.com/sepinf-inc/IPED/blob/main/HtmlViewer.java)** ([`iped-viewers/iped-viewers-api/src/main/java/iped/viewers/api/HtmlViewer.java`](https://github.com/sepinf-inc/IPED/blob/main/iped-viewers/iped-viewers-api/src/main/java/iped/viewers/api/HtmlViewer.java)): The viewer interface whose code source is specifically targeted by the restrictive policy to prevent network operations.

## Summary

- IPED installs a **custom `SecurityManager`** and **`DefaultPolicy`** during bootstrap in [`Configuration.java`](https://github.com/sepinf-inc/IPED/blob/main/Configuration.java) to create a security sandbox before loading evidence files.
- The **`DefaultPolicy.implies()`** method blocks all `SocketPermission` and `URLPermission` requests originating from `HtmlViewer`, preventing malicious HTML content from accessing the network.
- **Dynamic whitelisting** allows specific hosts (such as MinIO storage servers) to be granted `connect,resolve` permissions at runtime based on configuration.
- **VisualVM profiling** is supported through a stack trace inspection in `getPermissions()` that returns empty permissions for RMI loader contexts.
- Developers can **extend permissions** at runtime using `addAllowedPermission()` or **disable security entirely** (not recommended for production) using `System.setSecurityManager(null)`.

## Frequently Asked Questions

### How does IPED prevent malicious HTML files from leaking data?

IPED prevents data exfiltration by implementing a custom Java `Policy` class (`DefaultPolicy`) that explicitly denies all `SocketPermission` and `URLPermission` requests originating from the `HtmlViewer` component. When the HTML viewer attempts to open a network connection or access a URL, the policy's `implies()` method detects the viewer's code source and returns `false`, blocking the operation while allowing the application to continue running.

### Can I allow specific network connections while keeping the IPED security sandbox active?

Yes, you can dynamically extend the whitelist by calling `addAllowedPermission()` on the `DefaultPolicy` instance. For example, if your plugin needs to connect to a specific API endpoint, you can cast `Policy.getPolicy()` to `DefaultPolicy` and add a `SocketPermission` for that specific host and port. This approach maintains the restrictive sandbox for HTML viewers while granting necessary access to trusted components.

### Why does IPED make an exception for VisualVM in the security policy?

The `DefaultPolicy.getPermissions()` method includes a special check for the `sun.rmi.server.LoaderHandler.loadClass` stack trace element to accommodate Java profiling and debugging tools like VisualVM. Without this exception, the restrictive policy would prevent the RMI class loader from functioning, blocking profilers from attaching to the running IPED process. This exception only applies to the specific RMI loading context and does not weaken the sandbox for viewer components.

### Is it safe to disable the IPED SecurityManager in production environments?

No, disabling the `SecurityManager` using `System.setSecurityManager(null)` removes the network isolation layer and should only be done in isolated, trusted debugging environments. Without this security layer, malicious HTML evidence files could open arbitrary network connections to exfiltrate data, download additional payloads, or communicate with command-and-control servers during forensic examination.