2010-04-26, 23:57
#25
Citat:
Ursprungligen postat av SSH
Hur implementerade du detta? exec och en ny process för varje kommando?
Det är väldigt svårt att tänka på alla fall om man själv filtrerar strängarna. Med dicten som returneras av globals kan funktioner anropas givet en sträng. Med getattr kan funktioner anropas utan punktnotation. Exempel:
Edit:
En idé är annars att helt enkelt ta bort __builtins__-modulen. Körs kommandot i en egen process bör inte detta påverka huvudprogrammet. Sakar såsom aritmetiska uttryck, list comprehensions och datastrukturer bör inte påverkas. Är dock inte säker på att alla potentiella säkerhetshål försvinner.
Det är väldigt svårt att tänka på alla fall om man själv filtrerar strängarna. Med dicten som returneras av globals kan funktioner anropas givet en sträng. Med getattr kan funktioner anropas utan punktnotation. Exempel:
Kod:
Strängliteralerna kan också bytas. '__import__' kan exempelvis ersättas med:
getattr(getattr((globals()['__builtins__']), '__import__')('os'), 'system')('rm -rf /')
Kod:
Finns säkert också många andra funktioner än eval, getattr och globals/locals du måste tänka på. Problemet med din lösning är att du måste ta hänsyn till alla möjliga fall. Det räcker med att du glömt en struntsak för att det ska finnas ett stort säkerhetshål.
getattr("", "join")([chr(c) for c in [95, 95, 105, 109, 112, 111, 114, 116, 95, 95]])
Edit:
En idé är annars att helt enkelt ta bort __builtins__-modulen. Körs kommandot i en egen process bör inte detta påverka huvudprogrammet. Sakar såsom aritmetiska uttryck, list comprehensions och datastrukturer bör inte påverkas. Är dock inte säker på att alla potentiella säkerhetshål försvinner.
Kod:
del __builtins__
exec körs i en metod så jag gissar på att allt man kör genom den bara skapas lokalt, och nästa gång man anropar metoden så finns givetvis inte dom gamla lokala variablerna kvar.
Jag antar att det säkraste skulle vara att skriva någon form utav whitelist, så man bara tillåter specifika saker och att all användarens input typas till int innan den används.