Пример #1
0
        /*
         * (non-Javadoc)
         *
         * @see org.w3c.css.sac.DocumentHandler#ignorableAtRule(java.lang.String)
         */
        public virtual void ignorableAtRule(string atRule)
        {
            // this method is called when the parser hits an unrecognized
            // @-rule. Like the page/media/font declarations, this is
            // CSS2+ stuff

            //string msg = "The @-rule <u>" + HTMLEntityEncoder.htmlEntityEncode(atRule) + "</u> could not be processed for security reasons.";

            if (tagName != null)
            {
                /*
                 * errorMessages.Add(
                 *  ErrorMessageUtil.getMessage(ErrorMessageUtil.ERROR_CSS_TAG_RULE_NOTFOUND,
                 *  new Object[] {
                 *                      HTMLEntityEncoder.htmlEntityEncode(tagName),
                 *                      HTMLEntityEncoder.htmlEntityEncode(atRule)
                 *              }));
                 */
                errorMessages.Add(HTMLEntityEncoder.htmlEntityEncode(tagName));
            }
            else
            {
                /*
                 * errorMessages.Add(ErrorMessageUtil.getMessage(
                 *  ErrorMessageUtil.ERROR_STYLESHEET_RULE_NOTFOUND,
                 *  new Object[] {
                 *                      HTMLEntityEncoder.htmlEntityEncode(atRule)
                 *              }));
                 */
            }
        }
Пример #2
0
        private void recursiveValidateTag(HtmlNode node)
        {
            int maxinputsize = int.Parse(policy.getDirective("maxInputSize"));

            num++;

            HtmlNode parentNode = node.ParentNode;
            HtmlNode tmp        = null;
            string   tagName    = node.Name;

            //check this out
            //might not be robust enough
            if (tagName.ToLower().Equals("#text"))  // || tagName.ToLower().Equals("#comment"))
            {
                return;
            }

            Tag tag = policy.getTagByName(tagName.ToLower());

            if (tag == null || "filter".Equals(tag.Action))
            {
                StringBuilder errBuff = new StringBuilder();
                if (tagName == null || tagName.Trim().Equals(""))
                {
                    errBuff.Append("An unprocessable ");
                }
                else
                {
                    errBuff.Append("The <b>" + HTMLEntityEncoder.htmlEntityEncode(tagName.ToLower()) + "</b> ");
                }

                errBuff.Append("tag has been filtered for security reasons. The contents of the tag will ");
                errBuff.Append("remain in place.");

                errorMessages.Add(errBuff.ToString());

                for (int i = 0; i < node.ChildNodes.Count; i++)
                {
                    tmp = node.ChildNodes[i];
                    recursiveValidateTag(tmp);

                    if (tmp.ParentNode == null)
                    {
                        i--;
                    }
                }
                promoteChildren(node);
                return;
            }
            else if ("validate".Equals(tag.Action))
            {
                if ("style".Equals(tagName.ToLower()) && policy.getTagByName("style") != null)
                {
                    CssScanner styleScanner = new CssScanner(policy);
                    try
                    {
                        CleanResults cr = styleScanner.scanStyleSheet(node.FirstChild.InnerHtml, maxinputsize);

                        foreach (string msg in cr.getErrorMessages())
                        {
                            errorMessages.Add(msg.ToString());
                        }

                        /*
                         * If IE gets an empty style tag, i.e. <style/>
                         * it will break all CSS on the page. I wish I
                         * was kidding. So, if after validation no CSS
                         * properties are left, we would normally be left
                         * with an empty style tag and break all CSS. To
                         * prevent that, we have this check.
                         */

                        if (cr.getCleanHTML() == null || cr.getCleanHTML().Equals(""))
                        {
                            //node.getFirstChild().setNodeValue("/* */");
                            node.FirstChild.InnerHtml = "/* */";
                        }
                        else
                        {
                            //node.getFirstChild().setNodeValue(cr.getCleanHTML());
                            node.FirstChild.InnerHtml = cr.getCleanHTML();
                        }
                    }
                    //    catch (DomException e)
                    //    {
                    //        addError(ErrorMessageUtil.ERROR_CSS_TAG_MALFORMED, new Object[] { HTMLEntityEncoder.htmlEntityEncode(node.getFirstChild().getNodeValue()) });
                    //        parentNode.removeChild(node);
                    //    }
                    catch (ScanException e)
                    {
                        Console.WriteLine("Scan Exception: " + e.Message);

                        //addError(ErrorMessageUtil.ERROR_CSS_TAG_MALFORMED, new Object[] { HTMLEntityEncoder.htmlEntityEncode(node.getFirstChild().getNodeValue()) });
                        parentNode.RemoveChild(node);
                    }
                }

                HtmlAttribute attribute = null;
                for (int currentAttributeIndex = 0; currentAttributeIndex < node.Attributes.Count; currentAttributeIndex++)
                {
                    attribute = node.Attributes[currentAttributeIndex];

                    string name   = attribute.Name;
                    string _value = attribute.Value;

                    Attribute attr = tag.getAttributeByName(name);

                    if (attr == null)
                    {
                        attr = policy.getGlobalAttributeByName(name);
                    }

                    bool isAttributeValid = false;

                    if ("style".Equals(name.ToLower()) && attr != null)
                    {
                        CssScanner styleScanner = new CssScanner(policy);

                        try
                        {
                            CleanResults cr = styleScanner.scanInlineStyle(_value, tagName, maxinputsize);

                            //attribute.setNodeValue(cr.getCleanHTML());
                            attribute.Value = cr.getCleanHTML();

                            ArrayList cssScanErrorMessages = cr.getErrorMessages();

                            foreach (string msg in cr.getErrorMessages())
                            {
                                errorMessages.Add(msg.ToString());
                            }
                        }

                        /*
                         * catch (DOMException e)
                         * {
                         *
                         *  addError(ErrorMessageUtil.ERROR_CSS_ATTRIBUTE_MALFORMED, new Object[] { tagName, HTMLEntityEncoder.htmlEntityEncode(node.getNodeValue()) });
                         *
                         *  ele.removeAttribute(name);
                         *  currentAttributeIndex--;
                         *
                         * }
                         */
                        catch (ScanException ex)
                        {
                            Console.WriteLine(ex.Message);
                            //addError(ErrorMessageUtil.ERROR_CSS_ATTRIBUTE_MALFORMED, new Object[] { tagName, HTMLEntityEncoder.htmlEntityEncode(node.getNodeValue()) });
                            //ele.removeAttribute(name);
                            currentAttributeIndex--;
                        }
                    }
                    else
                    {
                        if (attr != null)
                        {
                            //try to find out how robust this is - do I need to do this in a loop?
                            _value = HtmlEntity.DeEntitize(_value);

                            foreach (string allowedValue in attr.AllowedValues)
                            {
                                if (isAttributeValid)
                                {
                                    break;
                                }

                                if (allowedValue != null && allowedValue.ToLower().Equals(_value.ToLower()))
                                {
                                    isAttributeValid = true;
                                }
                            }

                            foreach (string ptn in attr.AllowedRegExp)
                            {
                                if (isAttributeValid)
                                {
                                    break;
                                }
                                string pattern = "^" + ptn + "$";
                                Match  m       = Regex.Match(_value, pattern);
                                if (m.Success)
                                {
                                    isAttributeValid = true;
                                }
                            }

                            if (!isAttributeValid)
                            {
                                string        onInvalidAction = attr.OnInvalid;
                                StringBuilder errBuff         = new StringBuilder();

                                errBuff.Append("The <b>" + HTMLEntityEncoder.htmlEntityEncode(tagName) + "</b> tag contained an attribute that we couldn't process. ");
                                errBuff.Append("The <b>" + HTMLEntityEncoder.htmlEntityEncode(name) + "</b> attribute had a value of <u>" + HTMLEntityEncoder.htmlEntityEncode(_value) + "</u>. ");
                                errBuff.Append("This value could not be accepted for security reasons. We have chosen to ");

                                //Console.WriteLine(policy);

                                if ("removeTag".Equals(onInvalidAction))
                                {
                                    parentNode.RemoveChild(node);
                                    errBuff.Append("remove the <b>" + HTMLEntityEncoder.htmlEntityEncode(tagName) + "</b> tag and its contents in order to process this input. ");
                                }
                                else if ("filterTag".Equals(onInvalidAction))
                                {
                                    for (int i = 0; i < node.ChildNodes.Count; i++)
                                    {
                                        tmp = node.ChildNodes[i];
                                        recursiveValidateTag(tmp);
                                        if (tmp.ParentNode == null)
                                        {
                                            i--;
                                        }
                                    }

                                    promoteChildren(node);

                                    errBuff.Append("filter the <b>" + HTMLEntityEncoder.htmlEntityEncode(tagName) + "</b> tag and leave its contents in place so that we could process this input.");
                                }
                                else
                                {
                                    node.Attributes.Remove(attr.Name);
                                    currentAttributeIndex--;
                                    errBuff.Append("remove the <b>" + HTMLEntityEncoder.htmlEntityEncode(name) + "</b> attribute from the tag and leave everything else in place so that we could process this input.");
                                }

                                errorMessages.Add(errBuff.ToString());

                                if ("removeTag".Equals(onInvalidAction) || "filterTag".Equals(onInvalidAction))
                                {
                                    return; // can't process any more if we remove/filter the tag
                                }
                            }
                        }
                        else
                        {
                            StringBuilder errBuff = new StringBuilder();

                            errBuff.Append("The <b>" + HTMLEntityEncoder.htmlEntityEncode(name));
                            errBuff.Append("</b> attribute of the <b>" + HTMLEntityEncoder.htmlEntityEncode(tagName) + "</b> tag has been removed for security reasons. ");
                            errBuff.Append("This removal should not affect the display of the HTML submitted.");

                            errorMessages.Add(errBuff.ToString());
                            node.Attributes.Remove(name);
                            currentAttributeIndex--;
                        } // end if attribute is or is not found in policy file
                    }     // end if style.equals("name")
                }         // end while loop through attributes


                for (int i = 0; i < node.ChildNodes.Count; i++)
                {
                    tmp = node.ChildNodes[i];
                    recursiveValidateTag(tmp);
                    if (tmp.ParentNode == null)
                    {
                        i--;
                    }
                }
            }
            else if ("truncate".Equals(tag.Action))
            {
                Console.WriteLine("truncate");
                HtmlAttributeCollection nnmap = node.Attributes;

                while (nnmap.Count > 0)
                {
                    StringBuilder errBuff = new StringBuilder();

                    errBuff.Append("The <b>" + HTMLEntityEncoder.htmlEntityEncode(nnmap[0].Name));
                    errBuff.Append("</b> attribute of the <b>" + HTMLEntityEncoder.htmlEntityEncode(tagName) + "</b> tag has been removed for security reasons. ");
                    errBuff.Append("This removal should not affect the display of the HTML submitted.");
                    node.Attributes.Remove(nnmap[0].Name);
                    errorMessages.Add(errBuff.ToString());
                }

                HtmlNodeCollection cList = node.ChildNodes;

                int i      = 0;
                int j      = 0;
                int length = cList.Count;

                while (i < length)
                {
                    HtmlNode nodeToRemove = cList[j];
                    if (nodeToRemove.NodeType != HtmlNodeType.Text && nodeToRemove.NodeType != HtmlNodeType.Comment)
                    {
                        node.RemoveChild(nodeToRemove);
                    }
                    else
                    {
                        j++;
                    }
                    i++;
                }
            }
            else
            {
                errorMessages.Add("The <b>" + HTMLEntityEncoder.htmlEntityEncode(tagName) + "</b> tag has been removed for security reasons.");
                parentNode.RemoveChild(node);
            }
        }