I must take exception to your claim that "SOAP cannot distinguish between sensitive and non-sensitive web services and cannot perform user authentication, authorization, and access control."
It can. Stop Panicing
Specifically, you can use authorisation headers to include username and signature or password and have that handled by a header handler, orthogonally to the actual execution code. Also, most implementations make it trivial to work out the sender's IP address, so your handler or SOAP service can check it against a list, even though I prefer servlet2.3 filters for this purpose, and arrowpoint configuration even better. If your ops team cannot config an arrowpoint to restrict different http URLS to different network addresses, get a new ops team.
Finally, if you host your web service under Java or .NET you get the opportunity to crank down the functionality of the service's code to exactly that which you want 'no exec', read/write access to a subset of the file system, even before you get as far as doing separate user logins with restricted rights.
To summarise, I don't have any fear that by implementing a SOAP endpoint I have given unrestricted access to my entire app server to all callers, because I can restrict by subnet, by header signing and by cranking back the rights of the webapp. Articles claiming this is the case set spread terror almost us much as Bruce Schneider's "Soap is going to open up a whole new avenue for security vulnerabilities," claim.
I would also like to draw your attention to the Axis security document, which I wrote to clarify exactly what and where the security risks are in Axis:
http://cvs.apache.org/viewcvs.cgi/~checkout~/xml-axis/java/docs/security.html
If you think then I am fundamentally mistaken in my optimism then I would relish the opportunity to be corrected.
Steve Loughran
(author, Java Development with Ant, Axis developer, all round troublemaker)
Tell me what is SOAP? Is it something that we can imagine on our own?
The main problem about most SOAP programmers is that it is hard for them to appreciate that we are working in the interoperability paradigm.
This paradigm has several requirements that are unique from the era that led us to the idea of interoeprability.
The most important thing about interoperability is that we *cannot* do things the way we think they should be done. Even if I am sure that the approach I saw in my dream last night is the best
suitable solution, it is *not*. The best solution is now to work with standards, no matter whether we agree with the standards or not.
Having said that, please now go through the SOAP specification. For your convenience, here are a couple of sentences copied from the specification (URI to the official document fragment from where I copied is: http://www.w3.org/TR/2002/CR-soap12-part1-20021219/#secconsiderations):
QUOTE:
The SOAP Messaging Framework does not directly provide any mechanisms for dealing with access control, confidentiality, integrity and non-repudiation. Such mechanisms can be provided as SOAP extensions using the SOAP extensibility model..............
UNQUOTE:
So your little tricks are destroying interoperability, the very purpose of the existence of SOAP. If we don't care about or don't need interoerpability, then we don't
need SOAP at all. There are other better ways of remote invocation of methods. The whole effort for web services standardization is to enable
interoperability.
Simply put, SOAP is what the official SOAP specification says it is. Nothing more and nothing less. SOAP *does* have security threats and we do need to fear those threats. And fearing those threats gives rise to the development
of XML-based security standards.
In the next article of this series, I will try to explain some bits of how this security hole in SOAP applications can be filled in an interoperable way.
Your further comments and queries are welcome :)
Bilal
Note: Please look again at your IP addesses technique. Is it possible to apply this technique on the following scenario:
We have two web services hosted on the same SOAP server. I want to allow user A to access web service 1 but not web service 2. I want to allow user B to access web service 2 but not web service 1.
How will I stop user A from accessing web service 2, once his IP address has been authenticated and authorized? My IP firewall/filter is not aware of SOAP syntax (so it cannot look into a SOAP message to find out which web service it is heading for). So once my IP firewall software allows user A to access my web service 1, nothing can stop user A from accessing web service 2.
I think this scenario can only be handled with user tokens embedded inside a SOAP message (this is equivalent to making your IP firewall/filter SOAP-aware). Working with IP addresses alone cannot work. I have explained this in the article.
About servlets filter, it seems that it is not very easy to implement for newcomers like me ;) on WebSphere Application Developer 5.1.2 -> It seems that a WebSphere Gateway is necessary... Another brick in the big SOAP wall !!
About the security in general, I wonder why the SOAP implementers have not added a specification about the originating IP address of the incoming SOAP request, in the SOAP XML data itself... I think it is a big error from them, as this should have been the first think they could have thought of ;)
But maybe there is an explanation that I dont know :)
See you
Error: Document not found.
Path: /a/ws/2002/11/13/py-xml.html
About servlets filter, it seems that it is not very easy to implement for newcomers like me ;) on WebSphere Application Developer 5.1.2 -> It seems that a WebSphere Gateway is necessary... Another brick in the big SOAP wall !!
About the security in general, I wonder why the SOAP implementers have not added a specification about the originating IP address of the incoming SOAP request, in the SOAP XML data itself... I think it is a big error from them, as this should have been the first think they could have thought of ;)
But maybe there is an explanation that I dont know :)
I celebrate disagreement; it introduces new ideas. This is why, sadly, I must continue to disagree with your statements.
The key issue I have is that you are talking about SOAP over HTTP, yet using only the SOAP specifications for information, when you should be using the HTTP specs as well.
Your question was"
"We have two web services hosted on the same SOAP server. I want to allow user A to access web service 1 but not web service 2. I want to allow
user B to access web service 2 but not web service 1.
How will I stop user A from accessing web service 2, once his IP address has been authenticated and authorized? "
This is trivial. Really. It is so trivial it hurts.
Imagine we are running a server with web service 1. Because in SOAP over HTTP, services are bound to endpoint URLs, this service has an Url that defnes the service :
http://example.com/axis/services/Service1
now lets add another service. It will have its own endpoint:
http://example.com/axis/services/Service2
Can you see where I am getting at yet?
If I want to let user A at service 1, and user B at service 2, then all I have to do is configure the web server that is hosting the Axis runtime so that the URLs have different security rights. That's all. Router side, I could do this by fiddling with arrowpoint security settings to restrict by IP address. But we want authentication, rather than just IPaddr filtering so what do we do?
We go to the servlet API spec and look up what it takes to add security to a pattern of URLs, and extend the web.xml of Axis to filter on URLs:
<security-constraint>
<web-resource-collection>
<web-resource-name>Service1</web-resource-name>
<url-pattern>/services/service1</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>service1</role-name>
</auth-constraint>
</security-constraint>
Now when anything hits service1 it gets a 401 response, "no auth", and has to respond with the authentication information before it gets through. With the appropriate configuration of the app server, such as this change to tomcat's server.xml:
we get an app server that only gives userB access to the service2 role, and userA access to the service1 role -and our services have their access restricted to the roles of the same name.
Thus the HTTP infrastructure that SOAP is running over is preventing anything from POSTing to the different endpoints.
Therefore I rest my case: you do not need extra security above and beyond HTTP (digest) and HTTPS to have encrypted and authenticated SOAP messaging over HTTP. I am not doing any "tricks that destroy interoperability" as you claimed. We, and by that I mean everyone who implements SOAP over HTTP client and server frameworks, are reusing the existing pieces of the HTTP infrastructure to offer people security they can understand.
The rationale for WS-security is not that HTTP security is inadequate; it is because some people want to move beyond HTTP as a transport. Once you change transports you have a different problem. But your 'figure 7' service is quite clearly an HTTP based solution, which you can secure quite easily today.
You can continue disagreeing without going sad. We can do it happily as it introdcues new ideas!!!
However, I do not find much of a disagreement in your message. Your first message was about little security tricks (user tokens, IP addresses etc. for authentication) and I explained that we have to work with standards, without which we cannot ensure interoperability. For example, if we decide about user tokens, we need standards describing how to wrap and process security tokens in XML format.
At the end of my last message, I just put up a question, in which I was trying to prove that user tokens inside SOAP messages (the XML layer) are necessary for web services security. We cannot use lower layers for web services security.
After reading your latest message in which you want to celebrate further disagreement, without commenting anything on the main issue of the first message (interoperability), I think there is a basic confusion about two things. Please note that *interoperabiulity* and *deciding the level to implement web services security* are two distinct problems. You have chosen to disagree
only about the level to implement web services security. So I think the interoperability debate is over, with a conclusion that we have to stick
with standards. However, you can reopen the debate any time, happily :)
Your answer to my question assumes that my question was specifically about SOAP over HTTP, while my question did not mention SOAP over HTTP. However, I do think I should have explicitlly mentioned in my question that I am talking about SOAP in general and not SOAP over HTTP. So, let's discuss BOTH cases: SOAP in general AND SOAP over HTTP. And you will see that using HTTP end points to implement web services security is inadequate in both cases.
You mention "The rationale for WS-security is not that HTTP security is inadequate". Did I ever say that HTTP security is inadequate? My point is that HTTP security is not suitable for SOAP (and this is *partly* the rationale for WS-Security). Let's consider two of the popular models for moving beyond HTTP as a transport:
Messaging middleware applications like JMS
Virtual network overlay applications like JXTA
In both these applications, there will be middleware modules working effectively as routers over HTTP or some other equivalent transport. Such middleware modules give rise to the concept of SOAP intermediaries. The simple result is that the SOAP requester and the ultimate recepient of the SOAP message (the SOAP server which is supposed to author the SOAP response) MAY not know the HTTP or IP addresses of each other. So you cannot rely on web service end points to implement security. And if you do rely on web service end points, I think here you are breaking the well established rules formed in the early days of OSI stack development, when people used to argue what functionality should be built into which layer. Resuability (abstraction and encapsulation) are proven techniques not just in OO, but also in protocol stack development.
And if you trivialize this matter today, you will need to re-build systems as business logic grows.
Another thing. If we do consider SOAP oever HTTP, how will you implement operation or method level authorization policies?
These are the reasons, I don't consider HTTP for securing web services. And I think SOAP developers also appreciate these points. Please go through section 7.1.2 of SOAP Version 1.2 Part 2: Adjuncts specification. This section describes the *purpose* of SOAP HTTP binding. For your convenience, here is an extract from the official document:
QUOTE:
This binding is not intended to fully exploit the features of HTTP, but rather to use HTTP specifically for the purpose of communicating with other SOAP nodes implementing the same binding. Therefore..........
UNQUOTE:
I think, if you rely on HTTP for anything other than "specifically for the purpose of communicating with other SOAP nodes", you are misusing the technological framework available. Your customers will pay the price later on for this over-trivialization. And you see, that's why it hurts!
I mentioned in the begininng "I do not find much of a disagreement in your message". I think the only disagreement is in the "frame of minds". You solve a problem without considering what's coming next and say "Look this is so easy that it hurts". And I am trying to focus on what's coming next, and therefore don't think that your solution addresses the problem at all.
First: I wanted to say I have really enjoyed this article and the banter at the bottom.
Second: I wanted to throw in my two cents.
I agree with both of you but I have found a recent need to not follow the standards when it comes to developing secure web services.
By monitoring the raw structure of a SOAP request and return message it is clear that SOAP is simply a hybrid of the HTTP message structure.
For example:
*HTTP*
---Standard HTTP header POST (non-soap post):
POST /ReportService/Publisher/createReport HTTP/1.1
Host: somehost.com
Content-Type: application/x-www-form-urlencoded
Content-Length: length
Followed by standard HTTP post data
---Standard HTTP header RETURN
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
Followed by XML
*SOAP*
---Standard SOAP header POST:
POST /ReportService/Publisher HTTP/1.1
Host: somehost.com
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: http://somehost.com/ReportService/createReport
Followed by XML
---Standard SOAP header RETURN
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
Followed by XML
As you can see, in these examples, the posting/request headers are nearly identical and the return headers for HTTP and SOAP… ARE identical.
Beyond the header you either process XML or HTTP post data which is nothing more than “string” or “string encoded” data unless it has a binary attachment.
Any hacker will find this easy to strip apart and analyze then later mimic a valid consumer.
First habit: Always use SSL. You really don’t need another layer of encryption beyond this. Though in some cases I do anyway to provide an additional layer of security but it is really not needed other than to provide comfort to a customer.
Second habit: Minimize how often the client consumer has to send authentication. I only have a consumer send authentication once and authentication can only happen through a “connection” web service method. I then create a “session token” (or GUID) on the service side and return it to the client. The client then HAS to keep this “session token” and included it with all subsequent web services calls.
Yes… these habits require that I run my own “session” manager on the service.
I use this custom session manager to link to our roles and permissions settings to quickly determine if a calling user has access to the method AND/OR the CONTENT/DATA the method may return. In some instances the user will have access to a method but not the selected content that the method can request for. (This is key... security really goes beyond access to a web service method but also to the data that a method can return... just because a client has access to a method does not mean they have access to ALL data that method can return.)
The “session” manager monitors for these issues and modifies the returned XML to inform the consumer that they don’t have access to that data.
I try to never return a 404 error. I always try to return an XML result that provides some status like…
<STATUS>
<ERROR>FAIL<ERROR>
<MESSAGE>You are not authorized.</MESSAGE>
</STATUS>
To prevent a ‘stolen session’ you simply monitor the calling IP. If the calling IP does not match the IP originally associated with the “session token” when it was created then that call fails. If you don’t have access to the calling IP (or if you don’t have access to the protocol layer) you are in trouble and should resolve this issue first because you will not be able to properly monitor and/or provide secure web services.
The above methodology (beyond the SSL) allows for providing a “proprietary” token and XML authentication structure to and from our services to further prevent “most” hacker attacks. This also removes much of the “overhead” and reduces the size of the SOAP data to better support poor bandwidth environments. (Yes… poor bandwidth environments still exist… most of my experience with web services is in support of getting data to our troops in Iraq which include networks just vanishing and passing through 20 year old satellite technology. HTTP/SOAP does not guarantee message delivery (return stream) in these environments. (...another story for another time…))
This is all probably an over simplification and I look forward to holes and examples to problems with the above theory.