PDF-asiakirjat ovat uskomattoman tehokkaita, mutta tähän tehokkuuteen liittyy luontaisia tietoturvariskejä. Koska PDF-tiedostot tukevat upotettuja tiedostoja, interaktiivista JavaScriptiä ja monimutkaisia binäärivirtoja, niitä käytetään usein haittaohjelmien levityskanavina. Puskurin ylivuodot, rajojen ulkopuoliset luvut ja kokonaislukujen ylivuodot huonosti kirjoitetuissa PDF-jäsentimissä voivat johtaa etäkoodin suorittamiseen (RCE).
Jos olet rakentamassa Delphi-sovellusta, joka hyväksyy käyttäjien lataamia PDF-tiedostoja (esim. asiakirjojen vastaanottoportaali), muistiturvallisen PDF-jäsennyksen varmistaminen on kriittinen tietoturvavaatimus.
Yleiset PDF-hyökkäysvektorit
Haitalliset PDF-tiedostot kohdistuvat yleensä itse jäsentimen haavoittuvuuksiin käyttöjärjestelmän sijaan. Yleisiä tekniikoita ovat:
- Vääristyneet ristiinviittaustaulukot (XRef): Osoittimien siirtymien luominen, jotka johtavat rajojen ulkopuolelle, kaataen jäsentimen tai mahdollistaen muistin paljastumisen.
- Päättymättömät silmukat: Kehäviittausten luominen PDF-objektien välille (esim. objekti A viittaa objektiin B, joka viittaa objektiin A), mikä johtaa pinon loppumiseen.
- Räjähtävä purkaminen (Zip-pommit): FlateDecode-virrat, jotka purkautuvat muutamasta kilotavusta gigatavuihin kuluttaen järjestelmän muistin loppuun.
Puolustavat jäsennysstrategiat Delphissä
Kun jäsennetään PDF-tiedostoja natiivisti Delphissä, sinun on ohjelmoitava puolustavasti. Et voi luottaa PDF-sanakirjoissa annettuihin metatietoihin.
1. Kehäviittausten rikkominen
Kun käyt läpi PDF-objektipuuta rekursiivisesti, sinun on ylläpidettävä historiaa vierailuista objekteista päättymättömien silmukoiden estämiseksi.
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. Suojautuminen Zip-pommeja vastaan
Kun käytät FlateDecode-suodatinta virran purkamiseen, sinun on ehdottomasti rajoitettava laajentumisen enimmäiskokoa. Älä koskaan varaa muistia sokeasti perustuen /Length-sanakirja-avaimeen.
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;
Vahvistettujen moottoreiden ja turvallisten komponenttien hyödyntäminen
Täysin turvallisen PDF- jäsentimen kirjoittaminen alusta alkaen on valtava tehtävä. Alan vakiolähestymistapa on käyttää vahvistettua, raskaasti fuzz-testattua moottoria, kuten PDFiumia, tai luottaa tiukasti testattuihin natiivikirjastoihin.
PDFium on Google Chromen käyttämä ydinrenderöintimoottori. Koska Chrome käsittelee päivittäin miljoonia epäluotettavia PDF-tiedostoja, PDFium altistetaan Googlen Project Zeron aggressiiviselle ja jatkuvalle fuzz-testaukselle. Se käsittelee virheellisesti muotoillut XRefit, rikkoutuneet tietovirrat ja sykliset viittaukset sulavasti.
Samoin natiivikomponentit, kuten HotPDF Component ja Delphi PDF Library, sisältävät vankkoja puolustavia jäsennysstrategioita suoraan paketista. Ne toteuttavat tiukan rajatarkistuksen, rekursiivisen syvyyden rajoittimet ja muistivuotojen estomekanismit, jotka on suunniteltu erityisesti Delphi- ja C++Builder-ympäristöihin.
Riippumatta siitä, valitsetko PDFiumin kuluttamisen Delphi-kääreen kautta renderöintiin vai käytätkö natiivikomponentteja, kuten HotPDF:ää dokumenttien luomiseen ja käsittelyyn, perit yritystason tietoturvarajan, joka suojaa käyttäjiäsi ja palvelimiasi haitallisilta hyötykuormilta ilman, että sinun tarvitsee itse kirjoittaa puolustavia jäsentimiä.
Huomaa: Turvalliset, fuzz-testatut jäsennysominaisuudet ovat saatavilla koko tuotesarjassamme, mukaan lukien HotPDF Component, Delphi PDF Library ja PDFium Component.