Los documentos PDF pueden hacer una gran cantidad de cosas, y esa flexibilidad conlleva riesgos de seguridad inherentes. Debido a que los PDF admiten archivos incrustados, JavaScript interactivo y secuencias binarias complejas, frecuentemente se utilizan como vectores para la entrega de malware. Desbordamientos de búfer (buffer overflows), lecturas fuera de límites y desbordamientos de enteros en analizadores sintácticos de PDF mal escritos pueden llevar a la ejecución remota de código (RCE)
Si está construyendo una aplicación en Delphi que acepta PDFs subidos por el usuario (por ejemplo, un portal de ingestión de documentos), asegurar un análisis de PDF seguro en memoria es un requisito de seguridad crítico
Vectores de ataque comunes en PDF
Los PDFs maliciosos normalmente apuntan a vulnerabilidades en el analizador en sí más que en el sistema operativo. Las técnicas comunes incluyen:
- Tablas de referencias cruzadas (XRef) malformadas: Elaboración de desplazamientos de puntero que llevan fuera de límites, bloqueando el analizador o permitiendo la divulgación de memoria
- Bucles infinitos: Creación de referencias circulares entre objetos PDF (por ej., el Objeto A hace referencia al Objeto B, el cual hace referencia al Objeto A) llevando al agotamiento de la pila
- Descompresión explosiva (Bombas Zip): Secuencias FlateDecode que se descomprimen desde unos pocos kilobytes a gigabytes, agotando la memoria del sistema
Estrategias defensivas de análisis en Delphi
Cuando analice PDFs de forma nativa en Delphi, debe programar a la defensiva. No puede confiar en los metadatos proporcionados en los diccionarios PDF
1. Romper referencias circulares
Cuando recorra recursivamente un árbol de objetos PDF, debe mantener un historial de los objetos visitados para prevenir bucles infinitos
uses
System.Generics.Collections, System.SysUtils;
// A safe recursive function to walk the PDF tree
procedure ParsePDFDictionary(DictObj: TPDFDictionary; Visited: TList<Integer>);
var
ObjID: Integer;
begin
ObjID := DictObj.ObjectID;
if Visited.Contains(ObjID) then
begin
Writeln('Warning: Circular reference detected. Aborting branch.');
Exit;
end;
Visited.Add(ObjID);
try
// Process child objects safely...
finally
// Allow siblings to traverse, but prevent vertical recursion loops
Visited.Remove(ObjID);
end;
end;
2. Protegerse contra las Bombas Zip
Cuando aplique el filtro FlateDecode para descomprimir una secuencia, debe limitar estrictamente el tamaño máximo de expansión. Nunca asigne memoria a ciegas basándose en la clave de diccionario /Length
const
MAX_DECOMPRESSED_SIZE = 1024 * 1024 * 50; // 50 MB safety limit
procedure DecompressPDFStream(CompressedStream, OutputTarget: TStream);
var
ZLibStream: TZDecompressionStream;
Buffer: array[0..8191] of Byte;
BytesRead, TotalRead: Integer;
begin
ZLibStream := TZDecompressionStream.Create(CompressedStream);
try
TotalRead := 0;
repeat
BytesRead := ZLibStream.Read(Buffer[0], SizeOf(Buffer));
if BytesRead > 0 then
begin
TotalRead := TotalRead + BytesRead;
if TotalRead > MAX_DECOMPRESSED_SIZE then
raise Exception.Create('Security Exception: Decompression bomb detected!');
OutputTarget.WriteBuffer(Buffer[0], BytesRead);
end;
until BytesRead = 0;
finally
ZLibStream.Free;
end;
end;
Aprovechar motores endurecidos y componentes seguros
Escribir un analizador de PDF completamente seguro desde cero es una tarea monumental. El enfoque estándar de la industria es utilizar un motor endurecido y fuertemente sometido a pruebas de fuzzing como PDFium, o apoyarse en bibliotecas nativas rigurosamente probadas
PDFium es el motor de renderizado central utilizado por Google Chrome. Debido a que Chrome procesa millones de PDFs no confiables diariamente, PDFium está sometido a pruebas de fuzzing continuas y agresivas a través de OSS-Fuzz y ClusterFuzz. Maneja de manera elegante XRefs malformadas, secuencias rotas y referencias cíclicas
De manera similar, los componentes nativos como HotPDF Component y Delphi PDF Library incorporan estrategias de análisis defensivo bien probadas de forma predeterminada. Implementan una verificación estricta de límites, limitadores de profundidad recursiva y mecanismos de prevención de fugas de memoria diseñenos específicamente para los entornos Delphi y C++Builder
Ya sea que elija consumir PDFium a través de un envoltorio de Delphi para el renderizado, o utilice componentes nativos como HotPDF para la generación y procesamiento de documentos, hereda un perímetro de seguridad de grado empresarial, protegiendo a sus usuarios y sus servidores de cargas maliciosas sin tener que escribir analizadores defensivos usted mismo
Nota: Las capacidades de análisis seguras y sometidas a fuzzing están disponibles en toda nuestra suite, incluyendo HotPDF Component, Delphi PDF Library, y PDFium Component