public bool IsSafeAttribute(string tagName, Element el, NSoup.Nodes.Attribute attr) { TagName tag = TagName.ValueOf(tagName); AttributeKey key = AttributeKey.ValueOf(attr.Key); if (_attributes.ContainsKey(tag)) { if (_attributes[tag].Contains(key)) { if (_protocols.ContainsKey(tag)) { Dictionary <AttributeKey, HashSet <Protocol> > attrProts = _protocols[tag]; // ok if not defined protocol; otherwise test return(!attrProts.ContainsKey(key) || TestValidProtocol(el, attr, attrProts[key])); } else { // attribute found, no protocols defined, so OK return(true); } } } // no attributes defined for tag, try :all tag return(!tagName.Equals(":all") && IsSafeAttribute(":all", el, attr)); }
/// <summary> /// Add allowed URL protocols for an element's URL attribute. This restricts the possible values of the attribute to /// URLs with the defined protocol. /// </summary> /// <remarks>E.g.: <code>AddProtocols("a", "href", "ftp", "http", "https")</code></remarks> /// <param name="tag">Tag the URL protocol is for</param> /// <param name="key">Attribute key</param> /// <param name="protocols">List of valid protocols</param> /// <returns>this, for chaining</returns> public Whitelist AddProtocols(string tag, string key, params string[] protocols) { if (string.IsNullOrEmpty(tag)) { throw new ArgumentNullException("tag"); } if (string.IsNullOrEmpty(key)) { throw new ArgumentNullException("key"); } if (protocols == null) { throw new ArgumentNullException("protocols"); } TagName tagName = TagName.ValueOf(tag); AttributeKey attrKey = AttributeKey.ValueOf(key); Dictionary <AttributeKey, HashSet <Protocol> > attrMap; HashSet <Protocol> protSet; if (this._protocols.ContainsKey(tagName)) { attrMap = this._protocols[tagName]; } else { attrMap = new Dictionary <AttributeKey, HashSet <Protocol> >(); this._protocols.Add(tagName, attrMap); } if (attrMap.ContainsKey(attrKey)) { protSet = attrMap[attrKey]; } else { protSet = new HashSet <Protocol>(); attrMap.Add(attrKey, protSet); } foreach (string protocol in protocols) { if (string.IsNullOrEmpty(protocol)) { throw new Exception("protocol is empty."); } Protocol prot = Protocol.ValueOf(protocol); protSet.Add(prot); } return(this); }
public Attributes GetEnforcedAttributes(string tagName) { Attributes attrs = new Attributes(); TagName tag = TagName.ValueOf(tagName); if (_enforcedAttributes.ContainsKey(tag)) { Dictionary <AttributeKey, AttributeValue> keyVals = _enforcedAttributes[tag]; foreach (KeyValuePair <AttributeKey, AttributeValue> entry in keyVals) { attrs.Add(entry.Key.ToString(), entry.Value.ToString()); } } return(attrs); }
/// <summary> /// Add a list of allowed elements to a whitelist. (If a tag is not allowed, it will be removed from the HTML.) /// </summary> /// <param name="tags">tag names to allow</param> /// <returns>this (for chaining)</returns> public Whitelist AddTags(params string[] tags) { if (tags == null) { throw new ArgumentNullException("tags"); } foreach (string tagName in tags) { if (string.IsNullOrEmpty(tagName)) { throw new Exception("An empty tag was found."); } _tagNames.Add(TagName.ValueOf(tagName)); } return(this); }
/// <summary> /// Add a list of allowed attributes to a tag. (If an attribute is not allowed on an element, it will be removed.) /// E.g.: AddAttributes("a", "href", "class") allows href and class attributes on a tags. /// </summary> /// <remarks> /// To make an attribute valid for <b>all tags</b>, use the pseudo tag <code>:all</code>, e.g. /// <code>AddAttributes(":all", "class")</code>. /// </remarks> /// <param name="tag">The tag the attributes are for. The tag will be added to the allowed tag list if necessary.</param> /// <param name="keys">List of valid attributes for the tag.</param> /// <returns>This (for chaining)</returns> public Whitelist AddAttributes(string tag, params string[] keys) { if (string.IsNullOrEmpty(tag)) { throw new ArgumentNullException("tag"); } if (keys == null) { throw new ArgumentNullException("keys"); } if (keys.Length <= 0) { throw new ArgumentException("No attributes supplied."); } TagName tagName = TagName.ValueOf(tag); if (!_tagNames.Contains(tagName)) { _tagNames.Add(tagName); } HashSet <AttributeKey> attributeSet = new HashSet <AttributeKey>(); foreach (string key in keys) { if (string.IsNullOrEmpty(key)) { throw new Exception("key"); } attributeSet.Add(AttributeKey.ValueOf(key)); } if (_attributes.ContainsKey(tagName)) { HashSet <AttributeKey> currentSet = _attributes[tagName]; foreach (AttributeKey item in attributeSet) { currentSet.Add(item); } } else { _attributes.Add(tagName, attributeSet); } return(this); }
/// <summary> /// Add an enforced attribute to a tag. An enforced attribute will always be added to the element. If the element /// already has the attribute set, it will be overridden. /// </summary> /// <remarks>E.g.: <code>AddEnforcedAttribute("a", "rel", "nofollow")</code> will make all <code>a</code> tags output as /// <code><a href="..." rel="nofollow"></code></remarks> /// <param name="tag">The tag the enforced attribute is for. The tag will be added to the allowed tag list if necessary.</param> /// <param name="key">The attribute key</param> /// <param name="value">The enforced attribute value</param> /// <returns>this (for chaining)</returns> public Whitelist AddEnforcedAttribute(string tag, string key, string value) { if (string.IsNullOrEmpty(tag)) { throw new ArgumentNullException("tag"); } if (string.IsNullOrEmpty(key)) { throw new ArgumentNullException("key"); } if (string.IsNullOrEmpty(value)) { throw new ArgumentNullException("value"); } TagName tagName = TagName.ValueOf(tag); if (!_tagNames.Contains(tagName)) { _tagNames.Add(tagName); } AttributeKey attrKey = AttributeKey.ValueOf(key); AttributeValue attrVal = AttributeValue.ValueOf(value); if (_enforcedAttributes.ContainsKey(tagName)) { _enforcedAttributes[tagName].Add(attrKey, attrVal); } else { Dictionary <AttributeKey, AttributeValue> attrMap = new Dictionary <AttributeKey, AttributeValue>(); attrMap.Add(attrKey, attrVal); _enforcedAttributes.Add(tagName, attrMap); } return(this); }
public bool IsSafeTag(string tag) { return(_tagNames.Contains(TagName.ValueOf(tag))); }