簡體   English   中英

裝松 XAML 圖紙牢固

[英]loading loose XAML drawing securely

C# Windows 應用程序希望加載存儲在松散 XAML 文件中的矢量圖,而不允許任意代碼執行。

我已經從我可以控制的鏈接程序集中的資源中加載此類圖紙。 但是,我還想支持加載松散的 XAML 文件。 我想您可以使用 XAML 訪問控制來限制可以在此類 XAML 中實例化的對象? 理想情況下,我會將加載程序限制為僅實例化我們知道的文件中的繪圖圖元。 可以拒絕包含我們未列入白名單的新繪圖圖元的文件。

這是 API 已經支持的標准東西嗎? 因為我找不到。 否則,是否有人有示例或示例的開頭? 這是一個免費的開源項目,任何入門幫助都可能會大大減少我需要做的研究。

以下似乎在 XAML 負載中列出特定類型的白名單方面做得相當不錯:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Windows.Controls;
using System.Windows.Media;
using System.Xaml;
using System.Xml;

namespace TestXamlLoading
{
    internal class SchemaContext : XamlSchemaContext
    {
        // map from XAML element name to required namespace (currently always the same)
        private static readonly Dictionary<string, string> AllowedTypes = new Dictionary<string, string>();

        static SchemaContext()
        {
            // questionable: <Image> is used in some drawing XAML, should review it
            foreach (string name in new[]
            {
                "Canvas", "Compound", "Ellipse", "GradientStop", "GradientStopCollection", "Group", "Line",
                "LinearGradientBrush", "MatrixTransform", "Path", "PathGeometry", "Polygon",
                "RadialGradientBrush", "Rectangle", "RotateTransform", "ScaleTransform", "SkewTransform", "TextBlock",
                "TransformGroup", "TranslateTransform"
            })
            {
                AllowedTypes[name] = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
            }
        }

        public SchemaContext(IEnumerable<Assembly> referenceAssemblies, XamlSchemaContextSettings settings) : base(
            referenceAssemblies, settings)
        {
            // no code
        }

        protected override XamlType GetXamlType(string xamlNamespace, string name, params XamlType[] typeArguments)
        {
            if (!AllowedTypes.TryGetValue(name, out string requiredNamespace) || xamlNamespace != requiredNamespace)
            {
                throw new Exception($"disallowed instantiation of '{xamlNamespace}' '{name}' from XAML");
            }

            return base.GetXamlType(xamlNamespace, name, typeArguments);
        }
    }

    internal class Program
    {
        [STAThreadAttribute]
        private static void Main(string[] args)
        {
            bool shouldFail = TestLoad("..\\..\\..\\badfile.xaml");
            Debug.Assert(!shouldFail);
            bool shouldSucceed = TestLoad("..\\..\\..\\goodfile.xaml");
            Debug.Assert(shouldSucceed);
        }

        private static bool TestLoad(string path)
        {
            Stream inputStream = new FileStream(path, FileMode.Open);
            XmlReader xmlReader = new XmlTextReader(inputStream);
            Assembly[] referenceAssemblies =
            {
                // these are two separate assemblies which contain all the types we allow
                Assembly.GetAssembly(typeof(Canvas)),
                Assembly.GetAssembly(typeof(TransformGroup))
            };
            XamlSchemaContextSettings settings = new XamlSchemaContextSettings();
            XamlSchemaContext schemaContext = new SchemaContext(referenceAssemblies, settings);
            try
            {
                XamlReader reader = new XamlXmlReader(xmlReader, schemaContext);
                Canvas canvas = (Canvas) System.Windows.Markup.XamlReader.Load(reader);
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                return false;
            }

            return true;
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM