Change XmlReaderSettings for autogenerated WCF client - c#

I've generated code to communicate with WCF service using command:
svcutil.exe /syncOnly http://example.com/api.wsdl
In runtime I catch the exception:
For security reasons DTD is prohibited in this XML document. To enable DTD processing set the DtdProcessing property on XmlReaderSettings to Parse and pass the settings into XmlReader.Create method
How should I do that? How can I change XmlReaderSettings?

I have the exact same problem. I have been struggling with this the past 3 days. I am getting this error after TLS 1.2 was enforced on the server that host my webservice.
I also noticed that the WCF data service does not give the same problem. I only have to make sure .Net Framework is 4.6 or above. I assume because WCF data service is REST is why is does not give the same error.
I also read that the xmlreadersettings must be changed. But that is nog exposed in a WCF Service???

Related

asp.net .asmx web service ishow XXE vulnerability - External DNS

We have uncovered an XML External Entity vulnerability in our asp.net asmx web service.
We are testing an asp.net .asmx web service using burp suite, to check for XML External Entity Processing vulnerabilities. See:
https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#net
We see that when a DTD is included in the request like this:
<!DOCTYPE soapenv:envelope PUBLIC "-//B/A/EN" "http://1234565.cigitalcollaborator.com">
A DNS request is sent to for cigitalcollaborator.com. This indicates the asmx web service is processing the DTD in request.
We are using .net version 4.5.2.
According to this link, XXE vulnerabilities should be implicitly blocked for .net 4.5.2 and later:
https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet#.NET_4.5.2_and_later
But it's not... We ge this DNS lookup.
The underlying .net framework is handling XML deserialization/serialization for this asmx web service, so there's no code for us to really fix here. We cannot alter the behavior right, because it's somewhere in the underlying framework?
How we can fix this XXE vulnerability for our ASMX web service?
Thank you
Jon Paugh
I think that it is important to consider two different points here:
First - An automated scan designed to work across web applications using all manner of different technologies does not prove that a vulnerability is present. A DNS lookup is not the same as fully processing the Entity in question. If a subsequent request is made to the url in question, and data from that is processed then you have a vulnerability. You can configure your application use a proxy like Fiddler to verify if such a request is made.
Secondly, .NET has been secure since 4.5.2 by default. This is not the same as guaranteed secure. If an application requires DTD processing it can be enabled in the settings:
var xmlReaderSettings = new XmlReaderSettings();
xmlReaderSettings.DtdProcessing = DtdProcessing.Parse;
var xmlReader = XmlReader.Create(new StringReader("EvilXml", xmlReaderSettings));
Or
var xmlTextReader = new XmlTextReader(new StringReader("EvilXml");
xmlTextReader..DtdProcessing = DtdProcessing.Parse;
And with an XDocument resolver implementations process DTDs
var xmlDocument = new XmlDocument();
// Implementations of XmlResolver are probably unsafe
xmlDocument.XmlResolver = new MyCustomResolver();
// xmlDocument.XmlResolver = null is safe - should be the default from 4.5.2
xmlDocument.LoadXml("EvilXml");
I would probably search the source code for the two relevant text strings "DtdProcessing.Parse" and "XmlResolver" to rule this out.
ASXM web services are considered legacy and don't receive all bug fixes as they have limited extension points. You probably want to re-write this or at least put a facade in front of it using like WCF or WebAPI...
Sadly the connect articles referring to this have been taken down with connect retiring but there are references from people to linking to them:
"They are based on the old XML Serialization technology, which is not getting bug fixes. (see Microsoft comment on 1/11/2010)"
https://johnwsaunders3.wordpress.com/

Implementing a SOAP web service

I have a WSDL definition for a SOAP service and I have successfully generated *.cs file from it using SvcUtil.
Implementing client is quite straightforward - I just need to call the necessary functions from the generated *.cs and that's it.
Implementing server seems more complicated. As I understand I need to implement an interface from the generated *.cs and then use some magic to turn it into the web server.
But I don't need a new web server, I already have a web server written in C# which already has many functionality unrelated to the SOAP service that I need to implement. I don't want to create another web server but I want my SOAP service to be just a part of my existing application (server), that is my server can answer e.g. requests http://example.com/request1, http://example.com/request2 etc. and I want this SOAP service to be just http://example.com/request3.
Since HTTP is already handled by my server I don't need .NET to handle it for me, basically my server can accept client connections and call the necessary handler based on the URL. I have a handler for SOAP request which looks approximately like this:
MyResponse HandleSOAPRequest(MyRequest request)
{
// 1. parse soap message from request.body
// 2. process it
// 3. generate response, serialize it in SOAP format and return it
}
The question is - can I rely on WSDL definition and .NET libraries to do it?
Currently I'm parsing SOAP request using XDocument and manually extract fields from it and serialize using simple string concatenation. Using .NET built-in functions to serialize or parse XML doesn't work. That is if I try to serialize response from an object of the class defined in the generated *.cs file then produced XML is different from what is expected by the protocol, similarly, if I try to parse request as an object of the class defined in the generated *.cs file I get error because XML parser expects different format. This applies to both the SoapFormatter and XmlSerializer.
Since .NET can implement client this means that everything that is necessary to parse and serialize SOAP messages is already implemented, I just need to figure out a way how to use this functionality.
The documentation for ServiceModel wasn't very helpful.
The easiest way would be to start the service via the ServiceHost:
ServiceHost host = new ServiceHost(typeof(YourService));
host.Open();
(I assumed here the configuration will come from the app.config and will not be setup in code like in the linked example below.)
How to: Expose a Contract to SOAP and Web Clients
The only drawback of this is that the application has to run with admin rights or otherwise a weird cofiguration is necessary.

I am trying to consume a PHP SOAP service from C# and create a class wrapper in VS 2010

I've been tasked with creating a class wrapper for a SOAP service, the idea is that you'll be able to treat it as a regular class. The main reason for this is that the WDSL for the SOAP service contains only one method and it's got 5 parameters and it's only kind of OO so you'd have to know all the method calls really well and it's a bit hard to remember them all.
OK, so I've tried adding a web reference, now web references can now be added as service references in VS 2010. You click add service reference advanced etc and it puts in a service reference. Great. Unfortunately if I try and access this from a class I can't.
I can build a console app and put code in the main procedure and access the method of the SOAP service fine but when I add a reference to a class library the intellisense won't allow me to select anything. I'd instantiate an instance like so:
SOAPService.webServiceService ws = new SOAPService.webserviceService();
ws.
and then the intellisense refuses to kick in. If I do the same in a web project or a console app then I can access it fine. I've added the namespace I've done all kinds of things. Also, I can add a web reference and get a DISCO file whenever I create a web project.
OK, also while I'm on the subject I also need to pass credentials to the web service in PHP.
The problem is that in the past I'd create some .net system credentials and add these and it would usually pass through if I was connecting to another .net service.
How should I be sending them to a PHP web service? I always get either invalid username/password combo errors or envelope malformatted error types
Thanks
Mr. B
So the intellisense is not working, but if you add the method in and try to use it does it work, or produce an error?
With regard to diagnosing authentication issues try using fiddler to view the SOAP messages that are being sent, and to view the reply. Do you have some other software that connects and authenticates to that service? Use fiddler to look at the SOAP messages and compare them to see if the header is different etc.
I'd normally do it like this,
using (Service service = new Service())
{
service.ClientCredentials.Windows.ClientCredential.Domain = "domain";
service.ClientCredentials.Windows.ClientCredential.Password = "password";
service.ClientCredentials.Windows.ClientCredential.UserName = "username";
}
Also with regard to the service working or not in general use fiddler if you have any problems, you can see the SOAP messages and it often gives you a clearer message.
I know in IIS you can turn on failed request handling that also gives you an insight from what is going on at the server end, perhaps you have some form of logging too for your php service?

Trouble talking to web service in C#: XmlChoiceIdentifierATtribute is not valid in Items

There is a WSDL webservice that is out of my control that I'm having trouble with; I can interact with this service using soapUI and using Add Service Reference -> advanced -> Add Web Reference without a problem.
However, when I attempt to talk to it using the standard Add Service Reference method (add a service reference, connect using the generated code from wsdl.exe), I get the following error:
XmlSerializer attribute System.Xml.Serialization.XmlChoiceIdentifierAttribute is not
valid in Items. Only XmlElement, XmlArray, XmlArrayItem, XmlAnyAttribute and
XmlAnyElement attributes are supported when IsWrapped is true.
Description: An unhandled exception occurred during the execution of the current web
request. Please review the stack trace for more information about the error and where
it originated in the code.
Exception Details: System.InvalidOperationException: XmlSerializer attribute
System.Xml.Serialization.XmlChoiceIdentifierAttribute is not valid in Items. Only
XmlElement, XmlArray, XmlArrayItem, XmlAnyAttribute and XmlAnyElement attributes are
supported when IsWrapped is true.
I've read some things saying there is some SOAP incompatibility between Java and .NET, but searching around I can find virtually no one who is having this problem, making me think I must be doing something wrong?
What is happening is that the DataContractSerializer (default for WCF) cannot handle the schema (this is typical in non WCF-WCF scenarios) so it "falls back" and generates a proxy which uses XmlSerializer. It is possible that the "fallback" mechanism of generating a proxy for use with XmlSerializer is not generating it in a manner consistent with that of the direct-to-XmlSerializer approach used by Add Web reference.
When you Go to "Advanced->Add Web Reference" you are manually telling Visual Studio to use a meechanism that directly generates proxies which use the XmlSerializer instead of using the fallback mechanism.

Does myAssembly.xmlSerializer.dll always get generated?

I have a web service that does not use any xml attributes for serialization. I just return a string from the web service. In this case, does a serialization dll get created?
The reason I ask is I keep seeing c:\windows\temp\xxxxx.dll (where xxxxx is a random sequence of characters) every couple of weeks the web service is running. One solution is to pre-compile using sgen.exe and that might solve the problem.
Also, I saw a link that said only do this for client side libraries, but this error is on the web service side (server side), so can I still use sgen.exe?
JD
Every time you call the XmlSerializer constructor it will check the type you are trying to serialize and it will generate a temporary assembly. If the assembly already exists it will reuse it. So if your web service is a classic ASMX service it will use XmlSerializer on every request, no matter the return type. These temporary assemblies are part of the serialization process and in my opinion you shouldn't worry too much about them.

Categories

Resources