PDF-dokumenter er utroligt kraftfulde, men den kraft kommer med iboende sikkerhedsrisici. Fordi PDF'er understøtter indlejrede filer, interaktiv JavaScript og komplekse binære streams, bruges de ofte som vektorer for levering af malware. Bufferoverløb, læsninger uden for grænserne (out-of-bounds) og heltalsoverløb i dårligt skrevne PDF-parsere kan føre til fjernudførelse af kode (RCE).
Hvis du bygger en applikation i Delphi, der accepterer bruger-uploadede PDF'er (f.eks. en portal til dokumentindtagelse), er sikring af hukommelsessikker PDF-parsing et kritisk sikkerhedskrav.
Almindelige PDF-angrebsvektorer
Ondsindede PDF'er retter sig normalt mod sårbarheder i selve parseren frem for operativsystemet. Almindelige teknikker inkluderer:
- Misdannede krydsreference-tabeller (XRef): Udformning af pointer-forskydninger, der fører uden for grænserne, hvilket får parseren til at gå ned eller tillader afsløring af hukommelse.
- Uendelige sløjfer: Oprettelse af cirkulære referencer mellem PDF-objekter (f.eks. Objekt A refererer til Objekt B, som refererer til Objekt A), der fører til stak-udmattelse.
- Eksploderende dekomprimering (Zip Bombs): FlateDecode-streams, der dekomprimeres fra et par kilobyte til gigabyte, hvilket udtømmer systemets hukommelse.
Defensive parsing-strategier i Delphi
Når du parser PDF'er indfødt i Delphi, skal du programmere defensivt. Du kan ikke stole på de metadata, der leveres i PDF-ordbøgerne.
1. Brydning af cirkulære referencer
Når du rekursivt gennemgår et PDF-objekttræ, skal du opretholde en historik over besøgte objekter for at forhindre uendelige sløjfer.
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. Beskyttelse mod Zip-bomber
Når du anvender FlateDecode-filteret til at dekomprimere en stream, skal du strengt begrænse den maksimale udvidelsesstørrelse. Tildel aldrig hukommelse blindt baseret på /Length-ordbogs-nøglen.
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;
Udnyttelse af hærdede motorer og sikre komponenter
At skrive en fuldstændig sikker PDF-parser fra bunden er en monumental opgave. Branchestandarden er at bruge en hærdet motor, der er stærkt fuzz-testet, som PDFium, eller at stole på strengt testede native biblioteker.
PDFium er den centrale renderingsmotor, der bruges af Google Chrome. Fordi Chrome behandler millioner af upålidelige PDF'er dagligt, udsættes PDFium for aggressiv, kontinuerlig fuzzing af Googles Project Zero. Den håndterer misdannede XRef'er, ødelagte strømme og cykliske referencer problemfrit.
På samme måde inkorporerer native komponenter som HotPDF Component og Delphi PDF Library robuste defensive parsingsstrategier direkte fra kassen. De implementerer streng grænsekontrol, rekursive dybdebegrænsere og mekanismer til forhindring af hukommelseslækager designet specifikt til Delphi- og C++Builder-miljøer.
Uanset om du vælger at forbruge PDFium via en Delphi-wrapper til rendering, eller udnytter native komponenter som HotPDF til dokumentgenerering og -behandling, arver du et sikkerhedsperimeter på virksomhedsniveau, der beskytter dine brugere og dine servere mod ondsindede payloads uden selv at skulle skrive defensive parsere.
Bemærk: Sikre, fuzz-testede parsingsfunktioner er tilgængelige på tværs af hele vores suite, herunder HotPDF Component, Delphi PDF Library og PDFium Component.