OWASP বিভাগ: MASVS-স্টোরেজ: স্টোরেজ
ওভারভিউ
জিপ পাথ ট্রাভার্সাল দুর্বলতা, যা জিপস্লিপ নামেও পরিচিত, সংকুচিত আর্কাইভগুলি পরিচালনার সাথে সম্পর্কিত। এই পৃষ্ঠায়, আমরা একটি উদাহরণ হিসাবে ZIP বিন্যাস ব্যবহার করে এই দুর্বলতা প্রদর্শন করি, কিন্তু TAR, RAR, বা 7z এর মতো অন্যান্য বিন্যাস পরিচালনাকারী লাইব্রেরিতেও একই ধরনের সমস্যা দেখা দিতে পারে।
এই সমস্যার অন্তর্নিহিত কারণ হল জিপ আর্কাইভের ভিতরে, প্রতিটি প্যাক করা ফাইল একটি সম্পূর্ণ যোগ্য নামের সাথে সংরক্ষণ করা হয়, যা স্ল্যাশ এবং ডটগুলির মতো বিশেষ অক্ষরগুলির অনুমতি দেয়। java.util.zip
প্যাকেজ থেকে ডিফল্ট লাইব্রেরি ডিরেক্টরি ট্রাভার্সাল অক্ষরগুলির জন্য সংরক্ষণাগার এন্ট্রিগুলির নাম পরীক্ষা করে না ( ../
), তাই লক্ষ্যযুক্ত ডিরেক্টরি পাথের সাথে সংরক্ষণাগার থেকে বের করা নামটি সংযুক্ত করার সময় বিশেষ যত্ন নেওয়া উচিত .
বাহ্যিক উত্স থেকে যেকোনো জিপ-এক্সট্র্যাক্টিং কোড স্নিপেট বা লাইব্রেরি যাচাই করা খুবই গুরুত্বপূর্ণ। এই ধরনের অনেক লাইব্রেরি জিপ পাথ ট্রাভার্সালের জন্য ঝুঁকিপূর্ণ।
প্রভাব
জিপ পাথ ট্রাভার্সাল দুর্বলতা নির্বিচারে ফাইল ওভাররাইট অর্জন করতে ব্যবহার করা যেতে পারে। অবস্থার উপর নির্ভর করে, প্রভাব পরিবর্তিত হতে পারে, তবে অনেক ক্ষেত্রে এই দুর্বলতাটি কোড সম্পাদনের মতো বড় নিরাপত্তা সমস্যাগুলির দিকে নিয়ে যেতে পারে।
প্রশমন
এই সমস্যাটি প্রশমিত করার জন্য, প্রতিটি এন্ট্রি বের করার আগে, আপনার সর্বদা যাচাই করা উচিত যে লক্ষ্য পথটি গন্তব্য ডিরেক্টরির একটি শিশু। নীচের কোডটি অনুমান করে যে গন্তব্য ডিরেক্টরিটি নিরাপদ - শুধুমাত্র আপনার অ্যাপ দ্বারা লিখতে পারে এবং আক্রমণকারীর নিয়ন্ত্রণে নয় - অন্যথায় আপনার অ্যাপ সিমলিংক আক্রমণের মতো অন্যান্য দুর্বলতার ঝুঁকিতে পড়তে পারে৷
কোটলিন
companion object {
@Throws(IOException::class)
fun newFile(targetPath: File, zipEntry: ZipEntry): File {
val name: String = zipEntry.name
val f = File(targetPath, name)
val canonicalPath = f.canonicalPath
if (!canonicalPath.startsWith(
targetPath.canonicalPath + File.separator)) {
throw ZipException("Illegal name: $name")
}
return f
}
}
জাভা
public static File newFile(File targetPath, ZipEntry zipEntry) throws IOException {
String name = zipEntry.getName();
File f = new File(targetPath, name);
String canonicalPath = f.getCanonicalPath();
if (!canonicalPath.startsWith(targetPath.getCanonicalPath() + File.separator)) {
throw new ZipException("Illegal name: " + name);
}
return f;
}
দুর্ঘটনাক্রমে বিদ্যমান ফাইলগুলিকে ওভাররাইট করা এড়াতে, নিষ্কাশন প্রক্রিয়া শুরু করার আগে আপনাকে নিশ্চিত করতে হবে যে গন্তব্য ডিরেক্টরিটি খালি রয়েছে। অন্যথায় আপনি সম্ভাব্য অ্যাপ ক্র্যাশ বা চরম ক্ষেত্রে, একটি অ্যাপ্লিকেশন আপস ঝুঁকি.
কোটলিন
@Throws(IOException::class)
fun unzip(inputStream: InputStream?, destinationDir: File) {
if (!destinationDir.isDirectory) {
throw IOException("Destination is not a directory.")
}
val files = destinationDir.list()
if (files != null && files.isNotEmpty()) {
throw IOException("Destination directory is not empty.")
}
ZipInputStream(inputStream).use { zipInputStream ->
var zipEntry: ZipEntry
while (zipInputStream.nextEntry.also { zipEntry = it } != null) {
val targetFile = File(destinationDir, zipEntry.name)
// ...
}
}
}
জাভা
void unzip(final InputStream inputStream, File destinationDir)
throws IOException {
if(!destinationDir.isDirectory()) {
throw IOException("Destination is not a directory.");
}
String[] files = destinationDir.list();
if(files != null && files.length != 0) {
throw IOException("Destination directory is not empty.");
}
try (ZipInputStream zipInputStream = new ZipInputStream(inputStream)) {
ZipEntry zipEntry;
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
final File targetFile = new File(destinationDir, zipEntry);
…
}
}
}
সম্পদ
{% শব্দার্থে %}আপনার জন্য প্রস্তাবিত
- দ্রষ্টব্য: জাভাস্ক্রিপ্ট বন্ধ থাকলে লিঙ্ক টেক্সট প্রদর্শিত হয়
- পাথ ট্রাভার্সাল