OWASP বিভাগ: MASVS-CODE: কোডের গুণমান
সংক্ষিপ্ত বিবরণ
কোনো অ্যাপ্লিকেশনে ডায়নামিকভাবে কোড লোড করা একটি ঝুঁকির সৃষ্টি করে, যা প্রশমিত করা প্রয়োজন। আক্রমণকারীরা সংবেদনশীল তথ্য অ্যাক্সেস করতে বা ক্ষতিকর কার্যকলাপ চালানোর জন্য কোডটি বিকৃত করতে বা প্রতিস্থাপন করতে পারে।
ডাইনামিক কোড লোডিংয়ের অনেক পদ্ধতি, বিশেষ করে যেগুলো রিমোট সোর্স ব্যবহার করে, গুগল প্লে-র নীতিমালা লঙ্ঘন করে এবং এর ফলে গুগল প্লে থেকে আপনার অ্যাপটি সাসপেন্ড হয়ে যেতে পারে।
প্রভাব
যদি আক্রমণকারীরা অ্যাপ্লিকেশনে লোড করা কোডের অ্যাক্সেস পেতে সক্ষম হয়, তবে তারা তাদের লক্ষ্য পূরণের জন্য এটি পরিবর্তন করতে পারে। এর ফলে ডেটা পাচার এবং কোড এক্সিকিউশন এক্সপ্লয়েট ঘটতে পারে। এমনকি যদি আক্রমণকারীরা তাদের ইচ্ছামতো কাজ করার জন্য কোডটি পরিবর্তন করতে না-ও পারে, তবুও তারা কোডটি বিকৃত বা মুছে ফেলতে পারে এবং এর ফলে অ্যাপ্লিকেশনটির কার্যকারিতাকে প্রভাবিত করতে পারে।
প্রশমন
ডাইনামিক কোড লোডিং ব্যবহার করা এড়িয়ে চলুন
ব্যবসায়িক প্রয়োজন না থাকলে ডাইনামিক কোড লোডিং পরিহার করুন। যখনই সম্ভব, সমস্ত কার্যকারিতা সরাসরি অ্যাপ্লিকেশনের মধ্যেই অন্তর্ভুক্ত করা উচিত।
নির্ভরযোগ্য উৎস ব্যবহার করুন
যে কোড অ্যাপ্লিকেশনে লোড করা হবে, তা বিশ্বস্ত স্থানে সংরক্ষণ করা উচিত। লোকাল স্টোরেজের ক্ষেত্রে, অ্যাপ্লিকেশনের ইন্টারনাল স্টোরেজ অথবা স্কোপড স্টোরেজ (অ্যান্ড্রয়েড ১০ এবং তার পরবর্তী সংস্করণগুলোর জন্য) হলো প্রস্তাবিত স্থান। এই স্থানগুলোতে অন্যান্য অ্যাপ্লিকেশন এবং ব্যবহারকারীদের সরাসরি অ্যাক্সেস এড়ানোর জন্য ব্যবস্থা রয়েছে।
ইউআরএল (URL)-এর মতো দূরবর্তী স্থান থেকে কোড লোড করার সময়, সম্ভব হলে তৃতীয় পক্ষ ব্যবহার করা এড়িয়ে চলুন এবং নিরাপত্তার সর্বোত্তম অনুশীলন অনুসরণ করে কোডটি আপনার নিজস্ব পরিকাঠামোতে সংরক্ষণ করুন। যদি আপনার তৃতীয় পক্ষের কোড লোড করার প্রয়োজন হয়, তবে নিশ্চিত করুন যে প্রদানকারীটি বিশ্বস্ত।
অখণ্ডতা যাচাই করুন
কোডে কোনো রকম বিকৃতি ঘটানো হয়নি, তা নিশ্চিত করার জন্য ইন্টিগ্রিটি চেক করার পরামর্শ দেওয়া হয়। অ্যাপ্লিকেশনে কোড লোড করার আগে এই চেকগুলো করা উচিত।
রিমোট রিসোর্স লোড করার সময়, অ্যাক্সেস করা রিসোর্সগুলোর অখণ্ডতা যাচাই করার জন্য সাবরিসোর্স ইন্টিগ্রিটি ব্যবহার করা যেতে পারে।
এক্সটার্নাল স্টোরেজ থেকে রিসোর্স লোড করার সময়, ইন্টিগ্রিটি চেক ব্যবহার করে যাচাই করুন যে অন্য কোনো অ্যাপ্লিকেশন এই ডেটা বা কোডে হস্তক্ষেপ করেনি। ফাইলগুলোর হ্যাশ সুরক্ষিতভাবে, বিশেষত এনক্রিপ্ট করে এবং ইন্টারনাল স্টোরেজে সংরক্ষণ করা উচিত।
কোটলিন
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!")
}
}
}
জাভা
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!");
}
}
}
কোডটিতে স্বাক্ষর করুন
ডেটার অখণ্ডতা নিশ্চিত করার আরেকটি উপায় হলো, কোডটি লোড করার আগে সেটিতে স্বাক্ষর করা এবং তার স্বাক্ষর যাচাই করা। এই পদ্ধতির সুবিধা হলো, এটি শুধু মূল কোডটিই নয়, হ্যাশ কোডের অখণ্ডতাও নিশ্চিত করে, যা ডেটা বিকৃতি রোধে একটি অতিরিক্ত সুরক্ষা প্রদান করে।
যদিও কোড সাইনিং অতিরিক্ত নিরাপত্তা স্তর প্রদান করে, তবুও এটি মনে রাখা গুরুত্বপূর্ণ যে এটি একটি আরও জটিল প্রক্রিয়া, যা সফলভাবে বাস্তবায়নের জন্য অতিরিক্ত প্রচেষ্টা এবং সম্পদের প্রয়োজন হতে পারে।
কোড সাইনিং-এর কিছু উদাহরণ এই ডকুমেন্টের রিসোর্স বিভাগে পাওয়া যাবে।