SOAP Security advice required - c#

Ahead of a full 3rd Party penetration test, one of our clients has performed a preliminary security audit against our system.
This has revealed a handful of potential exploits that we are happy to deal with, but there is one item in the report that I'm not sure I agree with but I've been unable to convince them.
They have reported that they have been able to send a message which has been tampered with to one of our soap-based web services and that it has reported an error. This, they suggest, implies that the server has attempted to process the message.
So the request looks something like this :-
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://example.com/soap/envelope/]]>><" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<tns:SomeMethod xmlns:tns="http://example.com/"/>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Note the encoded ]]>>< inserted into the xmlns:SOAP-ENV attribute.
The response from the server is :-
<soap:Body>
<soap:Fault>
<faultcode>soap:VersionMismatch</faultcode>
<faultstring>Possible SOAP version mismatch: Envelope namespace http://example.com/soap/envelope/]]>>< was unexpected. Expecting http://example.com/soap/envelope/.</faultstring>
<detail />
</soap:Fault>
</soap:Body>
Their argument is that this shows that the payload has been inserted into an XML document and so has been processed (presumably exposing us to things like XXE exploits) and the fact that the error is a SOAP error rather than a generic 500 error proves this.
I'm not convinced that this is the case but I'm struggling to convince the client of this. According to this (https://msdn.microsoft.com/en-us/library/aa480498.aspx) article the XmlSerializer is responsible for serialising and deserialising the SOAP Xml to parmeters and so this is rejecting the bad SOAP envelope.
Can anyone confirm whether we have a security issue? And if it is how we should fix it?

Can anyone confirm whether we have a security issue? And if it is how we should fix it?
There is no security issue.
Different SOAP processors will produce different error messages for this example, though the SOAP protocol recommends the "SOAP version mismatch" fault. In my experience of 10+ years working with XML, SOAP, and other web services protocols, it is perfectly legitimate what his SOAP processor does. It simply rejects the SOAP-ENV:Envelope qualified tag based on the XML namespace mismatch, because the xmlns binding URI simply differs from the expected URI:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://example.com/soap/envelope/]]>><"
In fact, this XML is perfectly legit. And it should be rejected by the SOAP processor with a SOAP version mismatch fault.

Related

OcppV1.5 over Soap Error: Action does not exist

i am currently building a Client to communicate with a Gateway of a Charge Point.
The communication is build with OcppV1.5 over Soap & Http.
The Server doesn't accept my request. I get a Http Response 500 with the Error Reason:
"XML Request is not well formed, Action does not exist."
I looked into the wsdl files but I just don't understand why it doesn't accept my action.
My Request looks something like this:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="https://www.w3.org/2005/08/addressing" xmlns:cs="urn://Ocpp/Cp/2012/06/">
<SOAP-ENV:Header>
<cs:chargeBoxIdentity>0000.0000</cs:chargeBoxIdentity>
<wsa:From>
<wsa:Address>http://000.000.000.000:0000</wsa:Address>
</wsa:From>
<wsa:To>http://000.000.000.001:0001</wsa:To>
<wsa:Action>/ChangeConfiguration</wsa:Action>
<wsa:MessageID>00000.000000000000</wsa:MessageID>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<cs:changeConfigurationRequest>
<cs:key>MeterValueSampleInterval</cs:key>
<cs:value>60</cs:value>
</cs:changeConfigurationRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Update:
As Bogdan suggested I tried to send the same message using SoapUi and it worked. The generated Request from SoapUi looks like this:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ns="urn://Ocpp/Cp/2012/06/">
<soap:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
<ns:chargeBoxIdentity>000000.00000</ns:chargeBoxIdentity>
<wsa:Action>/ChangeConfiguration</wsa:Action>
<wsa:ReplyTo>
<wsa:Address>http://000.000.000.000:0000</wsa:Address>
</wsa:ReplyTo>
<wsa:MessageID>uuid:00000000-0000-0000-0000-000000000000</wsa:MessageID>
<wsa:To>http://000.000.000.000:00000/</wsa:To>
</soap:Header>
<soap:Body>
<ns:changeConfigurationRequest>
<ns:key>MeterValueSampleInterval</ns:key>
<ns:value>300</ns:value>
</ns:changeConfigurationRequest>
</soap:Body>
</soap:Envelope>
It's hard to tell from what you posted why you are getting an error, so I can only add some information that can hopefully allow you to troubleshoot the issue.
Your message has WS-Addressing headers, <wsa:Action> being one of them. The value of this field should be specified in the WSDL if your WSDL also includes WS-Addressing Metadata information, or should be specified in the documentation of the web service you are invoking. Your error message "XML Request is not well formed, Action does not exist" seems to indicate that there might be an issue with this field, but there is another action that SOAP services have which is a SOAP action. I asked about it in the comment above to make sure it's eliminated as a source of problems. In SOAP 1.1 it's called SOAPAction and is a separate HTTP header, while in SOAP 1.2 it's an action parameter on the HTTP Content-Type header. Based on the http://www.w3.org/2003/05/soap-envelope namespace, you have a SOAP 1.2 message.
With these explanations layed out, I suggest you take the WSDL and feed it to SoapUI who can generate sample requests that you can use to invoke the web service. If the WSDL also contains WS-Addressing Metadata, SoapUI should be able to pick it up and help you fill in the values you need. If not, look again through the WSDL for Action elements (make sure you differentiate between the SOAP Action and the WS-Addressing Action using their XML namespaces) or through the service documentation.
Once you get a succesfull call using SoapUI, then try to duplicate it with your code. At that point you can again use SoapUI to troubleshoot things and inspect your code built message to see it resembles the one you can successfully send with SoapUI.
Hope this helps get you closer to a resolution.

Altering a SOAP message before deserialization

I'm having trouble intercepting a response message due to an invalid envelope. Unfortunately, WCF is throwing the exception "Unrecognized message version." before AfterReceiveReply is called so I don't have an opportunity to correct the response XML. Is there a lower level (or different) call I can use to intercept the stream and correct this XML or is there a better way to handle the response, i.e. CustomBinding?
I've tried IClientMessageInspector AfterReceiveReply and IOperationBehavior but these behaviors are both called after the exception is thrown.
Here's what the response looks like.
<ENVELOPE>
<HEADER>
<ERROR_CODE>955</ERROR_CODE>
<ERROR_DESC>XML Parsing Failed: test:1:74 error: value '1231231230' does not match regular expression facet '\d{19,20}'</ERROR_DESC>
<ASYNCH_RESPONSE_INDICATOR>0</ASYNCH_RESPONSE_INDICATOR>
</HEADER>
<BODY>
<MY_METHOD_RESPONSE></MY_METHOD_RESPONSE>
</BODY>
</ENVELOPE>
The service you are trying to call is not a SOAP service. It looks like an old style POX web service, in which case there are two ways you can consume it.
use a WCF POX client, or
use HttpWebRequst
To use WCF, refer to here and here. Your problem here is that these style of services are now considered unorthodox, so the later versions of WCF may no longer support them.
On the other hand, HttpWebRequest, while still supported in .net, is fiddly and not widely used. It does have a high-level wrapper called WebClient which is much easier to use, but it may not give you the level of control you need.
I would certainly investigate the second option first. The support for POX services in WCF was brought in in 2008 with the REST Toolkit, Microsoft's initial foray into the world outside SOAP services (.net remoting notwithstanding), and so is seriously dated.

How to make sense of PHP WSDL

A client (company, not application) has provided a URL to a php-based web service. When I try to work from its url with SOAPUI, WCFTestClient or SvcUtil, all give various levels of non-success.
It looks very much as though there is a case-sensitivity issue. SvcUtil indicates, for example:
Error: There was an error verifying some XML Schemas generated during
export: Type 'http://www.w3.org/2001/XMLSchema:datetime' is not
declared.
Note the case of what I believe should be DateTime.
Is there a way (tool?) that can help generate the C# client side/translate from case-insensitive WSDL?
Note, my web service experience is modest and the customer's is even less so sorry for the basic question. Thanks!

WCF messageheader vs messagebodymember?

I do not understand when I should put the [MessageHeader] instead of the [MessageBodyMember]?
I have read that it's used to conform some protocol like Soap, but still, what does it change at the end?
SOAP is a protocol in which each message (request or response) is made up of two parts: the Header and the Body, inside an Envelope:
<s:Envelope xmlns:s='the namespace for the soap version'>
<s:Header>
<!-- SOAP headers will come here -->
</s:Header>
<s:Body>
<!-- SOAP body members will come here -->
</s:Body>
</s:Envelope>
You normally wouldn't use [MessageContract] (and MessageHeader or MessageBodyMember) in WCF services, only if you really need to interop with some 3rd party which expects the data in a certain format.
I think when I want to put something independent of message content, I will put it in the message header.
And if you want another party to read something from your message, it should be put in the header, because sometimes you may allow someone to read the message header not message body as it contains confidential contents.
You can think about it as difference between message data (MessageBodyMember) and message metadata (MessageHeader). There is plenty of build in standardized headers provided by WCF which deals with addressing, security, reliable messaging, etc. In default WCF implementation it is related only to SOAP.
There is also general rule that in complex messaging architecture there can be intermediaries who read metadata and use them to some processing and message routing (they can even add additional metadata) but they should never interfere with message body (data). In case of security they can even not be able to read message body or some metadata (headers).
In case of WCF you are able to set different security requirements (none, signed, signed and encrypted) for each message header and for whole message body (WCF doesn't support separate security requirements for different body parts). That can also lead to some decision about using body member or header.
For example if you decide to make some custom authentication, or transferring some client information in each message you will probably create custom header for that but real data payload related to the operation will be part of message body.

Semi-custom WCF proxy returns zeros, despite valid data coming back on wire

There is a series of SOAP services which I wish to call (across a series of services), and while the end points are well defined & documented, there is no WSDL data... so I decided to build my own.
In order to do so, I built a test WCF service which matches the known interface of the service I wish to call.
I then saved the WSDL it exposed, changed the base address the WSDL references, created my proxy (with wsdl.exe), added it to a test client project, and can successfully create a proxy and make calls which causes the SOAP service to send the expected response... only this expected response is not picked up by the proxy and returned to the calling code.
When looking at the back and forth traffic... I can clearly see that the service is replying with what I want.
Any suggestions as to how I might troubleshoot this and get the proxy to pickup the data?
Given the replies are effectively identical, I'm forced to look back at the differences between what my client is sending and another sends.
A known working app sends it's XML blob starting with the following:
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
While my client immediately starts with the envelope (without the xml tag, and with one less namespace):
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
The other difference is that the message within the body is prefixed by a namespace in theirs, while mine it is not... though both define this namespace within the tag.
Ala:
<s:Body>
<u:DoSomething xmlns:u="urn:http://some.namespace.org" />
</s:Body>
VS:
<s:Body>
<DoSomething xmlns="urn:http://some.namespace.org" />
</s:Body>
This is not a namespace:
s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
It's setting the encoding style for the envelope which, even though it's not required per the SOAP spec, may be required by the specific implementation you're talking to. Do you have enough control over what you're sending from the client to get that put on there?
Other than that, the XML PI is not required and I think you're definitely on the right track looking at the body XML. This is almost always the case of some kind of namespace mismatch somewhere. Are you 100% positive the namespace URIs are identical?
The most likely problem is the VS version using a "default" XML namespace. There are soap parsers that I've worked which don't work correctly when using an un-aliased (default) namespaces. If you know using the u: alias works with the service, your proxy should also generate it even when every tag inside the s:Body element is prefixed with the alias.

Categories