Apakah aman menyimpan sandi sebagai variabel lingkungan (bukan sebagai teks biasa) dalam file konfigurasi?

109

Saya mengerjakan beberapa aplikasi di rails, django (dan sedikit php), dan salah satu hal yang saya mulai lakukan di beberapa di antaranya adalah menyimpan database dan kata sandi lain sebagai variabel lingkungan daripada teks biasa di file konfigurasi tertentu ( atau di settings.py, untuk aplikasi django).

Saat mendiskusikan hal ini dengan salah satu kolaborator saya, dia menyarankan ini adalah praktik yang buruk - bahwa mungkin ini tidak seaman yang terlihat pada awalnya.

Jadi, saya ingin tahu - apakah ini praktik yang aman? Apakah lebih aman untuk menyimpan kata sandi sebagai teks biasa dalam file-file ini (pastikan, tentu saja, untuk tidak meninggalkan file-file ini di repo publik atau apa pun)?

jay
sumber

Jawaban:

45

Pada tingkat yang lebih teoritis, saya cenderung memikirkan tentang tingkat keamanan dengan cara berikut (dalam rangka meningkatkan kekuatan):

  • Tidak ada keamanan. Teks biasa. Siapapun yang tahu ke mana harus mencari, dapat mengakses data.
  • Keamanan dengan Kebingungan. Anda menyimpan data (teks biasa) di suatu tempat yang rumit, seperti variabel lingkungan, atau dalam file yang dimaksudkan agar terlihat seperti file konfigurasi. Seorang penyerang pada akhirnya akan mengetahui apa yang sedang terjadi, atau tersandung padanya.
  • Keamanan yang disediakan oleh enkripsi yang sepele untuk dibobol, (pikirkan caesar cipher!).
  • Keamanan disediakan oleh enkripsi yang dapat dipecahkan dengan beberapa upaya.
  • Keamanan disediakan oleh enkripsi yang tidak praktis untuk dibobol mengingat perangkat keras saat ini.
  • Sistem yang paling aman adalah yang tidak dapat digunakan oleh siapa pun! :)

Variabel lingkungan lebih aman daripada file teks biasa, karena mudah menguap / dibuang, tidak disimpan; yaitu jika Anda hanya menyetel variabel lingkungan lokal, seperti "set pwd = apapun," dan kemudian menjalankan skrip, dengan sesuatu yang keluar dari shell perintah Anda di akhir skrip, maka variabel tersebut tidak ada lagi. Kasus Anda termasuk dalam dua kasus pertama, yang menurut saya cukup tidak aman. Jika Anda akan melakukan ini, saya tidak akan merekomendasikan penerapan di luar jaringan intranet / rumah langsung Anda, dan kemudian hanya untuk tujuan pengujian.

John Carter
sumber
1
Itu tergantung pada sistem operasi - Pada kasus terbaik, variabel lingkungan sama rentannya dengan file teks biasa, tetapi kemungkinan lebih buruk. Dengan file teks biasa Anda dapat mengatur izin baca pada file / direktori untuk melindunginya. IIRC untuk variabel lingkungan, mereka tinggal di ruang memori untuk proses shell, sehingga cracker yang giat dapat memindai ruang itu untuk mencarinya.
John Carter
1
tunggu sebentar: jika Anda menyimpan kredensial di dalam variabel lingkungan, mereka harus sampai di sana terlebih dahulu. Baik dengan tangan, atau dengan naskah. Untuk mengotomatiskan startup perangkat lunak Anda, saya akan merekomendasikan sebuah skrip. Tapi coba tebak, maka Anda perlu menyimpannya dalam file konfigurasi (untuk variabel env). Kecuali Anda tidak memberikan nilai untuk variabel env secara manual, saya tidak dapat melihat perbedaan keamanan pada file konfigurasi.
matematika
59

Seperti disebutkan sebelumnya, kedua metode tidak memberikan lapisan "keamanan" tambahan setelah sistem Anda disusupi. Saya percaya bahwa salah satu alasan terkuat untuk memilih variabel lingkungan adalah kontrol versi : Saya telah melihat terlalu banyak konfigurasi basis data, dll. Disimpan secara diam-diam dalam sistem kontrol versi seperti GIT untuk dilihat oleh setiap pengembang lain (dan ups! Itu terjadi pada aku juga ...).

Tidak menyimpan kata sandi Anda dalam file membuatnya tidak mungkin untuk disimpan di sistem kontrol versi.

emrass
sumber
6
Alternatif yang cukup masuk akal untuk tidak menyimpan pengaturan konfigurasi rahasia dalam kontrol versi adalah menyimpannya dalam repositori atau proyek kontrol versi yang terpisah dari repositori untuk kode.
Kenny Evitt
1
@KennyEvitt yang masih meninggalkan kata sandi teks biasa yang tidak aman di lokasi bersama yang dapat ditemukan oleh siapa pun yang memiliki akses ke repositori dan tidak ada cara untuk melacak siapa yang mengaksesnya.
FistOfFury
2
@FistOfFury Tentu, siapa pun yang memiliki akses ke repositori ... dapat mengakses repositori. Inti dari menyimpan rahasia dalam repositori terpisah adalah agar seseorang dapat mengontrol akses ke rahasia tersebut secara berbeda dari kode itu sendiri. Tetapi repositori dapat diamankan, misalnya Anda dapat menyimpan rahasia yang dienkripsi di 'lokasi bersama'. Dan Anda bahkan dapat melacak info tentang akses ke repositori di lokasi bersama. Tetapi, tentu saja, mengizinkan siapa pun untuk mengakses info menyiratkan bahwa mereka dapat menyalin info itu dan dengan demikian mengaksesnya kapan saja di masa mendatang tanpa batasan atau pelacakan.
Kenny Evitt
2
Alasan bagus untuk menggunakan solusi manajemen konfigurasi yang memungkinkan Anda menyimpan rahasia terenkripsi, lalu menggantinya di template konfigurasi pada waktu perenderan. Chef memiliki kantong data terenkripsi, Ansible memiliki brankas, dll.
Brian Cline
1
Ini disebut Privileged Access Management, di mana rahasia disimpan di PAM Vault terpusat dengan kontrol akses yang komprehensif. Gartner mencantumkan beberapa produk semacam itu .
Amit Naidu
44

Setiap kali Anda harus menyimpan kata sandi, itu tidak aman. Titik. Tidak ada cara untuk menyimpan kata sandi yang tidak dienkripsi dengan aman. Sekarang mana dari variabel lingkungan vs. file konfigurasi yang lebih "aman" mungkin masih bisa diperdebatkan. IMHO, jika sistem Anda terganggu, tidak masalah di mana disimpan, peretas yang rajin dapat melacaknya.

Chris Pratt
sumber
12
Untuk variabel lingkungan, saya mengharapkan unix di sini ... Variabel lingkungan jauh kurang aman daripada file. Siapa pun dapat memeriksa lingkungan proses yang sedang berjalan, tetapi setidaknya file dapat memiliki ACL.
Vatine
11
Mengingat bahwa pengembang harus menyimpan kata sandi ini, ini bukan jawaban yang sangat membantu. Di mana Anda menyarankan agar dia menyimpannya?
Peter Nixey
2
@Vatine Places yang mengekspos variabel lingkungan memiliki izin juga. Coba cat /proc/1/environmisalnya.
Chris Down
4
@Vatine Benarkah? Saya tidak melihat lingkungan apa pun untuk proses yang tidak saya miliki di ps axe. strace -e open ps axemenunjukkan itu mendapatkan info ini dari /proc/[pid]/environ, yang memiliki penegakan izin (karenanya banyak open("/proc/19795/environ", O_RDONLY) = -1 EACCES (Permission denied)).
Chris Down
4
Hah. Lihatlah itu, masalah akhirnya telah diperbaiki (dulu itu psadalah setuid dan dengan senang hati akan menunjukkan lingkungan hampir semuanya).
Vatine
28

Maaf, saya tidak memiliki cukup perwakilan untuk berkomentar, tetapi saya juga ingin menambahkan bahwa jika Anda tidak berhati-hati, shell Anda mungkin menangkap kata sandi itu dalam riwayat perintahnya juga. Jadi menjalankan sesuatu seperti $ pwd=mypassword my_progsecara manual tidaklah sesingkat yang Anda harapkan.

brianclements
sumber
21
jika Anda mengawali seluruh "env var + command" dengan spasi, maka itu tidak akan disimpan dalam riwayat
shadi
terimakasih @yadi. Pelajari sesuatu yang baru setiap hari! Saya ingin tahu apakah itu khusus shell / mudah dimatikan atau apakah itu sesuatu yang dapat diharapkan secara konsisten?
brianclements
4
Cara lain adalah menggunakan read -s MY_PASS_VARyang akan melindungi dari penelusuran riwayat cangkang dan peselancar bahu.
MatrixManAtYrService
4
@brianclements Saya ingin menambahkan bahwa memberi awalan pada perintah dengan spasi hanya berfungsi jika shell saat HISTCONTROLini disetel ke ignorespaceatau ignoreboth, jadi secara teknis dapat diaktifkan / dinonaktifkan.
Musa
14

Saya pikir bila memungkinkan Anda harus menyimpan kredensial Anda dalam file gitignored dan bukan sebagai variabel lingkungan.

Salah satu hal yang perlu dipertimbangkan saat menyimpan kredensial dalam variabel ENV (lingkungan) vs file adalah variabel ENV dapat dengan mudah diperiksa oleh pustaka atau dependensi apa pun yang Anda gunakan.

Ini bisa dilakukan dengan niat jahat atau tidak. Misalnya, penulis perpustakaan dapat mengirim email pelacakan tumpukan ditambah variabel ENV ke dirinya sendiri untuk debugging (bukan praktik terbaik, tetapi mungkin dilakukan).

Jika kredensial Anda ada dalam file, maka memuncak ke dalamnya jauh lebih sulit.

Secara khusus, pikirkan tentang npm di node. Bagi seorang npm untuk melihat kredensial Anda jika mereka ada di ENV adalah masalah sederhana process.ENV. Jika di sisi lain mereka ada dalam sebuah file, itu lebih banyak pekerjaan.

Apakah file kredensial Anda dikontrol versi atau tidak adalah pertanyaan terpisah. Bukan versi yang mengontrol file kredensial Anda yang mengeksposnya ke lebih sedikit orang. Tidak perlu semua developer mengetahui kredensial produksi. Karena ini sesuai dengan prinsip hak istimewa paling rendah, saya sarankan git mengabaikan file kredensial Anda.

Peter Ajtai
sumber
6
+1 untuk "seorang penulis perpustakaan dapat mengirim email pelacakan tumpukan ditambah variabel ENV ke dirinya sendiri untuk debugging". Jangan pernah memikirkan skenario ini.
netishix
6

Itu tergantung pada model ancaman Anda.

Apakah Anda mencoba untuk mencegah pengguna Anda memercikkan kata sandi ke seluruh sistem file mereka di mana mereka kemungkinan besar akan dilupakan dan ditangani dengan salah? Jika demikian, maka ya, karena variabel lingkungan kurang persisten daripada file.

Apakah Anda mencoba melindungi dari sesuatu yang berbahaya yang secara langsung menargetkan program Anda? Jika demikian, maka tidak, karena variabel lingkungan tidak memiliki tingkat kontrol akses yang sama dengan file.

Secara pribadi, saya pikir pengguna yang lalai lebih umum daripada musuh yang termotivasi, jadi saya akan menggunakan pendekatan variabel lingkungan.

MatrixManAtYrService
sumber
0

AFAICT, ada dua alasan orang merekomendasikan penyimpanan rahasia dalam variabel lingkungan:

  1. Terlalu mudah untuk secara tidak sengaja mengkomit file flat rahasia ke repo. (Dan jika itu repo publik, Anda bersulang.)
  2. Ini mencegah kekacauan kata sandi, yaitu memiliki kunci yang sama di banyak file direktori proyek yang berbeda dengan sendirinya merupakan risiko keamanan karena pengembang pada akhirnya akan kehilangan jejak di mana rahasia berada.

Kedua masalah ini dapat diselesaikan dengan cara yang lebih baik. Yang pertama harus diselesaikan dengan git commit hook yang memeriksa hal-hal yang terlihat seperti kata sandi (mis., Gitleaks ). Saya berharap Linus membangun alat seperti itu ke dalam kode sumber perpustakaan git tetapi, sayangnya, itu tidak terjadi. (Tak perlu dikatakan, file rahasia harus selalu ditambahkan .gitignore, tetapi Anda memerlukan pengait jika seseorang lupa melakukannya.)

Yang terakhir ini dapat diselesaikan dengan memiliki file rahasia perusahaan global, yang idealnya disimpan di drive bersama hanya-baca. Jadi, dengan Python, Anda bisa mendapatkan sesuatu seperti from company_secrets import *.

Lebih penting lagi, seperti yang ditunjukkan oleh orang lain, terlalu mudah untuk meretas rahasia yang disimpan dalam variabel lingkungan. Misalnya, dalam Python, penulis perpustakaan dapat menyisipkan send_email(address="[email protected]", text=json.dumps(os.environ))dan kemudian Anda bersulang jika Anda menjalankan kode ini. Peretasan jauh lebih menantang jika Anda memiliki file di sistem Anda bernama ~/secret_company_stuff/.my_very_secret_company_stuff.

Hanya pengguna Django:
Django (dalam mode DEBUG) memperlihatkan nilai mentah dari variabel lingkungan di browser jika ada pengecualian (dalam mode DEBUG). Ini tampaknya sangat tidak aman jika, misalnya, pengembang secara tidak sengaja mulai DEBUG=Trueberproduksi. Sebaliknya, Django TIDAK mengaburkan variabel pengaturan password dengan mencari string API, TOKEN, KEY, SECRET, PASSatau SIGNATUREdalam rangka untuk settings.pynama variabel file.

pandichef
sumber