Tekninen artikkeli

Turvallinen PDF-esikatselu Delphi-sovelluksissa PDFium-komponentilla

Tässä artikkelissa käydään läpi toteutuksen tärkeimmät päätökset, rajatapaukset ja varmennukset

Käytännön toteutusvalinnat

Aloita tiedostotyypistä, odotetusta tuloksesta ja virhetilasta, jonka käyttäjän pitää nähdä. Sido sen jälkeen jokainen API-kutsu tarkistettavaan tulokseen, jotta validointi, lokitus ja tuki voivat toistaa asiakkaan tilanteen

  • Käytä ensin pieniä toistettavia syötetiedostoja
  • Pidä tuotenimet, API-nimet, tiedostonimet ja literal-arvot muuttumattomina
  • Tallenna validatorin tuloste ja versiotiedot luodun esimerkkitiedoston kanssa

Koodi ja API-kohdat

Koodiesimerkit säilytetään muuttumattomina, jotta kehittäjä voi verrata niitä suoraan Delphi-, C++Builder- ja Lazarus/FPC-projekteihin

procedure TPreviewPane.LoadUntrusted(const FilePath: string);
begin
  Pdf.FileName := FilePath;
  Pdf.FormFill := False;     // no form environment, hence no JavaScript engine
  Pdf.Active := True;

  FPermissions := Pdf.Permissions;   // raw flag word; all bits set = unrestricted
end;
procedure TPreviewPane.PdfViewWebLinkClick(Sender: TObject;
  const Url: WString; var Handled: Boolean);
begin
  Handled := True;   // never fall through to the default shell behavior

  if (AnsiStartsText('https://', Url) or AnsiStartsText('http://', Url))
    and HostIsAllowed(Url) then
    OpenInBrowser(Url)
  else
    FAudit.LogBlockedLink(FDocumentId, Url);
end;
procedure TPreviewPane.ExportAttachment(Index: Integer; const TargetDir: string);
var
  RawName, SafeName, Ext: string;
  Data: TBytes;
begin
  RawName := string(Pdf.AttachmentName[Index]);
  SafeName := ExtractFileName(RawName);    // strips any path components
  Ext := LowerCase(ExtractFileExt(SafeName));

  if not FAllowedExt.Contains(Ext) then    // allowlist, not blocklist
    raise EPreviewPolicy.CreateFmt('Attachment type %s blocked by policy', [Ext]);

  Data := Pdf.Attachment[Index];           // embedded payload as raw bytes
  TFile.WriteAllBytes(
    IncludeTrailingPathDelimiter(TargetDir) + SafeName, Data);
end;

Tarkistus ennen julkaisua

Tarkista tulostiedosto samoilla työkaluilla, joita asiakas tai arkisto käyttää. Kirjaa komponenttiversio, testidata, validatorin versio ja havaittu tulos, jotta myöhempi regressio voidaan jäljittää täsmällisesti

Esikatseluruudun uhkamalli

Esikatselu käsittelee asiakkaan toimittamaa sisältöä, joten JavaScript, ulkoiset linkit ja liitteet on käsiteltävä epäluotettavina. Turvallisuusvalinta kuuluu latauspolkuun, ei vain käyttöliittymän painikkeisiin

JavaScript pois latauksessa

Poista komentosarjojen suoritus ennen dokumentin avaamista, jotta sivun tapahtumat eivät ehdi käynnistyä. Käyttöliittymän jälkikäteinen esto on liian myöhäinen varmistus

Linkit ja liitteet

Älä anna PDF:n valita käyttöjärjestelmän oletuskäsittelijää ilman vahvistusta. Suodata liitteiden tiedostopääte, nimi ja tallennuskansio ennen kuin sisältö pääsee sovelluksen ulkopuolelle