Bisakah penyimpanan lokal dianggap aman? [Tutup]

161

Saya diminta untuk mengembangkan aplikasi web yang akan berfungsi offline untuk jangka waktu lama. Agar hal ini dapat dilakukan, saya tidak dapat menghindari menyimpan data sensitif (data pribadi tetapi bukan jenis data yang Anda hanya akan menyimpan hash) di penyimpanan lokal.

Saya menerima bahwa ini bukan praktik yang disarankan, tetapi diberi sedikit pilihan, saya melakukan yang berikut untuk mengamankan data:

  • encyrypting semuanya masuk ke penyimpanan lokal menggunakan perpustakaan cryptto javascript stanford dan AES-256
  • kata sandi pengguna adalah kunci enkripsi dan tidak disimpan pada perangkat
  • melayani semua konten (saat daring) dari satu server tepercaya melalui ssl
  • memvalidasi semua data yang masuk dan dari penyimpanan lokal di server menggunakan proyek antisami owasp
  • di bagian jaringan appcache, tidak menggunakan *, dan sebaliknya hanya mencantumkan URI yang diperlukan untuk koneksi dengan server tepercaya
  • secara umum mencoba menerapkan pedoman yang disarankan dalam lembar contekan OWASP XSS

Saya menghargai bahwa iblis sering dalam detail, dan tahu ada banyak keraguan tentang penyimpanan lokal dan keamanan berbasis javascript secara umum. Adakah yang bisa berkomentar apakah ada:

  • kelemahan mendasar dalam pendekatan di atas?
  • ada solusi yang mungkin untuk kelemahan seperti itu?
  • ada cara yang lebih baik untuk mengamankan penyimpanan lokal ketika aplikasi html 5 harus berfungsi offline untuk jangka waktu lama?

Terima kasih atas bantuannya.

pengguna1173706
sumber
"Saya menerima bahwa ini bukan latihan yang disarankan" - Begitukah? Bukankah sebaliknya yang telah diciptakan sebenarnya untuk itu?
hakre
2
Untuk mengklarifikasi, maksud saya tidak disarankan praktik untuk menyimpan data sensitif di penyimpanan lokal.
user1173706
Seperti itu Anda tidak boleh melewatkan data sensitif melalui jaringan besar?
hakre
@ user1173706 Mengapa aplikasi harus berfungsi harus berjalan untuk waktu yang lama secara offline? Seperti apa para pengguna? Browser apa yang harus Anda dukung? Saya pikir itu mungkin tapi saya perlu tahu secara spesifik tentang skenario Anda .
Benjamin Gruenbaum
@Benjamin saya telah memperbarui pertanyaan. Terima kasih.
user1173706

Jawaban:

74

WebKripto

Kekhawatiran dengan kriptografi di javascript sisi-klien (peramban) dirinci di bawah ini. Semua kecuali satu dari masalah ini tidak berlaku untuk WebCrypto API , yang sekarang didukung dengan cukup baik .

Untuk aplikasi offline, Anda masih harus merancang dan menerapkan keystore yang aman.

Selain: Jika Anda menggunakan Node.js, gunakan API crypto bawaan .

Kriptografi Asli-Javascript (pra-WebKripto)

Saya kira perhatian utama adalah seseorang dengan akses fisik ke komputer membaca localStorageuntuk situs Anda, dan Anda ingin kriptografi untuk membantu mencegah akses itu.

Jika seseorang memiliki akses fisik Anda juga terbuka terhadap serangan selain dan lebih buruk daripada membaca. Ini termasuk (tetapi tidak terbatas pada): keyloggers, modifikasi skrip luring, injeksi skrip lokal, keracunan cache browser, dan pengalihan DNS. Serangan-serangan itu hanya berfungsi jika pengguna menggunakan mesin setelah kompromi. Namun demikian, akses fisik dalam skenario seperti itu berarti Anda memiliki masalah yang lebih besar.

Jadi perlu diingat bahwa skenario terbatas di mana kripto lokal bernilai adalah jika mesin dicuri.

Ada perpustakaan yang menerapkan fungsionalitas yang diinginkan, misalnya Perpustakaan Stanford Javascript Crypto . Meskipun demikian, ada kelemahan bawaan (sebagaimana dimaksud dalam tautan dari jawaban @ ircmaxell):

  1. Kurangnya entropi / angka nomor acak;
  2. Kurangnya keystore aman yaitu kunci pribadi harus dilindungi kata sandi jika disimpan secara lokal, atau disimpan di server (yang melarang akses luring);
  3. Kurangnya penghapusan aman;
  4. Kurangnya karakteristik waktu.

Masing-masing kelemahan ini sesuai dengan kategori kompromi kriptografi. Dengan kata lain, walaupun Anda mungkin memiliki nama "crypto", itu akan jauh di bawah kerasnya yang dicita-citakan dalam praktik.

Semua yang dikatakan, penilaian aktuaria tidak sepele seperti "Javascript kripto lemah, jangan gunakan itu". Ini bukan endorsemen, hanya peringatan dan mengharuskan Anda untuk sepenuhnya memahami paparan kelemahan di atas, frekuensi dan biaya vektor yang Anda hadapi, dan kapasitas Anda untuk mitigasi atau asuransi jika terjadi kegagalan: Javascript crypto, di Terlepas dari kelemahannya, dapat mengurangi eksposur Anda tetapi hanya terhadap pencuri dengan kapasitas teknis terbatas. Namun, Anda harus menganggap Javascript crypto tidak memiliki nilai terhadap penyerang yang ditentukan dan mampu yang menargetkan informasi itu. Beberapa akan menganggap itu menyesatkan untuk menyebut data "dienkripsi" ketika begitu banyak kelemahan diketahui melekat pada implementasi. Dengan kata lain, Anda sedikit dapat mengurangi eksposur teknis Anda tetapi Anda meningkatkan eksposur keuangan Anda dari pengungkapan. Setiap situasi berbeda, tentu saja - dan analisis untuk mengurangi eksposur teknis terhadap eksposur keuangan adalah non-sepele. Berikut ini adalah analogi ilustrasi:Beberapa bank memerlukan kata sandi yang lemah , terlepas dari risiko yang melekat, karena paparan mereka terhadap kata sandi yang lemah lebih kecil daripada biaya pengguna akhir untuk mendukung kata sandi yang kuat.

🔥 Jika Anda membaca paragraf terakhir dan berpikir "Seseorang di Internet bernama Brian bilang saya bisa menggunakan Javascript crypto", jangan gunakan Javascript crypto.

Untuk kasus penggunaan yang dijelaskan dalam pertanyaan, tampaknya lebih masuk akal bagi pengguna untuk mengenkripsi partisi lokal atau direktori home mereka dan menggunakan kata sandi yang kuat. Jenis keamanan itu umumnya diuji dengan baik, dipercaya luas, dan umumnya tersedia.

Brian M. Hunt
sumber
Ada dokumentasi tambahan (kutipan) yang tersedia untuk posisi umum "jangan gunakan JavaScript crypto" yang disediakan oleh NCC Group dari 2011: Kriptografi JavaScript Dianggap Berbahaya (terutama karena tangkapan ke-22 pengunduhan alat untuk memverifikasi unduhan ... kualitas PRNG … Dll.)
amcgregor
58

Nah, premis dasar di sini adalah: tidak, belum aman.

Pada dasarnya, Anda tidak dapat menjalankan crypto di JavaScript: JavaScript Crypto Dianggap Berbahaya .

Masalahnya adalah Anda tidak bisa mendapatkan kode kripto ke dalam browser dengan andal, dan bahkan jika Anda bisa, JS tidak dirancang untuk membiarkan Anda menjalankannya dengan aman. Jadi sampai browser memiliki wadah kriptografi (yang disediakan oleh Ekstensi Media Terenkripsi, tetapi sedang digalakkan untuk tujuan DRM mereka), itu tidak mungkin dilakukan dengan aman.

Sejauh "Cara yang lebih baik", tidak ada satu pun saat ini. Satu-satunya alternatif Anda adalah menyimpan data dalam teks biasa, dan berharap yang terbaik. Atau jangan menyimpan informasi sama sekali. Either way.

Entah itu, atau jika Anda memerlukan keamanan semacam itu, dan Anda memerlukan penyimpanan lokal, buat aplikasi khusus ...

ircmaxell
sumber
8
Downvoter: dapatkah Anda memberikan jawaban yang lebih baik? Saya menyadari bahwa ini adalah masalah yang agak kontroversial di mana ada perbedaan pendapat yang signifikan antara profesional keamanan (dan non-profesional juga), sehingga sudut pandang alternatif akan layak untuk dibagikan. Kecuali Anda downvot karena alasan lain, bagaimana saya bisa memperbaiki jawaban ini?
ircmaxell
9
@ircmaxell bukan aku, tapi aku tidak setuju dengan jawaban ini. "Masalahnya adalah Anda tidak bisa mendapatkan kode kripto ke dalam browser dengan andal, dan bahkan jika Anda bisa, JS tidak dirancang untuk membiarkan Anda menjalankannya dengan aman." - Kenapa? Apa masalah yang melekat ? Anda dapat menggunakan perpustakaan enkripsi Stanford JavaScript dan mengenkripsi / mendekripsi di dalamnya. Anda dapat hash, dan Anda dapat melakukan semuanya dengan aman. Saya tidak melihat masalah inheren di sini di aplikasi offline di JS yang melakukan crpyto standar, seperti halnya aplikasi yang dibuat dalam bahasa lain.
Benjamin Gruenbaum
11
@BenjaminGruenbaum: masalahnya adalah ada beberapa tempat di mana kode crypto perlu berinteraksi dengan kode pihak ketiga. Inti dari artikel yang saya tautkan adalah bahwa Anda tidak dapat mengontrol lingkungan eksekusi. Jadi Anda menginstal lib Stanford Crypto. Lalu apa yang terjadi jika beberapa plugin browser diganti sjcl.encryptuntuk mengirim email kunci ke penyerang? Di JS itu 100% mungkin dan tidak ada yang bisa Anda lakukan untuk menghentikannya. Dan itulah intinya. Tidak ada mekanisme "keamanan" untuk mencegah JS lain melakukan hal-hal buruk pada data Anda. Dan itu masalah .
ircmaxell
13
@ircmaxell Jika Anda tidur dengan anjing, Anda tidak bisa berharap untuk tidak bangun dengan kutu. Jika pengguna menginstal tambahan malware yang sama dengan pengguna menginstal virus di PC mereka, itu tidak berbeda dari itu. Program Java atau C Anda bisa seaman mungkin, tetapi segera setelah penyerang memiliki kemampuan untuk menjalankan kode Anda sedang kacau. Itu tidak berbeda untuk JS. Addons tidak hanya muncul secara ajaib di browser. Selain itu, tidak menyimpan informasi yang dienkripsi tidak akan membantu dengan cara apa pun jika pengguna memiliki malware, karena itu bisa saja membajak data secara langsung.
Benjamin Gruenbaum
9
@BenjaminGruenbaum: tidak setuju. Dalam aplikasi normal, Anda akan perlu baik untuk kompromi aplikasi tersebut (untuk membaca lokasi memori), atau mendapatkan akses root untuk kotak (kompromi OS). Either way, Anda perlu kompromi sesuatu yang lebih dalam daripada sekadar perilaku normal. JS memungkinkan ini dalam perilaku normal. Yang mana masalahnya ...
ircmaxell
12

Sebagai eksplorasi topik ini, saya memiliki presentasi berjudul "Mengamankan TodoMVC Menggunakan API Kriptografi Web" ( video , kode ).

Ia menggunakan API Kriptografi Web untuk menyimpan daftar todo yang dienkripsi dalam penyimpanan lokal dengan kata sandi melindungi aplikasi dan menggunakan kunci turunan kata sandi untuk enkripsi. Jika Anda lupa atau kehilangan kata sandi, tidak ada pemulihan. ( Penafian - itu adalah POC dan tidak dimaksudkan untuk penggunaan produksi. )

Sebagai jawaban lain menyatakan, ini masih rentan terhadap XSS atau malware yang diinstal pada komputer klien. Namun, data sensitif apa pun juga akan berada di memori ketika data disimpan di server dan aplikasi sedang digunakan. Saya menyarankan bahwa dukungan offline mungkin merupakan use case yang meyakinkan.

Pada akhirnya, mengenkripsi localStorage mungkin hanya melindungi data dari penyerang yang hanya membaca akses ke sistem atau cadangannya. Ini menambahkan sejumlah kecil pertahanan mendalam untuk OWASP 10 item A6-Sensitive Data Exposure , dan memungkinkan Anda untuk menjawab "Apakah ada dari data ini yang disimpan dalam teks yang jelas dalam jangka panjang?" benar.

Kevin Hakanson
sumber
3

Ini adalah artikel yang sangat menarik di sini. Saya sedang mempertimbangkan menerapkan enkripsi JS untuk menawarkan keamanan saat menggunakan penyimpanan lokal. Sangat jelas bahwa ini hanya akan menawarkan perlindungan jika perangkat dicuri (dan diterapkan dengan benar). Itu tidak akan menawarkan perlindungan terhadap keylogger dll. Namun ini bukan masalah JS karena ancaman keylogger adalah masalah semua aplikasi, terlepas dari platform eksekusi mereka (browser, asli). Mengenai artikel "JavaScript Crypto Dianggap Berbahaya" yang dirujuk dalam jawaban pertama, saya punya satu kritik; itu menyatakan "Anda bisa menggunakan SSL / TLS untuk menyelesaikan masalah ini, tapi itu mahal dan rumit". Saya pikir ini adalah klaim yang sangat ambisius (dan mungkin agak bias). Ya, SSL memiliki biaya,

Kesimpulan saya - Ada tempat untuk kode enkripsi sisi klien, namun seperti halnya semua aplikasi, pengembang harus mengenali keterbatasannya dan menerapkannya jika sesuai dengan kebutuhan mereka, dan memastikan ada cara untuk mengurangi risiko itu.

Paul S
sumber
Secara historis ada biaya luar biasa (mekanik, bukan keuangan) yang terkait dengan negosiasi koneksi awal. Sampai pada titik bahwa perusahaan akan menggunakan peralatan terminasi SSL khusus, yang dapat menjadi mahal secara finansial di luar penerbitan sertifikat dan biaya jaminan. Saat ini banyak dari masalah tersebut telah diselesaikan, seperti persistensi sesi durasi yang diperpanjang untuk menghindari jabat tangan awal pada permintaan berikutnya.
amcgregor
2

Tidak dapat diakses ke halaman web mana pun (benar) tetapi mudah diakses dan mudah diedit melalui alat dev, seperti chrome (ctl-shift-J). Karenanya, custom crypto diperlukan sebelum menyimpan nilai.

Tetapi, jika javascript perlu mendekripsi (untuk memvalidasi) maka algoritma dekripsi terbuka dan dapat dimanipulasi.

Javascript membutuhkan wadah yang sepenuhnya aman dan kemampuan untuk mengimplementasikan variabel dan fungsi pribadi dengan benar yang hanya tersedia untuk juru bahasa js. Namun, ini melanggar keamanan pengguna - karena melacak data dapat digunakan tanpa impunitas.

Akibatnya, javascript tidak akan pernah sepenuhnya aman.

rockmo
sumber
-29

Tidak.

localStorage dapat diakses oleh halaman web mana pun, dan jika Anda memiliki kuncinya, Anda dapat mengubah data apa pun yang Anda inginkan.

Yang sedang berkata, jika Anda dapat menemukan cara untuk mengenkripsi kunci dengan aman, tidak masalah bagaimana Anda mentransfer data, jika Anda dapat berisi data dalam penutupan, maka data (agak) aman.

hellol11
sumber
19
Ini tidak dapat diakses oleh "halaman web apa pun". Ini hanya dapat diakses ke halaman di domain saat ini.
dtabuenc
@ Dtabuenc sebaliknya, saya membuat pena beberapa waktu lalu yang menunjukkan Anda setiap pasangan kunci / nilai tunggal di localStorage Anda , tanpa peretasan.
hellol11
3
Nggak! Maaf. Penyimpanan lokal terisolasi per-domain. Kode yang berjalan di satu domain tidak dapat mengakses nilai yang disimpan ke penyimpanan lokal oleh domain lain. Misalnya, google.com menyimpan banyak barang di penyimpanan lokal. Anda tidak akan dapat mencantumkan tombol apa pun dari google.com dalam contoh pena Anda.
dtabuenc
@dtabuenc mengujinya, Anda benar.
hellol11