Dlaczego shebang potrzebuje ścieżki?
Źle
#!ruby
Poprawny
#!/usr/local/bin/ruby
#!/usr/bin/env ruby
System operacyjny powinien mieć informacje dotyczące ścieżki zarejestrowanego polecenia i dlaczego nadal oczekuje na jego podanie?
Prawdopodobnie w celu uproszczenia jądra. Nie sądzę, aby jądro kiedykolwiek przeszukiwało twoją ścieżkę w celu znalezienia pliku wykonywalnego. Jest to obsługiwane przez bibliotekę C. #!
przetwarzanie odbywa się w jądrze, które nie korzysta ze standardowej biblioteki C.
Nie sądzę też, aby jądro miało pojęcie o twojej ścieżce. $PATH
jest zmienną środowiskową i tylko procesy mają środowisko. Jądro nie. Przypuszczam, że może on uzyskać dostęp do środowiska procesu, który wykonał exec, ale nie sądzę, aby cokolwiek w jądrze kiedykolwiek uzyskiwało dostęp do takich zmiennych środowiskowych.
Możesz uzyskać PATH
-semantykę wyszukiwania env
, więc:
#!/usr/bin/env ruby
ma semantykę, z której chcesz
#!ruby
Powodem, dla którego zależność PATH
nie jest uważana za dobrą praktykę, jest to, że skrypt nie może przyjmować żadnych założeń dotyczących zawartości zmiennej środowiskowej PATH, niszcząc „sekwencyjny model zależności” plików binarnych, w których
/bin
zawiera pliki wykonywalne potrzebne podczas rozruchu;/usr/bin
zawiera inne pliki wykonywalne używane podczas instalacji systemu operacyjnego;/usr/local/bin
zawiera pliki wykonywalne zainstalowane przez administratora systemu, które nie są częścią podstawowego systemu operacyjnego.~/bin
zawiera własne pliki wykonywalne użytkownika.Każdy poziom nie powinien zakładać istnienia plików binarnych w dalszej kolejności, które są bardziej „aplikacjami”, ale mogą polegać na plikach binarnych, które są bardziej „fundamentalne”. Zmienna PATH ma tendencję do działania od aplikacji do fundamentu, co jest odwrotnym kierunkiem do naturalnej zależności powyżej.
Aby zilustrować problem, zadaj sobie pytanie, co się stanie, jeśli skrypt ~/bin
wywołuje skrypt, /usr/local/bin
który wywołuje Ruby? Czy ten skrypt powinien zależeć od wersji zainstalowanej systemu operacyjnego /usr/bin/ruby
, czy od osobistej kopii, w której użytkownik ma ten plik ~/bin/ruby
? PATH
wyszukiwanie daje nieprzewidywalną semantykę związaną z tym drugim (być może ~/bin/ruby
jest zerwanym łączem symbolicznym), a pieczenie na ścieżce #!
daje to pierwsze.
Tak naprawdę nie ma innego niezależnego od platformy „systemu operacyjnego ... informacji dotyczących ścieżki zarejestrowanego polecenia”, więc najprościej jest nalegać na podanie ścieżki w #!
.
Wierzę, że tak, więc możesz określić alternatywnego tłumacza, jeśli potrzebujesz lub chcesz. Na przykład:
#!/home/user/myrubyinterpreter
Częściej spotykane ze skryptami powłoki:
#!/bin/bash
#!/bin/sh
#!/bin/dash
#!/bin/csh
ruby
, ale to nie powstrzymuje cię przed określeniem,/home/user/myrubyinterpreter
czy chceszZ książki Classic Shell Scripting :
źródło
Są inne powody, ale z punktu widzenia bezpieczeństwa nigdy nie chciałbym, aby skrypt przyjmował założenia dotyczące właściwej ścieżki. Co jeśli jest źle i uruchamia niewłaściwą powłokę lub interpretera? Ten, który został wstawiony przez złośliwego użytkownika? A co, jeśli opiera się na konkretnej powłoce i ulegnie awarii, jeśli zostanie użyta niewłaściwa powłoka?
Użytkownicy mogą zepsuć swoją ścieżkę i popsuć różne rzeczy - nie ufaj użytkownikowi :-) Przeprowadziłem wiele ataków, które polegają na tym, że użytkownik robi coś złego na swojej ścieżce - zwykle robi to w złej kolejności - więc mogę obalić normalne wywołanie skryptu.
Tak, wiem, że jeśli sam napisałeś skrypt, możesz słusznie twierdzić, że wytyczyłeś własną ścieżkę, ale tłumacz nie może podejmować tych decyzji.
źródło
$PATH
. . Bez podwyższonych uprawnień co się stanie, jeśliLD_PRELOAD
zostanie użyty? PS Przegłosowano, ponieważ fałszywe ostrzeżenie o bezpieczeństwie jest szkodliwe dla bezpieczeństwa.PATH
wektor ataku jest niewystarczający, i że nie ma tak wielu wektorów ataku, że należy ponownie przemyśleć całe podejście?