Пример #1
0
        internal AttributeWrapper(GumboAttribute attribute, ElementWrapper parent, int index,
            Action<string, ElementWrapper> addElementWithId)
        {
            if (parent == null)
            {
                throw new ArgumentNullException("parent");
            }

            if (addElementWithId == null)
            {
                throw new ArgumentNullException("addElementWithId");
            }

            Parent = parent;
            Index = index;
            Name = NativeUtf8Helper.StringFromNativeUtf8(attribute.name);
            Value = NativeUtf8Helper.StringFromNativeUtf8(attribute.value);
            OriginalName = NativeUtf8Helper.StringFromNativeUtf8(attribute.original_name.data, (int)attribute.original_name.length);
            OriginalValue = NativeUtf8Helper.StringFromNativeUtf8(attribute.original_value.data, (int)attribute.original_value.length);
            NameStart = attribute.name_start;
            NameEnd = attribute.name_end;
            ValueStart = attribute.value_start;
            ValueEnd = attribute.value_end;
            Namespace = attribute.attr_namespace;

            if (String.Equals(this.Name, "id", StringComparison.OrdinalIgnoreCase))
            {
                addElementWithId(this.Value, parent);
            }
        }
Пример #2
0
        internal AttributeWrapper(GumboAttribute attribute, ElementWrapper parent)
        {
            if (parent == null)
            {
                throw new ArgumentNullException(nameof(parent));
            }

            Parent        = parent;
            Name          = NativeUtf8Helper.StringFromNativeUtf8(attribute.name);
            Value         = NativeUtf8Helper.StringFromNativeUtf8(attribute.value);
            OriginalName  = NativeUtf8Helper.StringFromNativeUtf8(attribute.original_name.data, (int)attribute.original_name.length);
            OriginalValue = NativeUtf8Helper.StringFromNativeUtf8(attribute.original_value.data, (int)attribute.original_value.length);
            NameStart     = attribute.name_start;
            NameEnd       = attribute.name_end;
            ValueStart    = attribute.value_start;
            ValueEnd      = attribute.value_end;
            Namespace     = attribute.attr_namespace;
        }
Пример #3
0
        internal AttributeWrapper(GumboAttribute attribute, ElementWrapper parent)
        {
            if (parent == null)
            {
                throw new ArgumentNullException(nameof(parent));
            }

            Parent = parent;
            Name = NativeUtf8Helper.StringFromNativeUtf8(attribute.name);
            Value = NativeUtf8Helper.StringFromNativeUtf8(attribute.value);
            OriginalName = NativeUtf8Helper.StringFromNativeUtf8(attribute.original_name.data, (int)attribute.original_name.length);
            OriginalValue = NativeUtf8Helper.StringFromNativeUtf8(attribute.original_value.data, (int)attribute.original_value.length);
            NameStart = attribute.name_start;
            NameEnd = attribute.name_end;
            ValueStart = attribute.value_start;
            ValueEnd = attribute.value_end;
            Namespace = attribute.attr_namespace;
        }
Пример #4
0
        private bool ValidateNode(ElementWrapper node, InsertionsMap insertionsMap, ref RequestValidationParam dangerousParam)
        {
            var result = true;

            foreach (
                var element in node.Children.OfType<ElementWrapper>())
            {
                var elementStart = (int)element.StartPosition.offset;
                var elementEnd = (int)element.EndPosition.offset;

                foreach (
                    var insertionArea in
                        insertionsMap.Where(ia => ia.Includes(elementStart, elementEnd)))
                {
                    // Check if start position of node was included to insertions map
                    if (insertionArea.Includes(elementStart))
                    {
                        // Inclusion found (node was injected by request parameter)
                        dangerousParam = insertionArea.Param;
                        return false;
                    }

                    foreach (var attr in element.Attributes)
                    {
                        var attrNameStart = (int)attr.NameStart.offset;

                        if (insertionArea.Includes(attrNameStart))
                        {
                            // Inclusion found (attribute was injected by request parameter)
                            dangerousParam = insertionArea.Param;
                            return false;
                        }

                        var attrValueStart = (int)attr.ValueStart.offset;
                        var attrValueEnd = (int)attr.ValueEnd.offset;

                        // Skip if attribute value wasn't tainted by request parameter
                        if (!insertionArea.Includes(attrValueStart, attrValueEnd)) continue;

                        // Skip if attribute value passes validation
                        if (ValidateAttribute(attr.Name, attr.Value, insertionArea.Param.Value)) continue;

                        // Attribute value is dangerously tainted
                        dangerousParam = insertionArea.Param;
                        return false;
                    }
                }

                if (element.Tag == GumboTag.GUMBO_TAG_SCRIPT && element.Children.Any(child => child is TextWrapper))
                {
                    var text = element.Children.OfType<TextWrapper>().FirstOrDefault();

                    if (text != null)
                    {
                        // Validate javscript code inside <script /> tag
                        foreach (
                            var insertionArea in
                                insertionsMap.Where(
                                    ia =>
                                        ia.Includes((int) text.StartPosition.offset,
                                            (int) text.StartPosition.offset + text.Text.Length))
                                    .Where(insertionArea => !ValidateJavascript(text.Text, insertionArea.Param.Value)))
                        {
                            // Javascript code is dangerously tainted
                            dangerousParam = insertionArea.Param;
                            return false;
                        }
                    }
                }

                // TODO: Add integrity validation of style nodes here

                result &= ValidateNode(element, insertionsMap, ref dangerousParam);
            }

            return result;
        }
Пример #5
0
        private void AddElementWithId(string id, ElementWrapper element)
        {
            List<ElementWrapper> elements;
            if (!ElementsWithIds.TryGetValue(id, out elements))
            {
                elements = new List<ElementWrapper>();
                ElementsWithIds.Add(id, elements);
            }

            elements.Add(element);
        }
Пример #6
0
 private static void MarshalElementAndDescendants(ElementWrapper element)
 {
     GC.KeepAlive(element.Attributes);
     foreach (var child in element.Children.OfType<ElementWrapper>())
     {
         MarshalElementAndDescendants(child);
     }
 }