دسته OWASP: MASVS-STORAGE: ذخیره سازی
نمای کلی
ذخیره سازی داده ها در حافظه خارجی بدون فضای ذخیره سازی محدوده هیچ تضمین امنیتی ندارد. نوشتن فایل های حساس در حافظه خارجی می تواند منجر به قرار گرفتن در معرض داده های حساس شود.
تاثیر
اگر دادههای حساس در حافظه خارجی ذخیره شوند، هر برنامهای روی دستگاه میتواند به آن دسترسی داشته باشد و دادهها را در معرض خطر غیرضروری قرار دهد. علاوه بر این، اگر فایلهای ذخیره شده در حافظه خارجی در برنامه بارگذاری شوند، ممکن است در این فاصله دادهها دستکاری شده باشند. داده های تغییر یافته می تواند برای فریب کاربران یا حتی اجرای کد در برنامه بارگذاری طراحی شود.
اقدامات کاهشی
استفاده از Scoped Storage (اندروید 10 و بالاتر)
برای اندروید نسخه 10 و بالاتر، میتوان از فضای ذخیرهسازی محدوده استفاده کرد. این قابلیت استفاده از حافظه خارجی را ارائه می دهد، در حالی که از داده ها در برابر سایر برنامه ها محافظت می کند. با فضای ذخیرهسازی دامنه، برنامهها فقط میتوانند به فایلهایی که خودشان ایجاد کردهاند یا فایلهایی که در پوشه دانلودهای عمومی هستند دسترسی داشته باشند. این به محافظت از حریم خصوصی و امنیت کاربر کمک می کند.
از حافظه داخلی استفاده کنید
در صورت امکان، باید از حافظه داخلی برنامه مخصوصا برای داده های حساس استفاده شود. دسترسی به فضای ذخیره سازی مذکور محدود به برنامه مالک است و بنابراین می توان آن را ایمن در نظر گرفت، مگر اینکه دستگاه روت شده باشد.
رمزگذاری داده های حساس
اگر داده های حساس در حافظه خارجی ذخیره می شوند، باید رمزگذاری شوند. یک الگوریتم رمزگذاری قوی با استفاده از Android KeyStore برای نگهداری ایمن کلید توصیه می شود.
به یاد داشته باشید که به عنوان یک عمل امنیتی عمیق، همه داده های حساس باید رمزگذاری شوند، مهم نیست در کجا ذخیره می شوند.
توجه به این نکته مهم است که رمزگذاری کامل دیسک (یا رمزگذاری مبتنی بر فایل از اندروید 10) اقدامی است که هدف آن محافظت از داده ها در برابر دسترسی فیزیکی و سایر بردارهای حمله است. برای این مثال خاص، داده های حساس باید علاوه بر این توسط برنامه رمزگذاری شوند.
انجام بررسی های یکپارچگی
در مواردی که داده یا کد باید از حافظه خارجی در برنامه بارگیری شود، بررسی یکپارچگی برای تأیید اینکه هیچ برنامه دیگری در این داده یا کد دستکاری نشده است توصیه می شود. هش های فایل ها باید به صورت ایمن، ترجیحا رمزگذاری شده و در حافظه داخلی ذخیره شوند.
کاتلین
package com.example.myapplication
import java.io.BufferedInputStream
import java.io.FileInputStream
import java.io.IOException
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
object FileIntegrityChecker {
@Throws(IOException::class, NoSuchAlgorithmException::class)
fun getIntegrityHash(filePath: String?): String {
val md = MessageDigest.getInstance("SHA-256") // You can choose other algorithms as needed
val buffer = ByteArray(8192)
var bytesRead: Int
BufferedInputStream(FileInputStream(filePath)).use { fis ->
while (fis.read(buffer).also { bytesRead = it } != -1) {
md.update(buffer, 0, bytesRead)
}
}
private fun bytesToHex(bytes: ByteArray): String {
val sb = StringBuilder()
for (b in bytes) {
sb.append(String.format("%02x", b))
}
return sb.toString()
}
@Throws(IOException::class, NoSuchAlgorithmException::class)
fun verifyIntegrity(filePath: String?, expectedHash: String): Boolean {
val actualHash = getIntegrityHash(filePath)
return actualHash == expectedHash
}
@Throws(Exception::class)
@JvmStatic
fun main(args: Array<String>) {
val filePath = "/path/to/your/file"
val expectedHash = "your_expected_hash_value"
if (verifyIntegrity(filePath, expectedHash)) {
println("File integrity is valid!")
} else {
println("File integrity is compromised!")
}
}
}
جاوا
package com.example.myapplication;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class FileIntegrityChecker {
public static String getIntegrityHash(String filePath) throws IOException, NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA-256"); // You can choose other algorithms as needed
byte[] buffer = new byte[8192];
int bytesRead;
try (BufferedInputStream fis = new BufferedInputStream(new FileInputStream(filePath))) {
while ((bytesRead = fis.read(buffer)) != -1) {
md.update(buffer, 0, bytesRead);
}
}
byte[] digest = md.digest();
return bytesToHex(digest);
}
private static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
public static boolean verifyIntegrity(String filePath, String expectedHash) throws IOException, NoSuchAlgorithmException {
String actualHash = getIntegrityHash(filePath);
return actualHash.equals(expectedHash);
}
public static void main(String[] args) throws Exception {
String filePath = "/path/to/your/file";
String expectedHash = "your_expected_hash_value";
if (verifyIntegrity(filePath, expectedHash)) {
System.out.println("File integrity is valid!");
} else {
System.out.println("File integrity is compromised!");
}
}
}
منابع
- فضای ذخیره سازی
- مروری بر ذخیره سازی داده ها و فایل ها
- ذخیره سازی داده (ویژه برنامه)
- رمزنگاری
- فروشگاه کلید
- رمزگذاری مبتنی بر فایل
- رمزگذاری فول دیسک