ProgrammatieBackend ontwikkelaar

Wat is het verschil tussen het gebruik van eval BLOCK en eval STRING in Perl, wat zijn de kenmerken van foutafhandeling en veiligheid van elk van de opties?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord

In Perl zijn er twee syntaxis voor de eval constructie:

  1. eval BLOCK — voert een codeblok uit als een beveiligd blok, waarbij fatale runtime-fouten worden opgevangen. Het gebruikt de bestaande variabelen scope en vereist geen compilatie van de code tijdens runtime.
  2. eval STRING — compileert en voert een string uit als Perl-code tijdens runtime. Het kan dynamisch gegenereerde code uitvoeren en wordt gebruikt voor het creëren van dynamische subroutines, maar is gevaarlijk qua veiligheid (kan willekeurige, potentieel gevaarlijke code uitvoeren, vooral als de string is samengesteld uit externe gegevens).

Kenmerken van foutafhandeling:

  • In beide gevallen wordt een fatale fout opgevangen, en de globale variabele $@ bevat de foutmelding (als er een fout was), anders is $@ leeg.
  • eval BLOCK is sneller, veiliger en te verkiezen wanneer het niet nodig is om dynamische code uit te voeren.
  • eval STRING is handig voor dynamische codecreatie, maar compileert de string aanvullend, wat langzamer en potentieel gevaarlijker is.
# Voorbeeld van het gebruik van eval BLOCK my $result = eval { die "Error!" unless 1 + 1 == 2; return "OK"; }; if ($@) { warn "Error caught: $@"; } # Voorbeeld van het gebruik van eval STRING my $code = '$x = 1 + 2; $x;'; my $res = eval $code; if ($@) { warn "Eval string error: $@"; }

Vragend met een valstrik

Als er dynamisch substitueerbare variabelen binnen eval STRING worden geplaatst zonder de juiste escaping, kunnen er extra risico's ontstaan?

Ja, als de te substitueren string wordt samengesteld uit variabelen, vooral als ze van buitenaf zijn verkregen (bijvoorbeeld van gebruikersinvoer), ontstaat er een bedreiging voor beveiliging/injectie. Het is altijd nodig om escaping te gebruiken of eval STRING niet te gebruiken voor externe gegevens.

my $user_code = 'system("rm -rf /");'; eval $user_code; # HEEL GEVAARLIJK!

Voorbeelden van echte fouten door onwetendheid over de nuances van het onderwerp


Verhaal

In een auditeringsscript voor het controleren van de parameters van virtuele machines werd eval STRING gebruikt, waarin "per ongeluk" gegevens terechtkwamen die uit een extern configuratiebestand waren gelezen. Op een dag werd het bestand vervangen, wat leidde tot het uitvoeren van de code van een aanvaller en de compromittering van de server.


Verhaal

Een ontwikkelaar wikkelde een potentieel crasher stukje code in eval BLOCK, in de veronderstelling dat het niet alleen runtime-fouten zou "oppakken" maar ook compile-time fouten (bijvoorbeeld syntaxisfouten). Maar een syntaxisfout (bijvoorbeeld een typfout in de naam van een variabele) wordt niet opgevangen door eval BLOCK — het leidde tot een crash van het proces.


Verhaal

Bij het deserialiseren van complexe gegevensstructuren via eval STRING na een Dumper-dump, vergaten ze te controleren of de string alleen geldige Perl-code bevatte — een gebruiker voegde uitvoerbare code toe via input-injectie, wat leidde tot de uitvoering van kwaadaardige commando's op de server.