Cannot fix Improper Restriction of XML External Entity Reference error - c#

I have changed the code when trying to fix Veracode error for Improper Restriction of XML External Entity Reference, but it did not fix it.
Here is the code I have now:
XmlDocument xmlDoc=new XmlDocument();
using (System.IO.MemoryStream xmlstream = new System.IO.MemoryStream
(Encoding.Default.GetBytes(dsEQ.GetXml().ToString())))
{
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Prohibit;
using (XmlReader xmlreader = XmlReader.Create(xmlstream, settings))
{
try
{
xmlDoc.Load(xmlreader);
}
catch(XmlException e)
{
Connection.LogError(e.ToString(), e.Message);
}
}
}
However, Veracode still point out on this section of code with the same error message.
Is there anything else that I should do to fix it? We do not have any external references, everything is through intranet.

Set XmlResolver to null:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.XmlResolver = null;

Set XmlResolver = null will fix the issue.
static void LoadXML()
{
string xml = "<?xml version=\"1.0\" ?><!DOCTYPE doc
[<!ENTITY win SYSTEM \"file:///C:/Users/user/Documents/testdata2.txt\">]
><doc>&win;</doc>";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.XmlResolver = null; // Setting this to NULL disables DTDs - Its NOT null by default.
xmlDoc.LoadXml(xml);
Console.WriteLine(xmlDoc.InnerText);
Console.ReadLine();
}
Please go through below link for more information.
XML External Entity (XXE) Prevention Cheat Sheet

The original answer works for xmlDoc.Load(xmlreader).
The second question is a different context and requires different technology.
using (System.IO.StringReader rxml = new System.IO.StringReader(myxmltext))
{
XmlSerializer serializer = new XmlSerializer(typeof(MenuConfigBase));
using (XmlTextReader xr = new XmlTextReader(rxml))
{
xr.XmlResolver = null;
var cfgBase = (MenuConfigBase)serializer.Deserialize(xr);
}
}

Related

XXE: Improper Restriction of XML External Entity Reference With XDocument

So I am running into an issue when I run a security scan on my application. It turns out that I am failing to protect against XXE.
Here is a short snippet showing the offending code:
static void Main()
{
string inp = Console.ReadLine();
string xmlStr = ""; //This has a value that is much too long to put into a single post
if (!string.IsNullOrEmpty(inp))
{
xmlStr = inp;
}
XmlDocument xmlDocObj = new XmlDocument {XmlResolver = null};
xmlDocObj.LoadXml(xmlStr);
XmlNodeList measureXmlNodeListObj = xmlDocObj.SelectNodes("REQ/MS/M");
foreach (XmlNode measureXmlNodeObj in measureXmlNodeListObj)
{
XmlNode detailXmlNodeListObj = xmlDocObj.SelectSingleNode("REQ/DTD");
string measureKey = measureXmlNodeObj.Attributes["KY"].Value;
if (detailXmlNodeListObj.Attributes["MKY"].Value ==
measureKey) //Checking if selected MeasureKey is same
{
XmlNode filerNode = measureXmlNodeObj.SelectSingleNode("FS");
if (filerNode != null)
{
XDocument fixedFilterXmlObj = XDocument.Load(new StringReader(filerNode.OuterXml));
var measureFixedFilters = (from m in fixedFilterXmlObj.Element("FS").Elements("F")
select m).ToList();
foreach (var fixedFilter in measureFixedFilters)
{
var fixedFilterValues = (from m in fixedFilter.Elements("VS").Elements("V")
select m.Attribute("DESC").Value).ToList();
foreach (var value in fixedFilterValues)
{
Console.WriteLine(value.Trim());
}
}
}
}
}
Console.ReadLine();
}
According to Veracode, the line that unsafe is XDocument fixedFilterXmlObj = XDocument.Load(new StringReader(filerNode.OuterXml));
But it seems like according to Owsap, it should be safe:
Both the XElement and XDocument objects in the System.Xml.Linq library
are safe from XXE injection by default. XElement parses only the
elements within the XML file, so DTDs are ignored altogether.
XDocument has DTDs disabled by default, and is only unsafe if
constructed with a different unsafe XML parser.
So it seems like I am making the mistake of using an usafe XML Parser, opening XDocument to XXE.
I found a unit test that replicates the issue and also has a safe usage of XDocument but I can't seem to find what exactly my code is unsafe, because I do not use:
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Parse; // unsafe!
You can run my code to replicate the issue, but you should replace the line with the empty xmlStr with this value: here (too large for a single post)
I'm not sure how or why this works, but it does:
XDocument fixedFilterXmlObj;
using (XmlNodeReader nodeReader = new XmlNodeReader(filerNode))
{
nodeReader.MoveToContent();
fixedFilterXmlObj = XDocument.Load(nodeReader);
}

XMLPrime XLST.Compile throwing a null exception

public static SqlXml XMLPrimeTransform(SqlXml inputDataXML, SqlXml inputTrasnformXML)
{
MemoryStream ms = new MemoryStream();
XmlReader inxml = inputDataXML.CreateReader();
XmlReader intrans = inputTrasnformXML.CreateReader();
XmlReaderSettings xmlreadersettings = new XmlReaderSettings { NameTable = intrans.NameTable };
XdmDocument document= new XdmDocument(inxml);
XmlPrime.XsltSettings xsltSettings = new XmlPrime.XsltSettings(intrans.NameTable) { ContextItemType = XdmType.Node };
var xslt = Xslt.Compile(intrans, xsltSettings);
//var xslt = Xslt.Compile(inputTrasnformXML.CreateReader());
var contextItem = document.CreateNavigator();
var settings = new DynamicContextSettings { ContextItem = contextItem };
xslt.ApplyTemplates(settings, ms);
return new SqlXml(ms);
}
I wrote the above code function to apply a xlst 2.0 stylesheet to xml and return the XML.
I tried to modify the XMLPrime example, but for some reason the line:
var xslt = Xslt.Compile(intrans, xsltSettings);
is throwing a NullReferenceException. Both intrans and xsltSettings are not null. Anyone have any luck trying to accomplish this with XMLPrime or any other library?
It may be a bug specific to the stylesheet you are loading. Try using a minimal stylesheet to see if that is the case. If you think it is a bug in XmlPrime, contact the developers and supply a Visual Studio solution which reproduces the problem.

How to use XmlDocument object instead of reading XML file from drive?

I didn't know that I can use XSD schema to serialize received XML file. I used xsd.exe to generate cs class from XSD file and now I need to use that class to get data in class properties but I miss one thing and I need help.
This is the code:
private void ParseDataFromXmlDocument_UsingSerializerClass(XmlDocument doc)
{
XmlSerializer ser = new XmlSerializer(typeof(ClassFromXsd));
string filename = Path.Combine("C:\\myxmls\\test", "xmlname.xml");
ClassFromXsdmyClass = ser.Deserialize(new FileStream(filename, FileMode.Open)) as ClassFromXsd;
if (myClass != null)
{
// to do
}
...
Here I use XML file from drive. And I want to use this XmlDocument from parameter that I passed in. So how to adapt this code to use doc instead XML from drive?
You could write the XmlDocument to a MemoryStream, and then Deserialize it like you already did.
XmlDocument doc = new XmlDocument();
ClassFromXsd obj = null;
using (var s = new MemoryStream())
{
doc.Save(s);
var ser = new XmlSerializer(typeof (ClassFromXsd));
s.Seek(0, SeekOrigin.Begin);
obj = (ClassFromXsd)ser.Deserialize(s);
}

Using XmlReader get Unauthorized WebException

When trying to consume an RDF feed from craigslist, I'm running into a (401) Unauthorized WebException. I'm able to read the two commented out URLs directly below it with no issues. If I'm able to directly navigate to the craigslist URL using Internet Explorer with no problem, why does it fail when trying to load the data using an XmlReader?
http://portland.craigslist.org/search/sss?query=mac&srchType=A&format=rss
static void Main(string[] args)
{
XmlReader reader = XmlReader.Create("http://portland.craigslist.org/search/sss?query=mac&srchType=A&format=rss");
//XmlReader reader = XmlReader.Create("http://wdfw.wa.gov/news/newsrss.php");
//XmlReader reader = XmlReader.Create("http://rss.slashdot.org/Slashdot/slashdot");
Rss10FeedFormatter rf = new Rss10FeedFormatter();
rf.ReadFrom(reader);
Console.ReadLine();
}
}
Use XmlResolver
XmlUrlResolver resolver = new XmlUrlResolver();
resolver.Credentials = System.Net.CredentialCache.DefaultCredentials;
XmlReaderSettings settings = new XmlReaderSettings();
settings.XmlResolver = resolver;
// create a reader and populate the document
XmlReader reader = XmlReader.Create(rssFeedUrl, settings); //
doc = new XmlDocument();
doc.Load(reader);

Process XML in C# using external entity file

I am processing an XML file (which does not contain any dtd or ent declarations) in C# that contains entities such as é and à. I receive the following exception when attempting to load an XML file...
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(record);
Reference to undeclared entity
'eacute'.
I was able to track down the proper ent file here. How do I tell XmlDocument to use this ent file when loading my XML file?
In versions of the framework prior to .Net 4 you use ProhibitDtd of an XmlReaderSettings instance.
var settings = new XmlReaderSettings();
settings.ProhibitDtd = false;
string DTD = #"<!DOCTYPE doc [
<!ENTITY % iso-lat1 PUBLIC ""ISO 8879:1986//ENTITIES Added Latin 1//EN//XML""
""http://www.oasis-open.org/docbook/xmlcharent/0.3/iso-lat1.ent"">
%iso-lat1;
]> ";
string xml = string.Concat(DTD,"<xml><txt>rené</txt></xml>");
XmlDocument xd = new XmlDocument();
xd.Load(XmlReader.Create(new MemoryStream(
UTF8Encoding.UTF8.GetBytes(xml)), settings));
From .Net 4.0 onward use the DtdProcessing property with a value of DtdProcessing.Parse which you set on the XmlTextReader.
XmlDocument xd = new XmlDocument();
using (var rdr = new XmlTextReader(new StringReader(xml)))
{
rdr.DtdProcessing = DtdProcessing.Parse;
xd.Load(rdr);
}
I ran into the same problem, and not wanting to modify my XML (or DTD), I decided to create my own XmlResolver to add entities on the fly.
My implementation actually reads entities from the config file, but this should be enough to do what you're asking for. In this example, I'm converting a right single curly quote into an apostrophe.
class XmlEntityResolver : XmlResolver {
public override object GetEntity(Uri absoluteUri,
string role,
Type ofObjectToReturn)
{
if (absoluteUri.toString() == "-//MY PUB ID") {
MemoryStream ms = new MemoryStream();
StreamWriter sw = new StreamWriter(ms);
sw.Write("<!ENTITY rsquo \"'\">");
sw.Flush();
ms.Position = 0;
return ms;
}
else {
return base.GetEntity(absoluteUri, role, ofObjectToReturn);
}
}
}
Then, when you declare your XmlDocument, just set the resolver prior to load.
XmlDocument doc = new XmlDocument();
doc.XmlResolver = new XmlEntityResolver();
doc.Load(XML_FILE);
é is not a valid XML entity by default whereas it is a valid HTML entity by default.
You would need to define é as a valid XML entity for XML parsing purposes.
EDIT:
To add a reference to your external ent file you need to do that within the XML file itself. Save the ent file to disk and place it within the same directory as the document being parsed.
<!ENTITY % stuff SYSTEM "iso-lat1.ent">
%stuff;
If you want to go a different route check out the information on ENTITY declaration.
According to this, you have to reference them within the file; you cannot tell LoadXml to do this for you.
Your question has been answered in 2004 itself at MSDN Article........ You can find it here.......
http://msdn.microsoft.com/en-us/library/aa302289.aspx

Categories

Resources