Haukcode.DinkToPdf vs IronPDF: CVE-2022-35583, LOPDGDD y Facturae en .NET
Cuando los desarrolladores .NET buscan opciones de generación de PDF, Haukcode.DinkToPdf destaca como continuación del proyecto discontinuado DinkToPdf, que utiliza el binario wkhtmltopdf. Aunque Haukcode.DinkToPdf ofrece una conversión básica de HTML a PDF, conlleva importantes riesgos de seguridad derivados de wkhtmltopdf que nunca se solucionarán debido a la interrupción del proyecto.IronPDFpresenta una opción diferente: una biblioteca mantenida activamente que utiliza un moderno motor Chromium con actualizaciones de seguridad periódicas.
Esta comparación revisa ambas bibliotecas en aspectos técnicos relevantes para ayudar a los desarrolladores y arquitectos a tomar decisiones informadas para sus necesidades de .NET PDF.
Para los equipos de desarrollo que operan en España, la elección adquiere una dimensión adicional: la vulnerabilidad CVE-2022-35583 no es únicamente un riesgo técnico abstracto. Bajo el Reglamento General de Protección de Datos y su trasposición española en la LOPDGDD, una brecha de datos causada por SSRF desencadena obligaciones de notificación a la Agencia Española de Protección de Datos (AEPD) en 72 horas y puede suponer sanciones de hasta 20 millones de euros según el artículo 83 del RGPD. Organizaciones sujetas al Esquema Nacional de Seguridad (ENS) en categoría alta tienen explícitamente prohibido mantener en producción bibliotecas con vulnerabilidades críticas sin parche. Asimismo, aplicaciones que generan documentos fiscales para la Agencia Estatal de Administración Tributaria (AEAT) — incluyendo facturas electrónicas Facturae, registros VeriFactu o envíos al Suministro Inmediato de Información (SII) — están expuestas a la extracción de credenciales de API fiscales si un atacante explota el SSRF.
Explorando Haukcode.DinkToPdf
Haukcode.DinkToPdf es la continuación de la popular biblioteca DinkToPdf, basada en el binario wkhtmltopdf, ya desaparecido. La biblioteca pretende seguir siendo compatible con .NET Core y, al mismo tiempo, ofrecer conversión de HTML a PDF. Como continuación de un proyecto abandonado, Haukcode.DinkToPdf tiene notables limitaciones.
Haukcode.DinkToPdf utiliza SynchronizedConverter con PdfTools para la conversión. La configuración se gestiona a través de objetos HtmlToPdfDocument que contienen GlobalSettings para opciones de página (ColorMode, Orientation, PaperSize, Margins) y ObjectSettings para contenido (HtmlContent para cadenas HTML, Page para URLs). El método converter.Convert(doc) devuelve datos crudos de byte[].
La biblioteca requiere binarios nativos específicos para la plataforma: libwkhtmltox.dll (Windows), libwkhtmltox.so (Linux) y libwkhtmltox.dylib (macOS). La seguridad de los hilos requiere usar el SynchronizedConverter en un patrón singleton debido a las limitaciones de wkhtmltopdf.
Explorando IronPDF
IronPDF es una biblioteca .NET desarrollada de forma independiente que utiliza un moderno motor de renderizado Chromium. La biblioteca se mantiene activamente con actualizaciones periódicas, soporte profesional y continuos parches de seguridad.
IronPDF utiliza ChromePdfRenderer como su clase de renderización principal con configuración a través de propiedades RenderingOptions. Métodos como RenderHtmlAsPdf() y RenderUrlAsPdf() devuelven objetos PdfDocument que se pueden guardar con SaveAs() o acceder como BinaryData. La biblioteca es autónoma, sin necesidad de binarios nativos externos, y está diseñada a prueba de hilos sin requerir patrones singleton.
La consideración crítica de seguridad
La diferencia más significativa entre estas bibliotecas tiene que ver con la seguridad. Haukcode.DinkToPdf hereda CVE-2022-35583, una vulnerabilidad crítica de falsificación de peticiones del lado del servidor (SSRF) con una puntuación CVSS de 9,8.
CVE-2022-35583 Vectores de ataque:
- El contenido HTML malicioso puede hacer que el servidor busque recursos internos
- Los ataques de metadatos de AWS pueden acceder a
http://169.254.169.254para robar credenciales - Exploración de la red interna y acceso a los servicios internos
- Inclusión de archivos locales a través del protocolo
file:// - Posibilidad de hacerse con toda la infraestructura
No hay solución para esta vulnerabilidad porque wkhtmltopdf está abandonado (archivado desde enero de 2023, siendo la última versión 0.12.6 en 2020).
| Aspecto de seguridad | Haukcode.DinkToPdf | IronPDF |
|---|---|---|
| CVE críticos | CVE-2022-35583 (CVSS 9.8, no corregible) | Parcheado activamente |
| Motor subyacente | wkhtmltopdf (Qt WebKit ~2015) | Chromium (actualizado regularmente) |
| Estado del proyecto | Bifurcación de proyecto abandonado | Desarrollado activamente |
| Actualizaciones de seguridad | No se espera ninguno | Publicaciones periódicas |
| Soporte | Sólo para la comunidad | Asistencia profesional |
Implicaciones regulatorias españolas de CVE-2022-35583
En el contexto español, el impacto de esta vulnerabilidad va más allá de la seguridad técnica. El ENS (aprobado por Real Decreto 311/2022) exige que los sistemas de categoría media y alta mantengan un inventario actualizado de vulnerabilidades y apliquen parches en plazos definidos. Una biblioteca con un CVE crítico de CVSS 9,8 sin posibilidad de parche no puede superar una auditoría ENS, lo que bloquea el acceso a contratos con la Administración Pública.
La LOPDGDD añade presión adicional: si un atacante utiliza CVE-2022-35583 para acceder a datos personales de ciudadanos españoles (por ejemplo, nombres y NIE/DNI en facturas PDF), la organización debe notificar a la AEPD en 72 horas. Los responsables de cumplimiento de empresas medianas españolas que procesan documentos fiscales han identificado esta dependencia como riesgo de auditoría de nivel I.
Comparación de arquitecturas y motores
Las diferencias arquitectónicas fundamentales afectan a la calidad de la representación, la compatibilidad con los estándares web modernos y la complejidad de la implantación.
| Aspecto | Haukcode.DinkToPdf | IronPDF |
|---|---|---|
| Motor de renderizado | Qt WebKit (~2015) | Chromium (actual) |
| HTML5/CSS3 | Limitado | Se admite |
| JavaScript | Limitado, inseguro | Motor V8 completo |
| Binarios nativos | Requisitos (específicos de la plataforma) | Autocontenido |
| Seguridad de hilos | Requiere el patrón singleton | Thread-safe por diseño |
| Actualizaciones | No se espera ninguno | Publicaciones periódicas |
La dependencia de Haukcode.DinkToPdf del anticuado motor Qt WebKit implica la pérdida de años de parches de seguridad y una compatibilidad limitada con los estándares web modernos. El motor Chromium deIronPDFes compatible con los estándares web actuales y se actualiza periódicamente.
Comparación de códigos: Operaciones comunes en PDF
Conversión de HTML a PDF
La operación más fundamental demuestra las diferencias de diseño de las API.
Haukcode.DinkToPdf:
// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;
class Program
{
static void Main()
{
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Portrait,
PaperSize = PaperKind.A4,
},
Objects = {
new ObjectSettings() {
HtmlContent = "<html><body><h1>Hello World</h1></body></html>",
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("output.pdf", pdf);
}
}// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;
class Program
{
static void Main()
{
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Portrait,
PaperSize = PaperKind.A4,
},
Objects = {
new ObjectSettings() {
HtmlContent = "<html><body><h1>Hello World</h1></body></html>",
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("output.pdf", pdf);
}
}Imports DinkToPdf
Imports DinkToPdf.Contracts
Imports System.IO
Module Program
Sub Main()
Dim converter = New SynchronizedConverter(New PdfTools())
Dim doc = New HtmlToPdfDocument() With {
.GlobalSettings = New GlobalSettings() With {
.ColorMode = ColorMode.Color,
.Orientation = Orientation.Portrait,
.PaperSize = PaperKind.A4
},
.Objects = New List(Of ObjectSettings) From {
New ObjectSettings() With {
.HtmlContent = "<html><body><h1>Hello World</h1></body></html>"
}
}
}
Dim pdf As Byte() = converter.Convert(doc)
File.WriteAllBytes("output.pdf", pdf)
End Sub
End ModuleIronPDF:
// NuGet: Install-Package IronPdf
using IronPdf;
using System.IO;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<html><body><h1>Hello World</h1></body></html>");
pdf.SaveAs("output.pdf");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using System.IO;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<html><body><h1>Hello World</h1></body></html>");
pdf.SaveAs("output.pdf");
}
}Imports IronPdf
Imports System.IO
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<html><body><h1>Hello World</h1></body></html>")
pdf.SaveAs("output.pdf")
End Sub
End ClassHaukcode.DinkToPdf requiere crear un SynchronizedConverter con PdfTools, construir un HtmlToPdfDocument con objetos anidados GlobalSettings y ObjectSettings, llamar a Convert() para obtener bytes crudos, y luego escribir manualmente en el disco con File.WriteAllBytes().
IronPDF crea un ChromePdfRenderer, llama a RenderHtmlAsPdf() con la cadena HTML directamente, y guarda con SaveAs(). El funcionamiento es significativamente más conciso con un diseño de API moderno.
Para conocer las opciones avanzadas de conversión de HTML, consulte la Guía de conversión de HTML a PDF.
Conversión de URL a PDF
La conversión de páginas web muestra los distintos enfoques para tratar contenidos externos.
Haukcode.DinkToPdf:
// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;
class Program
{
static void Main()
{
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Portrait,
PaperSize = PaperKind.A4,
},
Objects = {
new ObjectSettings() {
Page = "https://www.example.com",
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("webpage.pdf", pdf);
}
}// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;
class Program
{
static void Main()
{
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Portrait,
PaperSize = PaperKind.A4,
},
Objects = {
new ObjectSettings() {
Page = "https://www.example.com",
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("webpage.pdf", pdf);
}
}Imports DinkToPdf
Imports DinkToPdf.Contracts
Imports System.IO
Module Program
Sub Main()
Dim converter = New SynchronizedConverter(New PdfTools())
Dim doc = New HtmlToPdfDocument() With {
.GlobalSettings = New GlobalSettings() With {
.ColorMode = ColorMode.Color,
.Orientation = Orientation.Portrait,
.PaperSize = PaperKind.A4
},
.Objects = New List(Of ObjectSettings) From {
New ObjectSettings() With {
.Page = "https://www.example.com"
}
}
}
Dim pdf As Byte() = converter.Convert(doc)
File.WriteAllBytes("webpage.pdf", pdf)
End Sub
End ModuleIronPDF:
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
pdf.SaveAs("webpage.pdf");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
pdf.SaveAs("webpage.pdf");
}
}Imports IronPdf
Imports System
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderUrlAsPdf("https://www.example.com")
pdf.SaveAs("webpage.pdf")
End Sub
End ClassHaukcode.DinkToPdf utiliza la misma estructura HtmlToPdfDocument con propiedad ObjectSettings.Page para la especificación de URLs.IronPDFproporciona un método RenderUrlAsPdf() dedicado que acepta la URL directamente, una API más clara para este caso de uso específico.
Tenga en cuenta que la renderización de URL con Haukcode.DinkToPdf conlleva el riesgo de vulnerabilidad SSRF CVE-2022-35583, ya que las URL o redirecciones maliciosas podrían explotar el servidor.
Configuración de páginas personalizadas
La configuración de la página muestra los diferentes modelos de configuración.
Haukcode.DinkToPdf:
// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;
class Program
{
static void Main()
{
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Landscape,
PaperSize = PaperKind.Letter,
Margins = new MarginSettings() { Top = 10, Bottom = 10, Left = 10, Right = 10 }
},
Objects = {
new ObjectSettings() {
HtmlContent = "<html><body><h1>Landscape Document</h1><p>Custom page settings</p></body></html>",
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("landscape.pdf", pdf);
}
}// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;
class Program
{
static void Main()
{
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Landscape,
PaperSize = PaperKind.Letter,
Margins = new MarginSettings() { Top = 10, Bottom = 10, Left = 10, Right = 10 }
},
Objects = {
new ObjectSettings() {
HtmlContent = "<html><body><h1>Landscape Document</h1><p>Custom page settings</p></body></html>",
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("landscape.pdf", pdf);
}
}Imports DinkToPdf
Imports DinkToPdf.Contracts
Imports System.IO
Module Program
Sub Main()
Dim converter = New SynchronizedConverter(New PdfTools())
Dim doc = New HtmlToPdfDocument() With {
.GlobalSettings = New GlobalSettings() With {
.ColorMode = ColorMode.Color,
.Orientation = Orientation.Landscape,
.PaperSize = PaperKind.Letter,
.Margins = New MarginSettings() With {.Top = 10, .Bottom = 10, .Left = 10, .Right = 10}
},
.Objects = {
New ObjectSettings() With {
.HtmlContent = "<html><body><h1>Landscape Document</h1><p>Custom page settings</p></body></html>"
}
}
}
Dim pdf As Byte() = converter.Convert(doc)
File.WriteAllBytes("landscape.pdf", pdf)
End Sub
End ModuleIronPDF:
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
renderer.RenderingOptions.MarginTop = 10;
renderer.RenderingOptions.MarginBottom = 10;
renderer.RenderingOptions.MarginLeft = 10;
renderer.RenderingOptions.MarginRight = 10;
var pdf = renderer.RenderHtmlAsPdf("<html><body><h1>Landscape Document</h1><p>Custom page settings</p></body></html>");
pdf.SaveAs("landscape.pdf");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
renderer.RenderingOptions.MarginTop = 10;
renderer.RenderingOptions.MarginBottom = 10;
renderer.RenderingOptions.MarginLeft = 10;
renderer.RenderingOptions.MarginRight = 10;
var pdf = renderer.RenderHtmlAsPdf("<html><body><h1>Landscape Document</h1><p>Custom page settings</p></body></html>");
pdf.SaveAs("landscape.pdf");
}
}Imports IronPdf
Imports IronPdf.Rendering
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape
renderer.RenderingOptions.MarginTop = 10
renderer.RenderingOptions.MarginBottom = 10
renderer.RenderingOptions.MarginLeft = 10
renderer.RenderingOptions.MarginRight = 10
Dim pdf = renderer.RenderHtmlAsPdf("<html><body><h1>Landscape Document</h1><p>Custom page settings</p></body></html>")
pdf.SaveAs("landscape.pdf")
End Sub
End ClassHaukcode.DinkToPdf configura las configuraciones de página a través de GlobalSettings con objetos anidados MarginSettings. Las propiedades utilizan enums como Orientation.Landscape y PaperKind.Letter.
IronPDF utiliza propiedades RenderingOptions directamente en el renderizador. Las propiedades se configuran individualmente (PaperSize, PaperOrientation, MarginTop, etc.) con enums tipados (PdfPaperSize.Letter, PdfPaperOrientation.Landscape). Ambos utilizan milímetros como unidades de margen.
Obtenga más información sobre la configuración de la renderización en Tutoriales de IronPDF.
Caso de uso: Facturación electrónica con IronPDF bajo VeriFactu y Facturae
Para empresas españolas obligadas a emitir facturas electrónicas conforme a la Ley Crea y Crece y los formatos Facturae 3.2.x y VeriFactu, la generación de PDF requiere una cadena de confianza completa. Haukcode.DinkToPdf, con su vulnerabilidad SSRF no corregible, no puede usarse en este pipeline porque los sistemas de facturación llaman a endpoints de la AEAT (e.g., servicios web de VeriFactu) con credenciales de certificado FNMT. Un atacante podría redirigir el conversor hacia esos endpoints internos y extraer tokens.
IronPDF, al ser autónomo y thread-safe, encaja directamente en un pipeline de facturación:
// Generación de PDF de factura Facturae con IronPDF
// Cumple con el Reglamento de Facturación (RD 1619/2012)
using IronPdf;
using System;
public class FacturaeInvoicePdfGenerator
{
public byte[] GenerateInvoicePdf(string invoiceHtml, string nifEmisor, string serieFactura)
{
// Configurar IronPdf.License en startup desde configuración segura
var renderer = new ChromePdfRenderer();
// Metadatos requeridos para trazabilidad AEAT/SII
renderer.RenderingOptions.Title = $"Factura {serieFactura} - {nifEmisor}";
renderer.RenderingOptions.Author = nifEmisor;
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
// El HTML ya lleva los bloques de datos VeriFactu (hash SHA-256, QR TBAI si aplica)
var pdf = renderer.RenderHtmlAsPdf(invoiceHtml);
// SaveAs seguro para archivo fiscal (retención 4 años según LOPDGDD)
string outputPath = $"facturas/{nifEmisor}_{serieFactura}_{DateTime.Now:yyyyMMdd}.pdf";
pdf.SaveAs(outputPath);
return pdf.BinaryData;
}
}// Generación de PDF de factura Facturae con IronPDF
// Cumple con el Reglamento de Facturación (RD 1619/2012)
using IronPdf;
using System;
public class FacturaeInvoicePdfGenerator
{
public byte[] GenerateInvoicePdf(string invoiceHtml, string nifEmisor, string serieFactura)
{
// Configurar IronPdf.License en startup desde configuración segura
var renderer = new ChromePdfRenderer();
// Metadatos requeridos para trazabilidad AEAT/SII
renderer.RenderingOptions.Title = $"Factura {serieFactura} - {nifEmisor}";
renderer.RenderingOptions.Author = nifEmisor;
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
// El HTML ya lleva los bloques de datos VeriFactu (hash SHA-256, QR TBAI si aplica)
var pdf = renderer.RenderHtmlAsPdf(invoiceHtml);
// SaveAs seguro para archivo fiscal (retención 4 años según LOPDGDD)
string outputPath = $"facturas/{nifEmisor}_{serieFactura}_{DateTime.Now:yyyyMMdd}.pdf";
pdf.SaveAs(outputPath);
return pdf.BinaryData;
}
}Imports IronPdf
Imports System
Public Class FacturaeInvoicePdfGenerator
Public Function GenerateInvoicePdf(invoiceHtml As String, nifEmisor As String, serieFactura As String) As Byte()
' Configurar IronPdf.License en startup desde configuración segura
Dim renderer As New ChromePdfRenderer()
' Metadatos requeridos para trazabilidad AEAT/SII
renderer.RenderingOptions.Title = $"Factura {serieFactura} - {nifEmisor}"
renderer.RenderingOptions.Author = nifEmisor
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4
' El HTML ya lleva los bloques de datos VeriFactu (hash SHA-256, QR TBAI si aplica)
Dim pdf = renderer.RenderHtmlAsPdf(invoiceHtml)
' SaveAs seguro para archivo fiscal (retención 4 años según LOPDGDD)
Dim outputPath As String = $"facturas/{nifEmisor}_{serieFactura}_{DateTime.Now:yyyyMMdd}.pdf"
pdf.SaveAs(outputPath)
Return pdf.BinaryData
End Function
End ClassEste patrón es válido también para la generación de tickets verificables en territorios con TicketBAI (Bizkaia, Gipuzkoa, Araba), donde el PDF del ticket debe incluir el código QR y el identificador TBAI generado por el sistema de software certificado. IronPDF puede inyectar esos elementos mediante HTML/CSS sin dependencias nativas, mientras que Haukcode.DinkToPdf añade riesgo de SSRF a un pipeline ya de por sí complejo.
Referencia de mapeo de API
Para los desarrolladores que estén evaluando la migración Haukcode.DinkToPdf o comparando capacidades, este mapeo muestra operaciones equivalentes:
Mapeo de clases conversoras
| Haukcode.DinkToPdf | IronPDF |
|---|---|
SynchronizedConverter | ChromePdfRenderer |
BasicConverter | ChromePdfRenderer |
PdfTools | N/A |
IConverter | N/A |
Mapeo de configuración de documentos
| Haukcode.DinkToPdf | IronPDF |
|---|---|
HtmlToPdfDocument | Llamada al método |
GlobalSettings | RenderingOptions |
ObjectSettings | RenderingOptions |
converter.Convert(doc) | renderer.RenderHtmlAsPdf(html) |
Mapeo de propiedades de GlobalSettings
| Propiedad GlobalSettings | Propiedad de IronPDF |
|---|---|
ColorMode | RenderingOptions.GrayScale |
Orientation | RenderingOptions.PaperOrientation |
PaperSize | RenderingOptions.PaperSize |
Margins.Top | RenderingOptions.MarginTop |
Margins.Bottom | RenderingOptions.MarginBottom |
Margins.Left | RenderingOptions.MarginLeft |
Margins.Right | RenderingOptions.MarginRight |
Mapeo de propiedades de ObjectSettings
| Propiedad ObjectSettings | Equivalente de IronPDF |
|---|---|
HtmlContent | Primer parámetro para RenderHtmlAsPdf() |
Page (URL) | renderer.RenderUrlAsPdf(url) |
HeaderSettings.Right = "[page]" | TextHeader.RightText = "{page}" |
Diferencias en la sintaxis de los marcadores
Los marcadores de posición de encabezado/pie de página utilizan una sintaxis diferente entre las bibliotecas:
| Haukcode.DinkToPdf | IronPDF |
|---|---|
[page] | {page} |
[toPage] | {total-pages} |
[date] | {date} |
Seguridad de hilos e inyección de dependencias
Haukcode.DinkToPdf requiere un manejo cuidadoso debido a las limitaciones de seguridad de hilos heredadas de wkhtmltopdf.
Haukcode.DinkToPdf (se requiere Singleton):
// Startup.cs - MUST be singleton due to thread safety issues
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));
}// Startup.cs - MUST be singleton due to thread safety issues
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));
}' Startup.vb - MUST be singleton due to thread safety issues
Public Sub ConfigureServices(services As IServiceCollection)
services.AddSingleton(GetType(IConverter), New SynchronizedConverter(New PdfTools()))
End SubIronPDF (Flexible):
// Startup.cs - Can be singleton or transient (both work)
public void ConfigureServices(IServiceCollection services)
{
IronPdf.License.LicenseKey = Configuration["IronPdf:LicenseKey"];
services.AddSingleton<IPdfService, IronPdfService>();
// Or services.AddTransient<IPdfService, IronPdfService>() - both are safe!
}// Startup.cs - Can be singleton or transient (both work)
public void ConfigureServices(IServiceCollection services)
{
IronPdf.License.LicenseKey = Configuration["IronPdf:LicenseKey"];
services.AddSingleton<IPdfService, IronPdfService>();
// Or services.AddTransient<IPdfService, IronPdfService>() - both are safe!
}Imports Microsoft.Extensions.DependencyInjection
Public Sub ConfigureServices(services As IServiceCollection)
IronPdf.License.LicenseKey = Configuration("IronPdf:LicenseKey")
services.AddSingleton(Of IPdfService, IronPdfService)()
' Or services.AddTransient(Of IPdfService, IronPdfService) - both are safe!
End SubIronPDF está diseñado a prueba de hilos, lo que permite patrones flexibles de inyección de dependencias sin el requisito del singleton.
Resumen comparativo de características
| Característica | Haukcode.DinkToPdf | IronPDF |
|---|---|---|
| Fuente de origen | Bifurcación de proyecto abandonado | Desarrollo independiente |
| Seguridad | CVE heredadas de la versión anterior (no corregibles) | Parcheado y seguro de forma proactiva |
| Comunidad y soporte | Pequeñas y esporádicas | Amplio, activo y dedicado |
| Características y actualizaciones | Limitada y esporádica | Regular con desarrollo activo |
| Soporte multihilo | Requiere el patrón singleton | Totalmente compatible y optimizado |
| Binarios nativos | Requisitos (específicos de la plataforma) | Autocontenido |
| HTML5/CSS3 | Limitado | Se admite |
| JavaScript | Limitado | Motor V8 completo |
| Licencia | MIT (gratuito) | Comercial con prueba gratuita |
Cuando los equipos consideran cambiar de Haukcode.DinkToPdf a IronPDF
Los equipos de desarrollo evalúan la transición de Haukcode.DinkToPdf aIronPDFpor varias razones:
Vulnerabilidades críticas de seguridad: CVE-2022-35583 (SSRF) es una vulnerabilidad crítica con CVSS 9.8 que nunca será parcheada. Para las aplicaciones que procesan HTML proporcionado por el usuario o que renderizan URL externas, esta vulnerabilidad permite el robo de credenciales de AWS, el acceso a la red interna y los ataques de inclusión de archivos locales.
Tecnología subyacente abandonada: wkhtmltopdf está abandonada (archivada en enero de 2023, última versión en 2020). Haukcode.DinkToPdf como continuación no puede abordar cuestiones fundamentales de la tecnología subyacente. El anticuado motor Qt WebKit (~2015)lleva años sin parches de seguridad.
Gestión de Binarios Nativos: Haukcode.DinkToPdf requiere distribuir binarios específicos para la plataforma (libwkhtmltox.dll, libwkhtmltox.so, libwkhtmltox.dylib). Esto complica el despliegue, las canalizaciones CI/CD y la contenedorización.IronPDFes autónomo, sin binarios externos.
Limitaciones de Seguridad de los Hilos: El patrón singleton requerido SynchronizedConverter limita la flexibilidad arquitectónica y puede crear cuellos de botella bajo carga.IronPDFestá diseñado a prueba de hilos, lo que permite instancias por solicitud.
Estándares web modernos: La compatibilidad limitada con HTML5/CSS3 y la ejecución insegura de JavaScript restringen las capacidades de representación de los contenidos web modernos. El motor Chromium deIronPDFes compatible con los estándares web actuales.
Viabilidad a largo plazo: La dependencia de tecnología abandonada crea una deuda técnica que se agrava con el tiempo. A medida que los proyectos escalan hacia .NET 10 y C# 14 hasta 2026, mantener la dependencia de envoltorios wkhtmltopdf sin mantenimiento se vuelve cada vez más problemático.
Cumplimiento regulatorio en España: Los equipos que gestionan obligaciones fiscales electrónicas españolas — VeriFactu, Facturae, SII, TicketBAI — enfrentan un escenario especialmente crítico. El pipeline de firma digital con certificado FNMT y comunicación con endpoints de la AEAT queda expuesto si se usa Haukcode.DinkToPdf: CVE-2022-35583 permitiría a un atacante redirigir solicitudes hacia los servicios internos de facturación. Bajo la LOPDGDD, una brecha de este tipo activa notificación obligatoria a la AEPD y posibles sanciones del artículo 83. La conformidad con el ENS categoría alta tampoco es viable con una biblioteca que tiene un CVE crítico de CVSS 9,8 sin parche permanente.
Fuerzas y consideraciones
Puntos fuertes de Haukcode.DinkToPdf
- Gratis y de código abierto: Licencia MIT sin costes de licencia
- Funcionalidad básica: Admite la conversión fundamental de HTML a PDF
- Código base existente: Familiar para los equipos que ya utilizan DinkToPdf
Consideraciones sobre Haukcode.DinkToPdf
- Vulnerabilidades de seguridad críticas: CVE-2022-35583 no se puede corregir
- Tecnología abandonada: Construida sobre wkhtmltopdf descatalogado
- Dependencia binaria nativa: Se requieren DLL específicas de la plataforma
- Temas de seguridad de hilos: Se requiere el patrón Singleton
- Estándares web limitados: Motor Qt WebKit obsoleto
- Sin soporte profesional: Asistencia únicamente comunitaria
- Deuda técnica: La dependencia de un proyecto abandonado aumenta el riesgo
Puntos fuertes de IronPDF
- Active Security Patching: Las actualizaciones periódicas abordan las vulnerabilidades
- Motor Chromium moderno: Compatibilidad con los estándares web actuales
- Autocontenido: Sin dependencias binarias nativas
- Diseño a prueba de hilos: Patrones de despliegue flexibles
- HTML5/CSS3/JavaScript completo: Capacidades de renderizado modernas
- Soporte profesional: Soporte de ingeniería dedicado
- Recursos completos: Amplios tutoriales y documentación
Consideraciones sobre IronPDF
- Licencia comercial: Requerida para uso en producción
Conclusión
Haukcode.DinkToPdf yIronPDFrepresentan enfoques fundamentalmente diferentes para la generación de PDF en aplicaciones .NET. Haukcode.DinkToPdf, como continuación del abandonado proyecto DinkToPdf que envolvía el descatalogado binario wkhtmltopdf, conlleva vulnerabilidades de seguridad críticas (CVE-2022-35583) que nunca serán parcheadas. La biblioteca requiere una distribución binaria nativa, patrones singleton para la seguridad de los hilos y proporciona un soporte limitado de estándares web modernos.
IronPDF ofrece una alternativa mantenida activamente con un moderno motor Chromium, actualizaciones de seguridad periódicas y una arquitectura a prueba de hilos. La biblioteca autónoma elimina la gestión de binarios nativos al tiempo que ofrece compatibilidad total con HTML5/CSS3/JavaScript.
A medida que las organizaciones planifican .NET 10, C# 14 y el desarrollo de aplicaciones hasta 2026, la elección entre mantener la dependencia de una tecnología abandonada con vulnerabilidades críticas no corregibles o adoptar una solución mantenida activamente con capacidades modernas afecta significativamente tanto a la postura de seguridad como a la velocidad de desarrollo. Los equipos que necesiten una generación de PDF segura, un renderizado moderno o una implementación simplificada descubrirán queIronPDFsatisface estos requisitos con eficacia.
Para organizaciones españolas, la decisión es aún más clara: los requisitos del ENS para sistemas de categoría media y alta, las obligaciones de notificación a la AEPD bajo la LOPDGDD, y la cadena de confianza para documentos fiscales VeriFactu, Facturae y SII firmados con certificado FNMT son incompatibles con una biblioteca que tiene CVE-2022-35583 como deuda técnica permanente. IronPDF, mantenido activamente y sin dependencias nativas externas, permite cumplir estos requisitos sin comprometer la postura de seguridad. Los equipos que operan bajo eIDAS para firma electrónica cualificada o que generan TicketBAI para los territorios forales (Bizkaia, Gipuzkoa, Araba) encontrarán en IronPDF una base técnicamente sólida y regulatoriamente defensible.
Comience a evaluar IronPDF con una prueba gratuita y explore la documentación exhaustiva para evaluar si se adapta a sus requisitos específicos.
