উত্তরাধিকার সুরক্ষা বিধি লঙ্ঘন না করে কীভাবে আমি নেট 4+ এ ইশিরাইজেবল কার্যকর করতে পারি?


109

পটভূমি: নোডা টাইমে অনেক সিরিয়ালাইজযোগ্য স্ট্রাক্ট রয়েছে। আমি বাইনারি সিরিয়ালাইজেশন অপছন্দ করার সময়, আমরা এটি সমর্থন করার জন্য অনেক অনুরোধ পেয়েছি, ফিরে 1.x টাইমলাইনে। আমরা ISerializableইন্টারফেস প্রয়োগ করে এটি সমর্থন ।

আমরা NET টাইম 2.x এর একটি নেট ইস্যু রিপোর্ট পেয়েছি । নেট ফিডল এর ​​মধ্যে ব্যর্থ । নোডা টাইম 1.x ব্যবহার করে একই কোডটি সূক্ষ্মভাবে কাজ করে। নিক্ষিপ্ত ব্যতিক্রমটি হ'ল:

সদস্যকে ওভাররাইড করার সময় উত্তরাধিকার সুরক্ষা বিধিগুলি লঙ্ঘন করা হয়েছে: 'নোডটাইম.ডায়রিশন.সিসটেম.রুনটাইম.সিরাইজেশন.আইরিয়াইজিবল.গেটঅবজেক্টডাটা (সিস্টেম.রুনটাইম.সিরাইজেশন.সরিয়ালাইজেশন ইনফো, সিস্টেম.রুনটাইম।সরিয়ালাইজেশন।স্ট্রিমিং কনটেক্সট)'। ওভাররাইডিং পদ্ধতির সুরক্ষার অ্যাক্সেসিবিলিটি ওভারড্রেন হওয়া পদ্ধতির সুরক্ষা অ্যাক্সেসিবিলিটির সাথে অবশ্যই মিলবে।

আমি এটিকে সংক্ষিপ্ত করে রেখেছি এমন ফ্রেমওয়ার্কটিতে: 1.x টার্গেটস। নেট 3.5 (ক্লায়েন্ট প্রোফাইল); 2.x লক্ষ্য। নেট 4.5। সাপোর্ট পিসিএল বনাম। নেট কোর এবং প্রকল্প ফাইল কাঠামোর ক্ষেত্রে তাদের বড় পার্থক্য রয়েছে, তবে দেখে মনে হচ্ছে এটি অপ্রাসঙ্গিক।

আমি এটি একটি স্থানীয় প্রকল্পে পুনরুত্পাদন করতে পরিচালিত করেছি, তবে আমি এর কোনও সমাধান পাইনি।

ভিএস2017 এ পুনরুত্পাদন করার পদক্ষেপ:

  • একটি নতুন সমাধান তৈরি করুন
  • একটি নতুন ক্লাসিক উইন্ডোজ কনসোল অ্যাপ্লিকেশন লক্ষ্যবস্তু তৈরি করুন। নেট 4.5.1। আমি এটিকে "কোডআরনার" বলেছি।
  • প্রকল্পের বৈশিষ্ট্যগুলিতে, স্বাক্ষর করতে যান এবং একটি নতুন কী দিয়ে অ্যাসেম্বলি সাইন করুন। পাসওয়ার্ডের প্রয়োজনীয়তাটি আনটিক করুন এবং কোনও ফাইলের নাম ব্যবহার করুন।
  • প্রতিস্থাপনের জন্য নিম্নলিখিত কোডটি আটকান Program.cs। এটি এই মাইক্রোসফ্ট নমুনায় কোডটির সংক্ষিপ্ত সংস্করণ । আমি সমস্ত পাথ একই করে রেখেছি, তাই আপনি যদি পুরো কোডটিতে ফিরে যেতে চান তবে আপনার আর কোনও পরিবর্তন করার দরকার নেই।

কোড:

using System;
using System.Security;
using System.Security.Permissions;

class Sandboxer : MarshalByRefObject  
{  
    static void Main()  
    {  
        var adSetup = new AppDomainSetup();  
        adSetup.ApplicationBase = System.IO.Path.GetFullPath(@"..\..\..\UntrustedCode\bin\Debug");  
        var permSet = new PermissionSet(PermissionState.None);  
        permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));  
        var fullTrustAssembly = typeof(Sandboxer).Assembly.Evidence.GetHostEvidence<System.Security.Policy.StrongName>();  
        var newDomain = AppDomain.CreateDomain("Sandbox", null, adSetup, permSet, fullTrustAssembly);  
        var handle = Activator.CreateInstanceFrom(  
            newDomain, typeof(Sandboxer).Assembly.ManifestModule.FullyQualifiedName,  
            typeof(Sandboxer).FullName  
            );  
        Sandboxer newDomainInstance = (Sandboxer) handle.Unwrap();  
        newDomainInstance.ExecuteUntrustedCode("UntrustedCode", "UntrustedCode.UntrustedClass", "IsFibonacci", new object[] { 45 });  
    }  

    public void ExecuteUntrustedCode(string assemblyName, string typeName, string entryPoint, Object[] parameters)  
    {  
        var target = System.Reflection.Assembly.Load(assemblyName).GetType(typeName).GetMethod(entryPoint);
        target.Invoke(null, parameters);
    }  
}
  • "আনট্রেসডকোড" নামে আরও একটি প্রকল্প তৈরি করুন। এটি একটি ক্লাসিক ডেস্কটপ ক্লাস লাইব্রেরি প্রকল্প হওয়া উচিত।
  • সমাবেশে স্বাক্ষর করুন; আপনি কোডরুনারের মতো একটি নতুন কী বা একই ব্যবহার করতে পারেন। (এটি আংশিকভাবে নোডা সময়ের পরিস্থিতি অনুকরণ করার জন্য এবং আংশিকভাবে কোড বিশ্লেষণকে সুখী রাখার জন্য))
  • নিম্নলিখিত কোডটি আটকে দিন Class1.cs(সেখানে কী রয়েছে তা মুছে ফেলা):

কোড:

using System;
using System.Runtime.Serialization;
using System.Security;
using System.Security.Permissions;

// [assembly: AllowPartiallyTrustedCallers]

namespace UntrustedCode
{
    public class UntrustedClass
    {
        // Method named oddly (given the content) in order to allow MSDN
        // sample to run unchanged.
        public static bool IsFibonacci(int number)
        {
            Console.WriteLine(new CustomStruct());
            return true;
        }
    }

    [Serializable]
    public struct CustomStruct : ISerializable
    {
        private CustomStruct(SerializationInfo info, StreamingContext context) { }

        //[SecuritySafeCritical]
        //[SecurityCritical]
        //[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {
            throw new NotImplementedException();
        }
    }
}

কোডআরনার প্রকল্প চালানো নিম্নলিখিত ব্যতিক্রম দেয় (পাঠযোগ্যতার জন্য পুনরায় ফর্ম্যাট করা):

আনহানডেল ব্যতিক্রম: সিস্টেম.রফলেশন.টারাজেট ইনভোকেশনএক্সেপশন: ব্যাতাকে একটি অনুরোধের
টার্গেট দ্বারা নিক্ষেপ করা হয়েছে।
--->
System.TypeLoadException:
সদস্যকে ওভাররাইড করার সময় উত্তরাধিকার সুরক্ষা বিধি লঙ্ঘন করা হয়েছে:
'অবিশ্বস্তকোড.কাস্টমস্ট্রাক্ট.সিস্টেম.রুনটাইম.সিরাইজেশন.আইরিয়ালাইজড.গেটঅবজেক্টডাটা (...)।
ওভাররাইডিং পদ্ধতির সুরক্ষার
অ্যাক্সেসিবিলিটি ওভারড্রেন হওয়া পদ্ধতির সুরক্ষা অ্যাক্সেসিবিলিটির সাথে অবশ্যই মিলবে ।

মন্তব্য করা আউট বৈশিষ্ট্যগুলি আমি চেষ্টা করেছি এমন জিনিসগুলি দেখায়:

  • SecurityPermissionদুটি পৃথক এমএস নিবন্ধ ( প্রথম , দ্বিতীয় ) দ্বারা সুপারিশ করা হয় , যদিও আকর্ষণীয়ভাবে তারা স্পষ্ট / অন্তর্নিহিত ইন্টারফেস প্রয়োগের চারপাশে বিভিন্ন জিনিস করে
  • SecurityCriticalনোডা টাইমের বর্তমানে যা আছে, এবং এই প্রশ্নের উত্তরটি সেটাই বোঝায়
  • SecuritySafeCritical কিছুটা কোড বিশ্লেষণ নিয়মের বার্তা দ্বারা প্রস্তাবিত by
  • কোনও বৈশিষ্ট্য ছাড়াই কোড বিশ্লেষণের নিয়মগুলি খুশি - উভয়ই SecurityPermissionবা SecurityCritical বর্তমানের সাথে, বিধিগুলি আপনাকে বৈশিষ্ট্যগুলি অপসারণ করতে বলে - যদি না থাকে তবে AllowPartiallyTrustedCallers। উভয় ক্ষেত্রেই পরামর্শগুলি অনুসরণ করা কোনও কাজে দেয় না।
  • নোডা টাইম এটি AllowPartiallyTrustedCallersপ্রয়োগ করেছে; এখানে উদাহরণটি প্রয়োগ করা গুণাবলির সাথে বা ছাড়া কাজ করে না।

একটি ব্যতিক্রম ছাড়া কোড চালায় তাহলে আমি যোগ [assembly: SecurityRules(SecurityRuleSet.Level1)]করতে UntrustedCodeসমাবেশ (এবং uncomment AllowPartiallyTrustedCallersঅ্যাট্রিবিউট), কিন্তু আমি বিশ্বাস করি যে যে অন্য কোড ব্যাহত পারে একটি দরিদ্র সমাধান।

.NET- এর সুরক্ষা দিকটি যখন আসে তখন আমি পুরোপুরি নষ্ট হয়ে যাওয়ার পুরোপুরি স্বীকার করি। সুতরাং আমি নেট নেট 4.5 কে লক্ষ্য করে কী করতে পারি এবং এখনও আমার প্রকারগুলি বাস্তবায়িত করার অনুমতি দেয় ISerializableএবং এখনও। নেট ফিডল যেমন পরিবেশে ব্যবহার করা যায়?

(আমি যখন নেট নেট ৪.৫ লক্ষ্য করছি, আমি বিশ্বাস করি এটি নেট নেট security.০ সুরক্ষা নীতি পরিবর্তনের ফলে সমস্যাটি দেখা দিয়েছে, তাই ট্যাগ tag)


মজার ব্যাপারটি যথেষ্ট, 4.0 তে সুরক্ষা মডেলের পরিবর্তনের এই ব্যাখ্যাটি বোঝায় যে কেবল অপসারণটি AllowPartiallyTrustedCallersকৌশলটি করা উচিত, তবে এটি কোনও পার্থক্য বলে মনে হচ্ছে না
ম্যাথিয়াস আর জেসেন

উত্তর:


56

এমএসডিএন অনুসারে , নেট নেট in.০ এ মূলত আপনার ISerializableআংশিক বিশ্বস্ত কোড ব্যবহার করা উচিত নয় এবং পরিবর্তে আপনার উচিত আইএসএফএফেরিয়ালাইজেশন ডেটা

Https://docs.microsoft.com/en-us/dotnet/standard/serialization/custom-seialization থেকে উদ্ধৃতি

গুরুত্বপূর্ণ

.NET ফ্রেমওয়ার্ক 4.0 এর পূর্ববর্তী সংস্করণগুলিতে, আংশিক বিশ্বস্ত সমাবেশে কাস্টম ব্যবহারকারীর ডেটা সিরিয়ালাইজেশন getObjectData ব্যবহার করে সম্পন্ন হয়েছিল। সংস্করণ ৪.০ দিয়ে শুরু করে, সেই পদ্ধতিটি সিকিউরিটিক্রিটিক্যালঅ্যাট্রিবিউট অ্যাট্রিবিউট দিয়ে চিহ্নিত করা হয়েছে যা আংশিকভাবে বিশ্বস্ত সমাবেশগুলিতে মৃত্যুদন্ড কার্যকর করে। এই শর্তটি নিয়ে কাজ করতে, ISafeSerializationData ইন্টারফেস প্রয়োগ করুন।

তাই আপনার প্রয়োজন হলে আপনি যা শুনতে চেয়েছিলেন সম্ভবত তা নয়, তবে আমি মনে করি না ব্যবহারের সময় এটির আশেপাশের কোনও উপায় নেই ISerializable( সুরক্ষায় ফিরে যাওয়া ব্যতীত Level1, যা আপনি বলেছিলেন যে আপনি চান না)।

পিএস: ISafeSerializationDataডক্সটি জানিয়েছে যে এটি কেবল ব্যাতিক্রমের জন্য, তবে এটি সমস্ত নির্দিষ্ট বলে মনে হচ্ছে না, আপনি এটি একটি শট দিতে চাইতে পারেন ... আমি মূলত এটি আপনার নমুনা কোড দিয়ে পরীক্ষা করতে পারি না ( ISerializableকাজগুলি মুছে ফেলা ব্যতীত , তবে আপনি এটি ইতিমধ্যে জানতেন) ... ISafeSerializationDataআপনার যথেষ্ট পরিমাণে স্যুট আছে কিনা তা আপনাকে দেখতে হবে।

পিএস 2: অ্যাসিবিউটটিSecurityCritical কাজ করে না কারণ যখন অ্যাসেম্বলি আংশিক বিশ্বাস মোডে ( স্তর 2 সুরক্ষা ) লোড করা হয় তখন তা উপেক্ষা করা হয় । আপনি এটা আপনার নমুনা কোডের উপর দেখতে পারেন, যদি আপনি ডিবাগ targetমধ্যে পরিবর্তনশীল ExecuteUntrustedCodeএটা invoking সামনে ঠিক আছে, এটা থাকবে IsSecurityTransparentকরার trueএবং IsSecurityCriticalকরতে falseএমনকি যদি আপনার সাথে পদ্ধতি চিহ্নিত SecurityCriticalঅনুষঙ্গ)


আহা - ব্যাখ্যার জন্য ধন্যবাদ। লজ্জা ব্যতিক্রম এখানে এত বিভ্রান্তিকর। কী করা দরকার তা নিয়ে কাজ করা দরকার ...
জন স্কিটি

@ জোনস্কিট সত্যি বলতে, আমি বাইনারি সিরিয়ালাইজেশন পুরোপুরি খাই ... তবে আমি বুঝতে পারি যে আপনার ইউজারবেস এটি পছন্দ করতে পারে না
জেএলসি

আমি মনে করি আমাদের এটি করতে হবে - যার অর্থ v3.0 এ চলেছে। যদিও এর অন্যান্য সুবিধাগুলি রয়েছে ... আমার নোদা টাইম সম্প্রদায়ের সাথে পরামর্শ করা দরকার।
জন স্কিটে

12
@ জোনস্কিট বিটিডব্লিউ, আপনি যদি আগ্রহী হন তবে এই নিবন্ধটি স্তর 1 এবং স্তর 2 সুরক্ষার (এবং কেন এটি কাজ করে না) মধ্যে পার্থক্য ব্যাখ্যা করে
জেএলসি

8

গৃহীত উত্তরটি এতটাই দৃ .়প্রত্যয়ী যে আমি প্রায় বিশ্বাস করি এটি কোনও ত্রুটি নয়। তবে এখন কিছু পরীক্ষা-নিরীক্ষা করার পরে আমি বলতে পারি যে লেভেল 2 সুরক্ষা সম্পূর্ণ গণ্ডগোল; কমপক্ষে, কিছু সত্যই মাছধরা।

কয়েক দিন আগে আমি আমার লাইব্রেরিগুলিতে একই সমস্যাটিতে ঝাঁপিয়ে পড়েছি। আমি দ্রুত ইউনিট পরীক্ষা তৈরি করেছি; যাইহোক,। নেট ফিডল আমি যে সমস্যার মুখোমুখি হয়েছি তা পুনরুত্পাদন করতে পারিনি, যখন খুব একই কোডটি "সাফল্যের সাথে" একটি কনসোল অ্যাপ্লিকেশনটিতে ব্যতিক্রম ছুঁড়ে দিয়েছে। শেষ পর্যন্ত আমি সমস্যাটি কাটিয়ে উঠতে দুটি অদ্ভুত উপায় খুঁজে পেয়েছি।

টিএল; ডিআর : দেখা গেছে যে আপনি যদি আপনার গ্রাহক প্রকল্পে ব্যবহৃত লাইব্রেরির অভ্যন্তরীণ ধরণের ব্যবহার করেন তবে আংশিক বিশ্বস্ত কোড প্রত্যাশার মতো কাজ করে: এটি একটি ISerializableবাস্তবায়ন ইনস্ট্যান্টিয়েট করতে সক্ষম হয় (এবং একটি সুরক্ষা সমালোচনামূলক কোড সরাসরি কল করা যায় না, তবে নীচে দেখুন)। বা, যা আরও হাস্যকর, আপনি যদি প্রথমবারের মতো কাজ না করে তবে স্যান্ডবক্সটি আবার তৈরি করার চেষ্টা করতে পারেন ...

তবে আসুন কিছু কোড দেখুন।

ClassLibrary.dll:

আসুন দুটি কেস পৃথক করা যাক: একটি সুরক্ষা সমালোচনামূলক বিষয়বস্তু সহ একটি নিয়মিত শ্রেণীর জন্য এবং একটি ISerializableবাস্তবায়ন:

public class CriticalClass
{
    public void SafeCode() { }

    [SecurityCritical]
    public void CriticalCode() { }

    [SecuritySafeCritical]
    public void SafeEntryForCriticalCode() => CriticalCode();
}

[Serializable]
public class SerializableCriticalClass : CriticalClass, ISerializable
{
    public SerializableCriticalClass() { }

    private SerializableCriticalClass(SerializationInfo info, StreamingContext context) { }

    [SecurityCritical]
    public void GetObjectData(SerializationInfo info, StreamingContext context) { }
}

ইস্যুটি কাটিয়ে উঠার একটি উপায় হ'ল গ্রাহক সমাবেশ থেকে একটি অভ্যন্তরীণ প্রকার ব্যবহার করা। যে কোনও প্রকার এটি করবে; এখন আমি একটি বৈশিষ্ট্য সংজ্ঞা:

[AttributeUsage(AttributeTargets.All)]
internal class InternalTypeReferenceAttribute : Attribute
{
    public InternalTypeReferenceAttribute() { }
}

এবং সমাবেশে প্রাসঙ্গিক বৈশিষ্ট্য প্রয়োগ করা হয়েছে:

[assembly: InternalsVisibleTo("UnitTest, PublicKey=<your public key>")]
[assembly: AllowPartiallyTrustedCallers]
[assembly: SecurityRules(SecurityRuleSet.Level2, SkipVerificationInFullTrust = true)]

সমাবেশে স্বাক্ষর করুন, InternalsVisibleToবৈশিষ্ট্যের কীটি প্রয়োগ করুন এবং পরীক্ষার প্রকল্পের জন্য প্রস্তুত করুন:

ইউনিটটেষ্ট.ডিল (নুনিট এবং ক্লাসলিবারি ব্যবহার করে):

অভ্যন্তরীণ কৌশলটি ব্যবহার করার জন্য পরীক্ষার সমাবেশটিও স্বাক্ষর করা উচিত। সমাবেশ বৈশিষ্ট্য:

// Just to make the tests security transparent by default. This helps to test the full trust behavior.
[assembly: AllowPartiallyTrustedCallers] 

// !!! Comment this line out and the partial trust test cases may fail for the fist time !!!
[assembly: InternalTypeReference]

দ্রষ্টব্য : বৈশিষ্ট্যটি যে কোনও জায়গায় প্রয়োগ করা যেতে পারে। আমার ক্ষেত্রে এটি একটি এলোমেলো পরীক্ষার ক্লাসের পদ্ধতিতে আমাকে খুঁজে পেতে কয়েক দিন সময় নিয়েছিল।

দ্রষ্টব্য 2 : আপনি যদি সমস্ত পরীক্ষার পদ্ধতি এক সাথে চালান তবে এটি ঘটতে পারে যে পরীক্ষাগুলি পাস হবে।

পরীক্ষার শ্রেণীর কঙ্কাল:

[TestFixture]
public class SecurityCriticalAccessTest
{
    private partial class Sandbox : MarshalByRefObject
    {
    }

    private static AppDomain CreateSandboxDomain(params IPermission[] permissions)
    {
        var evidence = new Evidence(AppDomain.CurrentDomain.Evidence);
        var permissionSet = GetPermissionSet(permissions);
        var setup = new AppDomainSetup
        {
            ApplicationBase = AppDomain.CurrentDomain.BaseDirectory,
        };

        var assemblies = AppDomain.CurrentDomain.GetAssemblies();
        var strongNames = new List<StrongName>();
        foreach (Assembly asm in assemblies)
        {
            AssemblyName asmName = asm.GetName();
            strongNames.Add(new StrongName(new StrongNamePublicKeyBlob(asmName.GetPublicKey()), asmName.Name, asmName.Version));
        }

        return AppDomain.CreateDomain("SandboxDomain", evidence, setup, permissionSet, strongNames.ToArray());
    }

    private static PermissionSet GetPermissionSet(IPermission[] permissions)
    {
        var evidence = new Evidence();
        evidence.AddHostEvidence(new Zone(SecurityZone.Internet));
        var result = SecurityManager.GetStandardSandbox(evidence);
        foreach (var permission in permissions)
            result.AddPermission(permission);
        return result;
    }
}

এবং আসুন একে একে পরীক্ষার কেসগুলি দেখুন

কেস 1: ইস্রায়েলিজেবল বাস্তবায়ন

প্রশ্নে একই সমস্যা। পরীক্ষা পাস হলে

  • InternalTypeReferenceAttribute প্রয়োগ করা হয়
  • স্যান্ডবক্স একাধিকবার তৈরি করার চেষ্টা করা হয়েছে (কোড দেখুন)
  • বা, যদি সমস্ত পরীক্ষার মামলা একবারে কার্যকর করা হয় এবং এটি প্রথমটি নয়

অন্যথায়, Inheritance security rules violated while overriding member...আপনি তাত্ক্ষণিকভাবে ব্যবহার করার সময় সম্পূর্ণ অনুপযুক্ত ব্যতিক্রম আসে SerializableCriticalClass

[Test]
[SecuritySafeCritical] // for Activator.CreateInstance
public void SerializableCriticalClass_PartialTrustAccess()
{
    var domain = CreateSandboxDomain(
        new SecurityPermission(SecurityPermissionFlag.SerializationFormatter), // BinaryFormatter
        new ReflectionPermission(ReflectionPermissionFlag.MemberAccess)); // Assert.IsFalse
    var handle = Activator.CreateInstance(domain, Assembly.GetExecutingAssembly().FullName, typeof(Sandbox).FullName);
    var sandbox = (Sandbox)handle.Unwrap();
    try
    {
        sandbox.TestSerializableCriticalClass();
        return;
    }
    catch (Exception e)
    {
        // without [InternalTypeReference] it may fail for the first time
        Console.WriteLine($"1st try failed: {e.Message}");
    }

    domain = CreateSandboxDomain(
        new SecurityPermission(SecurityPermissionFlag.SerializationFormatter), // BinaryFormatter
        new ReflectionPermission(ReflectionPermissionFlag.MemberAccess)); // Assert.IsFalse
    handle = Activator.CreateInstance(domain, Assembly.GetExecutingAssembly().FullName, typeof(Sandbox).FullName);
    sandbox = (Sandbox)handle.Unwrap();
    sandbox.TestSerializableCriticalClass();

    Assert.Inconclusive("Meh... succeeded only for the 2nd try");
}

private partial class Sandbox
{
    public void TestSerializableCriticalClass()
    {
        Assert.IsFalse(AppDomain.CurrentDomain.IsFullyTrusted);

        // ISerializable implementer can be created.
        // !!! May fail for the first try if the test does not use any internal type of the library. !!!
        var critical = new SerializableCriticalClass();

        // Critical method can be called via a safe method
        critical.SafeEntryForCriticalCode();

        // Critical method cannot be called directly by a transparent method
        Assert.Throws<MethodAccessException>(() => critical.CriticalCode());
        Assert.Throws<MethodAccessException>(() => critical.GetObjectData(null, new StreamingContext()));

        // BinaryFormatter calls the critical method via a safe route (SerializationFormatter permission is required, though)
        new BinaryFormatter().Serialize(new MemoryStream(), critical);
    }

}

কেস ২: সুরক্ষা সমালোচনামূলক সদস্যদের নিয়ে নিয়মিত ক্লাস

পরীক্ষাটি প্রথমটির মতো একই শর্তে পাস করে। তবে বিষয়টি এখানে সম্পূর্ণ আলাদা: আংশিক বিশ্বস্ত কোডটি কোনও সুরক্ষা সমালোচনামূলক সদস্যকে সরাসরি অ্যাক্সেস করতে পারে

[Test]
[SecuritySafeCritical] // for Activator.CreateInstance
public void CriticalClass_PartialTrustAccess()
{
    var domain = CreateSandboxDomain(
        new ReflectionPermission(ReflectionPermissionFlag.MemberAccess), // Assert.IsFalse
        new EnvironmentPermission(PermissionState.Unrestricted)); // Assert.Throws (if fails)
    var handle = Activator.CreateInstance(domain, Assembly.GetExecutingAssembly().FullName, typeof(Sandbox).FullName);
    var sandbox = (Sandbox)handle.Unwrap();
    try
    {
        sandbox.TestCriticalClass();
        return;
    }
    catch (Exception e)
    {
        // without [InternalTypeReference] it may fail for the first time
        Console.WriteLine($"1st try failed: {e.Message}");
    }

    domain = CreateSandboxDomain(
        new ReflectionPermission(ReflectionPermissionFlag.MemberAccess)); // Assert.IsFalse
    handle = Activator.CreateInstance(domain, Assembly.GetExecutingAssembly().FullName, typeof(Sandbox).FullName);
    sandbox = (Sandbox)handle.Unwrap();
    sandbox.TestCriticalClass();

    Assert.Inconclusive("Meh... succeeded only for the 2nd try");
}

private partial class Sandbox
{
    public void TestCriticalClass()
    {
        Assert.IsFalse(AppDomain.CurrentDomain.IsFullyTrusted);

        // A type containing critical methods can be created
        var critical = new CriticalClass();

        // Critical method can be called via a safe method
        critical.SafeEntryForCriticalCode();

        // Critical method cannot be called directly by a transparent method
        // !!! May fail for the first time if the test does not use any internal type of the library. !!!
        // !!! Meaning, a partially trusted code has more right than a fully trusted one and is       !!!
        // !!! able to call security critical method directly.                                        !!!
        Assert.Throws<MethodAccessException>(() => critical.CriticalCode());
    }
}

কেস ২-৩: কেস 1-2 এর সম্পূর্ণ বিশ্বাস সংস্করণ

সম্পূর্ণতার জন্য এখানে সম্পূর্ণরূপে বিশ্বস্ত ডোমেনে মৃত্যুদন্ড কার্যকর করা একই ক্ষেত্রে রয়েছে। যদি আপনি [assembly: AllowPartiallyTrustedCallers]পরীক্ষাগুলি ব্যর্থ করে দেন তবে আপনি সরাসরি সমালোচনামূলক কোড অ্যাক্সেস করতে পারেন (কারণ পদ্ধতিগুলি ডিফল্টরূপে স্বচ্ছ নয়)।

[Test]
public void CriticalClass_FullTrustAccess()
{
    Assert.IsTrue(AppDomain.CurrentDomain.IsFullyTrusted);

    // A type containing critical methods can be created
    var critical = new CriticalClass();

    // Critical method cannot be called directly by a transparent method
    Assert.Throws<MethodAccessException>(() => critical.CriticalCode());

    // Critical method can be called via a safe method
    critical.SafeEntryForCriticalCode();
}

[Test]
public void SerializableCriticalClass_FullTrustAccess()
{
    Assert.IsTrue(AppDomain.CurrentDomain.IsFullyTrusted);

    // ISerializable implementer can be created
    var critical = new SerializableCriticalClass();

    // Critical method cannot be called directly by a transparent method (see also AllowPartiallyTrustedCallersAttribute)
    Assert.Throws<MethodAccessException>(() => critical.CriticalCode());
    Assert.Throws<MethodAccessException>(() => critical.GetObjectData(null, default(StreamingContext)));

    // Critical method can be called via a safe method
    critical.SafeEntryForCriticalCode();

    // BinaryFormatter calls the critical method via a safe route
    new BinaryFormatter().Serialize(new MemoryStream(), critical);
}

উপসংহার:

অবশ্যই এটি নেট সমস্যা নিয়ে আপনার সমস্যার সমাধান করবে না। তবে এখন আমি খুব অবাক হব যদি এটি কাঠামোর কোনও বাগ না হয়।

আমার কাছে এখন সবচেয়ে বড় প্রশ্ন হ'ল গৃহীত উত্তরের উদ্ধৃত অংশ। কীভাবে তারা এই আজেবাজে কথাটি এলো? ISafeSerializationDataপরিষ্কারভাবে কিছু জন্য একটি সমাধান নয়: এটা একচেটিয়াভাবে বেস দ্বারা ব্যবহৃত হয় Exceptionবর্গ এবং যদি আপনি সাবস্ক্রাইব SerializeObjectStateইভেন্টটি (কেন যে একটি overridable পদ্ধতি নয়?), তারপর রাষ্ট্র এছাড়াও খায় করা হবে না Exception.GetObjectDataশেষ।

AllowPartiallyTrustedCallers/ SecurityCritical/ SecuritySafeCriticalগুণাবলীর তিন ব্যক্তির সমন্বয় ঠিক ব্যবহার উপরে দেখানো জন্য ডিজাইন করা হয়েছে। এটি আমার কাছে মোটামুটি বোকা বলে মনে হচ্ছে যে আংশিক বিশ্বস্ত কোড তার সুরক্ষা সমালোচনামূলক সদস্যদের ব্যবহারের চেষ্টা নির্বিশেষে কোনও প্রকারকে ইনস্ট্যান্ট করতে পারে না। তবে এটি একটি আরও বড় বাজে কথা ( আসলে একটি সুরক্ষা গর্ত ) যে আংশিক বিশ্বস্ত কোডটি কোনও সুরক্ষা সমালোচনা পদ্ধতিতে সরাসরি অ্যাক্সেস করতে পারে ( কেস ২ দেখুন ) যদিও এটি সম্পূর্ণ বিশ্বস্ত ডোমেন থেকেও স্বচ্ছ পদ্ধতির জন্য নিষিদ্ধ।

সুতরাং যদি আপনার গ্রাহক প্রকল্পটি একটি পরীক্ষা বা অন্য কোনও সুপরিচিত সমাবেশ হয় তবে অভ্যন্তরীণ কৌশলটি সঠিকভাবে ব্যবহার করা যেতে পারে। নেট নেট এবং অন্যান্য বাস্তব-জীবনের স্যান্ডবক্সযুক্ত পরিবেশগুলির জন্য SecurityRuleSet.Level1মাইক্রোসফ্ট দ্বারা এটি স্থির না হওয়া পর্যন্ত একমাত্র সমাধানটি আবার ফিরে আসবে ।


আপডেট: ইস্যুটির জন্য একটি বিকাশকারী সম্প্রদায়ের টিকিট তৈরি করা হয়েছে।


2

এমএসডিএন অনুসারে দেখুন:

লঙ্ঘন কীভাবে ঠিক করবেন?

এই নিয়ম লঙ্ঘন সমাধানের জন্য, করতে GetObjectData পদ্ধতি দৃশ্যমান এবং overridable এবং নিশ্চিত সব দৃষ্টান্ত ক্ষেত্র ধারাবাহিকতাতে প্রক্রিয়ায় অন্তর্ভুক্ত বা স্পষ্টভাবে চিহ্নিত করা হয় NonSerializedAttribute অ্যাট্রিবিউট।

নীচের উদাহরণটি দুটি পুঙ্খানুপুঙ্খ লঙ্ঘন সংশোধন করে বুক ক্লাসে আইএসরিজিয়েবল.গেটঅবজেক্টডাটার একটি ওভাররাইডযোগ্য বাস্তবায়ন সরবরাহ করে এবং লাইব্রেরি ক্লাসে ইস্রাইরিজেবল.গেটঅবজেক্ট ডেটা প্রয়োগ করে।

using System;
using System.Security.Permissions;
using System.Runtime.Serialization;

namespace Samples2
{
    [Serializable]
    public class Book : ISerializable
    {
        private readonly string _Title;

        public Book(string title)
        {
            if (title == null)
                throw new ArgumentNullException("title");

            _Title = title;
        }

        protected Book(SerializationInfo info, StreamingContext context)
        {
            if (info == null)
                throw new ArgumentNullException("info");

            _Title = info.GetString("Title");
        }

        public string Title
        {
            get { return _Title; }
        }

        [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
        protected virtual void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("Title", _Title);
        }

        [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {
            if (info == null)
                throw new ArgumentNullException("info");

            GetObjectData(info, context);
        }
    }

    [Serializable]
    public class LibraryBook : Book
    {
        private readonly DateTime _CheckedOut;

        public LibraryBook(string title, DateTime checkedOut)
            : base(title)
        {
            _CheckedOut = checkedOut;
        }

        protected LibraryBook(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
            _CheckedOut = info.GetDateTime("CheckedOut");
        }

        public DateTime CheckedOut
        {
            get { return _CheckedOut; }
        }

        [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
        protected override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            base.GetObjectData(info, context);

            info.AddValue("CheckedOut", _CheckedOut);
        }
    }
}

2
আপনি যে নিবন্ধটি লিঙ্ক করেছেন সেটি CA2240 এর জন্য, যা বরখাস্ত নয় - কোড এটি লঙ্ঘন করে না। এটি স্ট্রাক্ট, সুতরাং এটি কার্যকরভাবে সিল করা হয়েছে; এটির কোন ক্ষেত্র নেই; এটি GetObjectDataসুস্পষ্টভাবে প্রয়োগ করে , তবে স্পষ্টভাবে এটি করা কোনও উপকারে আসে না।
জন স্কিটি

15
অবশ্যই, এবং চেষ্টা করার জন্য ধন্যবাদ - তবে আমি কেন এটি কার্যকর হয় না তা ব্যাখ্যা করছি । (এবং একটি সুপারিশ হিসাবে - কিছু এই, যেখানে প্রশ্নটি যাচাইযোগ্য উদাহরণ অন্তর্ভুক্ত মত চতুর জন্য, এটি একটি ভাল ধারণা প্রস্তাব নির্ধারণ প্রয়োগের এবং কিনা এটা চেষ্টা করার আসলে সাহায্য করে।)
জন স্কিট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.