تبدیل نا امن بایت ها(Insecure Deserialization): تفاوت بین نسخهها
از Secure Coding
(یک نسخهٔ میانیِ همین کاربر نمایش داده نشده است) | |||
سطر ۳۷۲: | سطر ۳۷۲: | ||
</div> | </div> | ||
− | از | + | === توابع php === |
+ | |||
+ | از توابعی می تواند در بروز این آسیب پذیری موثر باشد می توان به | ||
+ | |||
+ | * unserialize | ||
+ | * json_decode | ||
+ | |||
+ | اشاره نمود. | ||
[[category:تبدیل ناامن بایت ها(Deserialization Insecure)]] | [[category:تبدیل ناامن بایت ها(Deserialization Insecure)]] |
نسخهٔ کنونی تا ۳۰ مارس ۲۰۲۰، ساعت ۱۰:۵۶
گاهی لازم است برای انتقال برخی داده ها مانند object ها ابتدا اطلاعات را serialize کنید.
به این صورت که داده مورد نظر را به شکل مشخصی قرار می دهیم(serialization) و پس از نتقال آن را به شکل اولیه تبدیل می کنیم(deserialization).
برای مثال در تصویر بالا اطلاعات کاربری شامل username و role و ... ابتدا serialize و انتقال می دهیم و پس از انتقال آن را deserialize می کنیم.
آسیب پذیری insecure deserialization هنگام deserialize شدن داده رخ می دهد و باعث بروز آسیب پذیری های دیگر مانند آسیب پذیری اجرای کد از راه دور می شود.
محتویات
]روش های جلوگیری[ویرایش]
روش های جلوگیری در PHP[ویرایش]
مثال 1)
<?php class foo { public $file = "test.txt"; public $data = "text"; function __destruct(){ file_put_contents($this->file, $this->data); } } $file_name = $_GET['session_filename']; print "Readfile ".$file_name."<br>"; if(!file_exist($file_name)) { print "No file\n"; } else{ unserialize(file_get_contents($file_name)); }
روش 1)
<?php class foo { public $file = "test.txt"; public $data = "text"; function __destruct(){ file_put_contents($this->file, $this->data); } } $file_name = $_GET['session_filename']; $allowedvalues = array("allow_value_1", "allow_value_2", "allow_value_3"); if(!in_array($file_name, $allowedvalues)){ die("Such a value is not allowed."); } print "Readfile ".$file_name."<br>"; if(!file_exist($file_name)) { print "No file\n"; } else{ unserialize(file_get_contents($file_name)); } ?>
روش های جلوگیری در ASP.NET[ویرایش]
مثال 1)
public void Serialize(SerializationProductModel pro, String filename) { System.IO.Stream ms = File.OpenWrite(filename); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(ms, pro); ms.Flush(); ms.Close(); ms.Dispose(); } public SerializationProductModel Deserialize(String filename) { BinaryFormatter formatter = new BinaryFormatter(); FileStream fs = File.Open(filename, FileMode.Open); SerializationProductModel obj = (SerializationProductModel) formatter.Deserialize(fs); fs.Flush(); fs.Close(); fs.Dispose(); return obj; }
مثال 2)
using System.Web.Script.Serialization; public class ExampleClass { public T Deserialize<T>(string str) { JavaScriptSerializer s = new JavaScriptSerializer(new SimpleTypeResolver()); return s.Deserialize<T>(str); } }
روش 1)
public class DemoDeserializationBinder: SerializationBinder { public override Type BindToType(string assemblyName, string typeName) { List < Tuple < string, Type >> allowedTypes = new List < Tuple < string, Type >> (); allowedTypes.Add(new Tuple < string, Type > ("RestAPIService.Models.SerializationProductModel", typeof(SerializationProductModel))); foreach(Tuple < string, Type > typeTuple in allowedTypes) { if (typeName == typeTuple.Item1) { return typeTuple.Item2; } } throw new ArgumentOutOfRangeException("Disallowed type"); } } public SerializationProductModel Secure_Deserialize(String filename) { //Format the object as Binary //add Binder BinaryFormatter formatter = new BinaryFormatter { Binder = new DemoDeserializationBinder() }; //Reading the file from the server FileStream fs = File.Open(filename, FileMode.Open); SerializationProductModel obj = (SerializationProductModel) formatter.Deserialize(fs); //SerializationProductModel pro = (SerializationProductModel)obj; fs.Flush(); fs.Close(); fs.Dispose(); return obj; }
روش 2)
using System.Web.Script.Serialization; public class ExampleClass { public T Deserialize<T>(string str) { JavaScriptSerializer s = new JavaScriptSerializer(); return s.Deserialize<T>(str); } }
روش های جلوگیری در JAVA[ویرایش]
مثال 1)
class Utils { // Function to serialize an object and write it to a file public static void SerializeToFile(Object obj, String filename) { try { FileOutputStream file = new FileOutputStream(filename); ObjectOutputStream out = new ObjectOutputStream(file); // Serialization of the object to file System.out.println("Serializing " + obj.toString() + " to " + filename); out.writeObject(obj); out.close(); file.close(); } catch(Exception e) { System.out.println("Exception: " + e.toString()); } } // Function to deserialize an object from a file public static Object DeserializeFromFile(String filename) { Object obj = new Object(); try { FileInputStream file = new FileInputStream(filename); ObjectInputStream in = new ObjectInputStream(file); // Deserialization of the object to file System.out.println("Deserializing from " + filename); obj = in.readObject(); in.close(); file.close(); } catch(Exception e) { System.out.println("Exception: " + e.toString()); } return obj; } }
روش 1)
package com.suducode.safe.deserialization; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectStreamClass; import java.util.List; /** * This class helps with safely de serializing an object from a stream avoiding the known * vulnerability in native java de serialization. * * @param <T> De-serialized object will be cast to this type. * @author Sudharshan Krishnamurthy * @version 1.0 */ public class SafeDeserializer<T> { private long length = 0; private long maxBytes = 0; private long maxObjects = 0; private InputStream inputStream; private List<Class<?>> safeClasses; /** * A de-serializer to replace the unsafe ObjectInputStream.readObject() method built into Java. This method * checks to be sure the classes referenced are safe, the number of objects is limited to something sane, * and the number of bytes is limited to a reasonable number. The returned Object is also cast to the * specified type. * * @param safeClasses List of Classes allowed in serialized object being read. * @param maxObjects long representing the maximum number of objects allowed inside the serialized * object being read. * @param maxBytes long representing the maximum number of bytes allowed to be read from the InputStream. * @param inputStream InputStream containing an untrusted serialized object. * @return Object read from the stream. (cast to the Class of the type parameter) * @throws IOException might be thrown while reading fom the stream. * @throws ClassNotFoundException might be thrown while casting the deserialized object. */ public SafeDeserializer(List<Class<?>> safeClasses, long maxObjects, long maxBytes, InputStream inputStream) { this.safeClasses = safeClasses; this.maxBytes = maxBytes; this.maxObjects = maxObjects; this.inputStream = inputStream; } public T safelyReadObject() throws IOException, ClassNotFoundException { // create an input stream limited to a certain number of bytes InputStream lis = new SecureFilterInputStream(inputStream); // create an object input stream that checks classes and limits the number of objects to read ObjectInputStream ois = new SecureObjectInputStream(lis); // use the protected ObjectInputStream to read object safely and cast to T return (T) ois.readObject(); } /** * Filter Input stream override to enforce some security rules. */ private class SecureFilterInputStream extends FilterInputStream { protected SecureFilterInputStream(InputStream in) { super(in); } @Override public int read() throws IOException { int val = super.read(); if (val != -1) { length++; checkLength(); } return val; } @Override public int read(byte[] bytes, int off, int len) throws IOException { int val = super.read(bytes, off, len); if (val > 0) { length += val; checkLength(); } return val; } private void checkLength() throws IOException { if (length > maxBytes) { throw new SecurityException("Security violation: attempt to deserialize too many bytes" + " from stream. Limit is " + maxBytes); } } } /** * Object Input stream override to enforce some security rules. */ private class SecureObjectInputStream extends ObjectInputStream { private int objCount = 0; boolean status = enableResolveObject(true); protected SecureObjectInputStream(InputStream filteredInputStream) throws IOException { super(filteredInputStream); } @Override protected Object resolveObject(Object obj) throws IOException { if (objCount++ > maxObjects) { throw new SecurityException("Security violation: attempt to deserialize too many objects" + " from stream. Limit is " + maxObjects); } return super.resolveObject(obj); } @Override protected Class<?> resolveClass(ObjectStreamClass osc) throws IOException, ClassNotFoundException { Class<?> clazz = super.resolveClass(osc); if (clazz.isArray() || clazz.equals(String.class) || Number.class.isAssignableFrom(clazz) || safeClasses.contains(clazz)) { return clazz; } throw new SecurityException("Security violation: attempt to deserialize unauthorized " + clazz); } } }
توابع php[ویرایش]
از توابعی می تواند در بروز این آسیب پذیری موثر باشد می توان به
- unserialize
- json_decode
اشاره نمود.