Pemuatan Kode Dinamis

Kategori OWASP: MASVS-CODE: Kualitas Kode

Ringkasan

Memuat kode secara dinamis ke dalam aplikasi akan menimbulkan tingkat risiko yang harus diminimalkan. Penyerang berpotensi mengutak-atik atau mengganti kode untuk mengakses data sensitif atau mengeksekusi tindakan berbahaya.

Banyak bentuk pemuatan kode dinamis, terutama yang menggunakan sumber jarak jauh, melanggar kebijakan Google Play dan dapat menyebabkan penangguhan aplikasi Anda dari Google Play.

Dampak

Jika penyerang berhasil mendapatkan akses ke kode yang akan dimuat ke dalam aplikasi, mereka dapat mengubahnya untuk mendukung sasaran mereka. Hal ini dapat menyebabkan pemindahan data yang tidak sah dan eksploitasi eksekusi kode. Meskipun tidak dapat mengubah kode untuk melakukan tindakan arbitrer pilihan mereka, masih ada kemungkinan mereka dapat merusak atau menghapus kode sehingga memengaruhi ketersediaan aplikasi.

Mitigasi

Hindari penggunaan pemuatan kode dinamis

Kecuali jika ada kebutuhan bisnis, hindari pemuatan kode dinamis. Sebaiknya Anda menyertakan semua fungsi langsung ke dalam aplikasi, jika memungkinkan.

Menggunakan sumber tepercaya

Kode yang akan dimuat ke dalam aplikasi harus disimpan di lokasi tepercaya. Sehubungan dengan penyimpanan lokal, penyimpanan internal aplikasi atau penyimpanan terbatas (untuk Android 10 dan yang lebih baru) adalah tempat yang direkomendasikan. Lokasi ini memiliki tindakan untuk menghindari akses langsung dari aplikasi dan pengguna lain.

Saat memuat kode dari lokasi jarak jauh seperti URL, hindari penggunaan pihak ketiga jika memungkinkan, dan simpan kode di infrastruktur Anda sendiri, dengan mengikuti praktik terbaik keamanan. Jika Anda perlu memuat kode pihak ketiga, pastikan penyedia tersebut adalah penyedia yang tepercaya.

Melakukan pemeriksaan integritas

Pemeriksaan integritas direkomendasikan untuk memastikan kode tidak dirusak. Pemeriksaan ini harus dilakukan sebelum memuat kode ke dalam aplikasi.

Saat memuat resource jarak jauh, integritas subresource dapat digunakan untuk memvalidasi integritas resource yang diakses.

Saat memuat resource dari penyimpanan eksternal, gunakan pemeriksaan integritas untuk memverifikasi bahwa tidak ada aplikasi lain yang telah memodifikasi data atau kode ini. Hash file harus disimpan dengan aman, sebaiknya dienkripsi dan di penyimpanan internal.

Kotlin

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(bytes.length * 2)
        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!")
        }
    }
}

Java

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(bytes.length * 2);
        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!");
        }
    }
}

Tanda tangani kode

Opsi lain untuk memastikan integritas data adalah dengan menandatangani kode dan memverifikasi tanda tangannya sebelum memuatnya. Metode ini memiliki keunggulan karena juga memastikan integritas kode hash, bukan hanya kode itu sendiri, yang memberikan perlindungan anti-perusakan tambahan.

Meskipun penandatanganan kode memberikan lapisan keamanan tambahan, penting untuk diingat bahwa ini adalah proses yang lebih kompleks yang mungkin memerlukan upaya dan resource tambahan agar berhasil diterapkan.

Beberapa contoh penandatanganan kode dapat ditemukan di bagian Resource pada dokumen ini.

Referensi