pdf-via-chrome is a Java library for generating PDFs from HTML and URLs using headless Chrome. This document outlines security considerations when using the library and provides guidance for reporting vulnerabilities.
If you discover a security vulnerability in this project, please report it to us responsibly:
- Do not open a public GitHub issue
- Email security details to: [security contact email - to be configured]
- Include:
- Description of the vulnerability
- Steps to reproduce
- Potential impact
- Suggested remediation (if any)
We will acknowledge receipt within 48 hours and provide a detailed response within 5 business days.
Risk: When generating PDFs from URLs, malicious users could attempt to access internal network resources.
Built-in Protection:
- URLs are automatically validated before processing
- Private IP addresses are blocked (10.x.x.x, 192.168.x.x, 172.16-31.x.x)
- Localhost and loopback addresses are blocked (127.x.x.x, ::1)
- Link-local addresses are blocked (169.254.x.x, fe80::/10)
- Only HTTP and HTTPS protocols are allowed
- Hostnames are resolved to verify they don't point to private IPs
Additional Protection (optional):
// Use domain whitelist for strictest control
Set<String> allowedDomains = Set.of("example.com", "trusted.org");
UrlValidator.builder()
.url(userProvidedUrl)
.allowedDomains(allowedDomains)
.validate();
// Or use domain blacklist
Set<String> blockedDomains = Set.of("internal-site.com");
UrlValidator.builder()
.url(userProvidedUrl)
.blockedDomains(blockedDomains)
.validate();Recommendation:
- Always validate and sanitize user-provided URLs before processing
- Use domain whitelisting in production environments when possible
- Never allow PDF generation from arbitrary user-provided URLs without validation
Risk: Untrusted HTML content could contain malicious scripts or content.
Mitigation:
- Warning: This library does NOT sanitize HTML by default
- Chrome's headless mode executes JavaScript in the HTML
- Never generate PDFs from untrusted HTML without sanitization
- Consider using a library like OWASP Java HTML Sanitizer for untrusted content
Example with HTML Sanitization (requires adding com.googlecode.owasp-java-html-sanitizer dependency):
import org.owasp.html.PolicyFactory;
import org.owasp.html.Sanitizers;
// Sanitize untrusted HTML before PDF generation
PolicyFactory policy = Sanitizers.FORMATTING
.and(Sanitizers.LINKS)
.and(Sanitizers.BLOCKS);
String unsafeHtml = getUserInput(); // Potentially malicious
String safeHtml = policy.sanitize(unsafeHtml);
try (PdfGenerator generator = PdfGenerator.create().build()) {
byte[] pdf = generator.fromHtml(safeHtml).generate();
}Recommendation:
- Treat user-provided HTML as untrusted
- Sanitize HTML before PDF generation
- Consider disabling JavaScript for untrusted content
- Use Content Security Policy (CSP) headers when appropriate
Risk: Malicious inputs could cause excessive resource consumption.
Built-in Protection:
- Timeouts: All operations have configurable timeouts
- Default page load timeout: 30 seconds
- Default Chrome startup timeout: 45 seconds
- Chrome shutdown timeout: 5 seconds
- Process isolation: Each Chrome instance runs in a separate process
- Automatic cleanup: Resources are automatically released via AutoCloseable
Timeout Configuration:
// Configure custom timeouts
try (PdfGenerator generator = PdfGenerator.create()
.withTimeout(Duration.ofSeconds(60)) // Overall operation timeout
.build()) {
PageOptions pageOptions = PageOptions.builder()
.pageLoadTimeout(Duration.ofSeconds(30)) // Page load timeout
.build();
byte[] pdf = generator.fromUrl(url).generate();
}Additional Protection Recommendations:
// 1. Limit concurrent PDF generations
ExecutorService executor = Executors.newFixedThreadPool(5); // Max 5 concurrent PDFs
// 2. Implement request queuing with limits
BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(100);
ExecutorService limitedExecutor = new ThreadPoolExecutor(
2, 5, 60L, TimeUnit.SECONDS, queue,
new ThreadPoolExecutor.CallerRunsPolicy()
);
// 3. Monitor Chrome memory usage
// Chrome typically uses 100-200MB per instance
// Set JVM and system memory limits accordinglyRecommendation:
- Limit concurrent PDF generation operations
- Implement request queuing and rate limiting
- Monitor system resources (CPU, memory)
- Set appropriate timeouts for all operations
- Consider implementing circuit breakers for high-traffic scenarios
Risk: Running Chrome without sandboxing can expose the system to browser vulnerabilities.
Default Behavior:
- Chrome runs with sandbox ENABLED by default
- Sandbox provides process isolation and security
Docker/Container Environments:
- The
--no-sandboxflag is sometimes required in containers - Use with caution as it reduces security
// Only disable sandbox in trusted container environments
try (PdfGenerator generator = PdfGenerator.create()
.withNoSandbox(true) // ⚠️ Use only in trusted environments
.withDisableDevShmUsage(true) // For limited /dev/shm
.build()) {
// ...
}Recommendation:
- Keep sandbox enabled unless absolutely necessary
- Only disable in isolated, trusted environments (e.g., containers)
- Document why
--no-sandboxis required in your deployment - Consider security implications before disabling
Risk: Temporary files could contain sensitive data or be accessed by unauthorized users.
Built-in Protection:
- Chrome user data directories are created in system temp directory
- Temporary directories are automatically cleaned up on close
- Uses Java's
Files.createTempDirectory()with default permissions
Recommendation:
- Ensure system temp directory has appropriate permissions
- Clean up PDF data from memory when no longer needed
- Consider encrypting PDFs containing sensitive information
- Implement proper file system access controls
Built-in Protection:
- OWASP Dependency-Check runs automatically on
mvn verify - Build fails if critical/high vulnerabilities (CVSS ≥ 7) are found
- Dependencies are regularly updated
Check for Vulnerabilities:
# Run dependency vulnerability scan
mvn dependency-check:check
# View reports
# - target/dependency-check-report.html
# - target/dependency-check-report.jsonRecommendation:
- Run dependency scans regularly
- Keep dependencies up to date
- Review security advisories for Chrome and dependencies
- Subscribe to security mailing lists
General Recommendations:
// 1. Validate all user inputs
if (url == null || url.isBlank() || url.length() > 2048) {
throw new IllegalArgumentException("Invalid URL");
}
// 2. Limit HTML content size
if (html.length() > 1_000_000) { // 1MB limit
throw new IllegalArgumentException("HTML content too large");
}
// 3. Validate PDF options
PdfOptions options = PdfOptions.builder()
.scale(Math.max(0.1, Math.min(2.0, userScale))) // Clamp to valid range
.margins("1cm") // Use constants instead of user input
.build();
// 4. Sanitize file paths
Path outputPath = Paths.get(BASE_DIR, sanitizeFilename(userFilename));
if (!outputPath.startsWith(BASE_DIR)) {
throw new SecurityException("Path traversal attempt");
}- Enable URL validation with domain whitelisting
- Sanitize all user-provided HTML content
- Configure appropriate timeouts for all operations
- Implement rate limiting and request queuing
- Keep Chrome sandbox enabled (unless in trusted container)
- Run OWASP dependency scans in CI/CD pipeline
- Monitor system resources (CPU, memory, disk)
- Implement proper logging and alerting
- Use HTTPS for all URL-based PDF generation
- Encrypt PDFs containing sensitive data
- Implement proper access controls
- Regular security updates and patches
Implement multiple layers of security:
- Input Validation: Validate and sanitize all inputs
- SSRF Protection: Use URL whitelisting
- HTML Sanitization: Sanitize untrusted HTML
- Resource Limits: Implement timeouts and rate limiting
- Process Isolation: Chrome runs in separate process
- Monitoring: Track resource usage and failures
- Updates: Keep dependencies and Chrome up to date
-
JavaScript Execution: The library executes JavaScript in HTML by default
- Risk: Malicious scripts could access page content
- Mitigation: Sanitize HTML or disable JavaScript for untrusted content
-
Chrome Binary: The library depends on a Chrome/Chromium installation
- Risk: Vulnerabilities in Chrome affect the library
- Mitigation: Keep Chrome updated to latest stable version
-
Memory Usage: Chrome instances can use 100-200MB each
- Risk: High concurrent usage could exhaust memory
- Mitigation: Limit concurrent operations, monitor memory
| Version | Supported | Security Updates |
|---|---|---|
| 1.0.x | ✅ Yes | Yes |
| < 1.0 | ❌ No | No |
Security updates will be released as needed for supported versions. Critical vulnerabilities will be addressed within:
- Critical (CVSS 9.0-10.0): 24-48 hours
- High (CVSS 7.0-8.9): 1-2 weeks
- Medium (CVSS 4.0-6.9): 1 month
- Low (CVSS 0.1-3.9): Best effort
- OWASP Top 10
- OWASP SSRF Prevention Cheat Sheet
- OWASP HTML Sanitizer
- Chrome Security
- NVD - National Vulnerability Database
For security-related questions or concerns:
- Security issues: [security contact email]
- General questions: GitHub Issues
- Project maintainers: See CONTRIBUTORS.md