IronSoftwareA team building a financial reporting system chose Haukcode.DinkToPdf for its simplicity and zero...
A team building a financial reporting system chose Haukcode.DinkToPdf for its simplicity and zero licensing cost. Six months into production, a security audit flags CVE-2022-35583—a critical SSRF vulnerability in wkhtmltopdf with CVSS score 9.8. The vendor confirms the risk: malicious HTML can force the server to access internal network resources or local files. The wkhtmltopdf project archived in January 2023, so no patch exists. The team now faces a choice: accept the security risk, rebuild the entire reporting system with a different library, or implement extensive input sanitization that may still miss edge cases.
This scenario plays out repeatedly: teams adopt DinkToPdf/Haukcode.DinkToPdf for its straightforward API and free licensing, then discover the underlying wkhtmltopdf binary carries an unfixable critical vulnerability. The library itself is unmaintained—Haukcode.DinkToPdf package is deprecated on NuGet, and the original DinkToPdf stopped receiving updates in 2017.
IronPDF uses a Chromium rendering engine maintained and updated with browser security patches. Where Haukcode.DinkToPdf wraps an archived binary (wkhtmltopdf 0.12.6 from 2020), IronPDF's rendering engine receives ongoing updates. The architectural difference affects both security posture and rendering capabilities.
The ChromePdfRenderer class provides an API similar to DinkToPdf's converter pattern but without requiring manual native binary deployment or version management. Teams migrating from Haukcode.DinkToPdf typically find the code changes minimal, but the operational benefits—no manual binary management, no critical vulnerabilities—substantial.
Product Status: Deprecated on NuGet with warning "no longer maintained." Haukcode.DinkToPdf was itself a continuation of DinkToPdf which stopped in 2017. The underlying wkhtmltopdf project archived in January 2023 with last release 0.12.6 in 2020. No future updates or security patches possible. GitHub issues and pull requests go unanswered.
Missing Capabilities: Rendering engine based on QtWebKit which stopped development in 2012—predates modern CSS Grid, Flexbox improvements, and many CSS3 features. JavaScript execution limited to basic DOM manipulation—modern frameworks (React, Vue, Angular) don't work. Web font loading unreliable. SVG support limited. No built-in async operations—all conversions block calling thread. No built-in multi-threading safety—requires manual converter synchronization.
Technical Issues: wkhtmltopdf native binary (~40MB) requires manual deployment to application directory or system PATH. Platform-specific binaries needed (Windows .dll, Linux .so) with correct permissions. Thread safety issues require SynchronizedConverter wrapper and careful resource management. Memory leaks common when converter not properly disposed. Docker deployments require adding ~15 packages (libfontconfig, libfreetype, libx11, etc.). Frequent segmentation faults in native code that can crash entire process.
Support Status: No support available—project unmaintained. Community forums (Stack Overflow) show questions going unanswered. Forked versions exist but also unmaintained. Documentation consists of README and scattered blog posts from 2017-2019. No migration path to newer technology provided by maintainers.
Architecture Problems: P/Invoke wrapper means all HTML processing happens in unmanaged native code—debugging extremely difficult. Process crashes from wkhtmltopdf binary take down entire application. No graceful degradation for unsupported CSS—either renders or crashes. File permissions on Linux frequently cause "library not found" errors. Environment variables (LD_LIBRARY_PATH) often required on Linux.
Security Issues: CVE-2022-35583 (CVSS 9.8 Critical) - Server-Side Request Forgery vulnerability allows attackers to:
| Feature | Haukcode.DinkToPdf | IronPDF |
|---|---|---|
| Current Status | Deprecated/Unmaintained | Active |
| HTML Support | QtWebKit (2012) | Chromium (current) |
| Rendering Quality | Limited modern CSS | Pixel-perfect Chrome |
| Installation | NuGet + manual binary | NuGet only |
| Support | None | Standard included |
| Security | Critical CVE unfixable | Regular security updates |
using System;
using System.IO;
using DinkToPdf;
using DinkToPdf.Contracts;
namespace DinkToPdfExample
{
class Program
{
static void Main(string[] args)
{
// SECURITY WARNING: CVE-2022-35583 - Do not use in production
// Malicious HTML can exploit SSRF vulnerability
// Must manually deploy wkhtmltopdf binary to:
// Windows: bin/Debug/net6.0/libwkhtmltox.dll
// Linux: /usr/lib/libwkhtmltox.so (or set LD_LIBRARY_PATH)
try
{
// Create converter
// BasicConverter for single-threaded use
// SynchronizedConverter for multi-threaded (but still has issues)
var converter = new BasicConverter(new PdfTools());
// Configure document
var doc = new HtmlToPdfDocument
{
GlobalSettings = new GlobalSettings
{
ColorMode = ColorMode.Color,
Orientation = Orientation.Portrait,
PaperSize = PaperKind.A4,
Margins = new MarginSettings
{
Top = 10,
Bottom = 10,
Left = 10,
Right = 10
}
},
Objects =
{
new ObjectSettings
{
HtmlContent = @"
<html>
<head><style>body { font-family: Arial; }</style></head>
<body><h1>Hello from DinkToPdf</h1></body>
</html>"
}
}
};
// Convert - blocks calling thread
byte[] pdfBytes = converter.Convert(doc);
// Save to file
File.WriteAllBytes("output.pdf", pdfBytes);
Console.WriteLine("PDF created");
}
catch (DllNotFoundException)
{
Console.WriteLine("ERROR: wkhtmltopdf binary not found");
Console.WriteLine("Ensure libwkhtmltox is in application directory or system PATH");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
// Native crashes often provide minimal error information
}
}
}
}
Benchmark observations (1000 simple HTML pages, Windows Server 2019, 4-core):
Technical limitations:
using System;
using IronPdf;
namespace IronPdfExample
{
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(@"
<html>
<head><style>body { font-family: Arial; }</style></head>
<body><h1>Hello from IronPDF</h1></body>
</html>");
pdf.SaveAs("output.pdf");
}
}
}
Benchmark observations (1000 simple HTML pages, same hardware):
Comparison summary:
For detailed HTML rendering, see the HTML string to PDF guide.
using System;
using System.IO;
using DinkToPdf;
using DinkToPdf.Contracts;
namespace DinkToPdfUrlExample
{
class Program
{
static void Main(string[] args)
{
try
{
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument
{
GlobalSettings = new GlobalSettings
{
ColorMode = ColorMode.Color,
Orientation = Orientation.Portrait,
PaperSize = PaperKind.Letter
},
Objects =
{
new ObjectSettings
{
// URL instead of HtmlContent
Page = "https://example.com",
// JavaScript delay (milliseconds)
// QtWebKit JS support limited
JavaScriptDelay = 1000,
// Load error handling
LoadSettings = new LoadSettings
{
// Network timeout
// No retry logic available
}
}
}
};
byte[] pdfBytes = converter.Convert(doc);
File.WriteAllBytes("url_output.pdf", pdfBytes);
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
// Common errors:
// - Network timeout (no configuration options)
// - HTTPS certificate validation failures
// - JavaScript not executing
}
}
}
}
Benchmark observations (100 live URLs with JavaScript):
Technical limitations:
using System;
using IronPdf;
namespace IronPdfUrlExample
{
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.Timeout = 120;
renderer.RenderingOptions.WaitFor.RenderDelay(50);
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("url_output.pdf");
}
}
}
Benchmark observations (same 100 URLs):
For URL rendering with authentication, see the URL to PDF documentation.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using DinkToPdf;
using DinkToPdf.Contracts;
namespace DinkToPdfBatchExample
{
class Program
{
static void Main(string[] args)
{
// Create thread-safe converter
var converter = new SynchronizedConverter(new PdfTools());
var htmlPages = new List<string>();
for (int i = 0; i < 100; i++)
{
htmlPages.Add($"<html><body><h1>Page {i}</h1></body></html>");
}
var stopwatch = Stopwatch.StartNew();
// Parallel processing
Parallel.ForEach(htmlPages, new ParallelOptions { MaxDegreeOfParallelism = 4 },
(html, state, index) =>
{
try
{
var doc = new HtmlToPdfDocument
{
GlobalSettings = new GlobalSettings
{
PaperSize = PaperKind.A4
},
Objects =
{
new ObjectSettings { HtmlContent = html }
}
};
// SynchronizedConverter serializes all calls internally
// Parallel.ForEach doesn't actually help performance
byte[] pdfBytes = converter.Convert(doc);
File.WriteAllBytes($"output_{index}.pdf", pdfBytes);
}
catch (Exception ex)
{
Console.WriteLine($"Page {index} failed: {ex.Message}");
}
});
stopwatch.Stop();
Console.WriteLine($"Completed in {stopwatch.ElapsedMilliseconds}ms");
}
}
}
Benchmark observations (100 pages):
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using IronPdf;
namespace IronPdfBatchExample
{
class Program
{
static void Main(string[] args)
{
var htmlPages = new List<string>();
for (int i = 0; i < 100; i++)
{
htmlPages.Add($"<html><body><h1>Page {i}</h1></body></html>");
}
var stopwatch = Stopwatch.StartNew();
Parallel.ForEach(htmlPages, new ParallelOptions { MaxDegreeOfParallelism = 4 },
(html, state, index) =>
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs($"output_{index}.pdf");
});
stopwatch.Stop();
Console.WriteLine($"Completed in {stopwatch.ElapsedMilliseconds}ms");
}
}
}
Benchmark observations (same 100 pages):
For batch processing details, see the ChromePdfRenderer documentation.
FROM mcr.microsoft.com/dotnet/aspnet:6.0
# Install wkhtmltopdf dependencies (15+ packages)
RUN apt-get update && apt-get install -y \
libfontconfig1 \
libfreetype6 \
libx11-6 \
libxext6 \
libxrender1 \
libjpeg62-turbo \
libpng16-16 \
libssl1.1 \
ca-certificates \
fonts-liberation \
fontconfig \
wget \
&& rm -rf /var/lib/apt/lists/*
# Download and install wkhtmltopdf binary
RUN wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.buster_amd64.deb \
&& apt install -y ./wkhtmltox_0.12.6-1.buster_amd64.deb \
&& rm wkhtmltox_0.12.6-1.buster_amd64.deb
WORKDIR /app
COPY . .
ENTRYPOINT ["dotnet", "MyApp.dll"]
Docker image sizes:
FROM ironsoftwareofficial/ironpdfengine:latest
WORKDIR /app
COPY . .
ENTRYPOINT ["dotnet", "MyApp.dll"]
Docker image sizes:
| Haukcode.DinkToPdf Operation | IronPDF Equivalent |
|---|---|
new SynchronizedConverter(new PdfTools()) |
new ChromePdfRenderer() |
new HtmlToPdfDocument() |
Implicit in Render methods |
GlobalSettings.PaperSize |
renderer.RenderingOptions.PaperSize |
GlobalSettings.Orientation |
renderer.RenderingOptions.PaperOrientation |
GlobalSettings.Margins |
renderer.RenderingOptions.Margin* |
ObjectSettings.HtmlContent |
renderer.RenderHtmlAsPdf(html) |
ObjectSettings.Page (URL) |
renderer.RenderUrlAsPdf(url) |
ObjectSettings.JavaScriptDelay |
renderer.RenderingOptions.WaitFor.RenderDelay() |
converter.Convert(doc) |
Implicit in Render methods |
File.WriteAllBytes(path, bytes) |
pdf.SaveAs(path) |
| Manual binary deployment | Not required |
| Platform-specific dependencies | Not required |
| Category | Feature | Haukcode.DinkToPdf | IronPDF |
|---|---|---|---|
| Status | Active Development | Deprecated | Active |
| Product Maintenance | None since 2018 | Ongoing | |
| Security Updates | None possible | Regular | |
| Rendering Engine | QtWebKit (2012) | Chromium (current) | |
| Support | Community Forum | Dead | Active |
| Commercial Support | Not available | Included | |
| Documentation | README only | Comprehensive | |
| Code Examples | Minimal | Extensive | |
| Content Creation | HTML5 Support | Very limited | Full |
| CSS3 Support | Minimal | Complete | |
| JavaScript | Basic (outdated) | Full V8 | |
| Modern Frameworks | Not supported | Excellent | |
| Web Fonts | Unreliable | Automatic | |
| SVG | Limited | Full | |
| Performance | Render Speed | Slow | Fast (2.7x) |
| Memory Efficiency | Poor (leaks) | Excellent | |
| Multi-threading | Fake (serialized) | True parallel | |
| Failure Rate | 3.2% | 0% | |
| Security | CVE-2022-35583 | CRITICAL UNFIXABLE | Not affected |
| SSRF Protection | None | Protected | |
| Regular Updates | Never | Yes | |
| Installation | Complexity | High | Low |
| Native Binary | Manual 40MB deployment | Not required | |
| System Dependencies | 15+ packages | None | |
| Docker Image | 420MB | 190MB | |
| Known Issues | DLL not found | Frequent | Not applicable |
| Segmentation faults | Common | Not applicable | |
| Memory leaks | Known issue | Not present | |
| Thread crashes | Documented | Not applicable | |
| Development | Learning Curve | Moderate | Shallow |
| Debugging | Impossible (native) | Standard .NET | |
| Error Messages | Cryptic/none | Detailed |
CVE-2022-35583 (Critical - CVSS 9.8): Server-Side Request Forgery—malicious HTML can access internal network, read local files. NO FIX AVAILABLE.
Segmentation faults: Native wkhtmltopdf binary crashes with segfaults approximately 2-3 times per 1000 conversions, taking down entire application.
Memory leaks: Documented leaks in native code accumulate over time, requiring periodic application restarts.
Thread safety: SynchronizedConverter serializes all operations internally—Parallel.ForEach provides minimal benefit (~3% improvement).
Binary deployment failures: Incorrect wkhtmltopdf binary version or missing system dependencies cause DllNotFoundException with minimal diagnostic info.
Linux dependency hell: Requires 15+ system packages with specific versions—missing or wrong versions cause silent failures.
Network timeouts: No retry logic—temporary network issues cause conversion failures.
JavaScript failures: QtWebKit from 2012 fails on modern JavaScript—React/Vue/Angular don't execute.
Docker image bloat: Dependencies add 240MB to image size.
No error isolation: Native crashes propagate to .NET application, no way to isolate failures.
Haukcode.DinkToPdf:
dotnet add package Haukcode.DinkToPdf
# Manual steps:
# Windows:
# 1. Download libwkhtmltox.dll from wkhtmltopdf releases
# 2. Copy to bin/Debug or bin/Release directory
# 3. Ensure 64-bit if running 64-bit app
# Linux:
# 1. Install dependencies:
sudo apt-get install -y libfontconfig1 libfreetype6 libx11-6 \
libxext6 libxrender1 libjpeg62-turbo libpng16-16 \
libssl1.1 fonts-liberation fontconfig
# 2. Download and install .deb package
wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.buster_amd64.deb
sudo apt install -y ./wkhtmltox_0.12.6-1.buster_amd64.deb
using DinkToPdf;
using DinkToPdf.Contracts;
IronPDF:
dotnet add package IronPdf
using IronPdf;
using IronPdf.Rendering;
Haukcode.DinkToPdf served teams well when it was actively maintained and before the security landscape changed. For legacy applications where migration isn't immediately possible and the SSRF vulnerability is mitigated through strict input sanitization, it may continue functioning. However, the project is officially deprecated, unmaintained, and built on an archived binary with an unfixable critical security vulnerability.
Migration from Haukcode.DinkToPdf to IronPDF is necessary for any production system exposed to untrusted HTML input. The CVE-2022-35583 SSRF vulnerability (CVSS 9.8) allows attackers to access internal networks, read local files, and bypass firewalls—and will never be patched. Beyond security, the performance benchmarks show IronPDF delivering 2.7x faster rendering with zero failures compared to DinkToPdf's 3.2% failure rate and native crashes.
IronPDF's migration path is straightforward—the API patterns are similar, but without native binary deployment or system dependency management. The ChromePdfRenderer provides modern CSS3 and JavaScript support that QtWebKit (2012) cannot match. For teams currently using DinkToPdf/Haukcode.DinkToPdf, reviewing the migration timeline is critical given the security implications. See the complete migration guide for step-by-step instructions, and review ChromePdfRenderer API documentation for feature details.
Are you currently using DinkToPdf/Haukcode.DinkToPdf in production? What's blocking your migration timeline?