Exceptions don't get return through HttpProxy? #3538
-
We're finally trying to move off of WcfProxy and to HttpProxy, on our path to Csla 6. We're at 5.4.2 right now. On .Net Framework 4.7.2. One thing I'm seeing right away is that both BusinessException & InnerException are null on the DataPortalException. I can see there's string containing the type name of the actual exception we threw on the server. I thought I saw that exceptions just don't flow over httpproxy, is that correct? Are we going to need to look at that string property to figure out what actually happened? Or is there something I'm doing wrong perhaps that would get exceptions through? |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 8 replies
-
That doesn't sound right...exception should flow across. That is the whole point of a DataPortalException. The only thing I've seen related to this (it's been awhile so forgive me if I'm not remembering this correctly) is that .NET SecurityException does not flow. It acted differently than other types of exceptions. So I stopped using that type. I had tried inheriting from SecurityException for my "LoginFailedExceptions". But I ended up simply inherting from System.Exception after noticing that weird behavior. |
Beta Was this translation helpful? Give feedback.
-
Actual exception types do not flow through Instead look at the |
Beta Was this translation helpful? Give feedback.
-
Hmm, so I might have been responsible for that. CSLA 6 is different in some ways, for the reasons of better security. I'm not exactly clear from your text if you are finding a problem on 5.4.2, or 6.x. I thought the changes I made were in 6.x, because they were potentially breaking changes. If it's 6.x, then read on. Flowing exception details to the outside of a server app - e.g. a data portal host - leaves a pretty big security hole. Like, huge. Insanely big. Take, for example, a temporary failure to access a database; the error text usually contains the NAME of the database, which gives an attacker a hugely useful bit of information in crafting a carefully considered SQL injection attack on a system. I wanted the behaviour of 6.x to be to log the details of the exception, ad return a unique identifier that allows a dev/devops/ops engineer to look up the issue from the server-side logs. However, I can't remember if that is exactly what happened; there was a limitation because some hosts do not enable logging by default. However, that was certainly the plan. If your desire is to work out what went wrong, after the fact, as part of fault finding, then enable logging on the server and all is well. If, instead, your intention is to offer different behaviour on the client at runtime depending on what went wrong, then I strongly, strongly, like REALLY strongly, encourage you to redesign your response to support the idea of returning a non-success result as data. Flowing exceptions outside of an AppDomain is a disaster from a security perspective. Flowing a data type that includes an integer/enum value that represents the non-standard behaviour you want to be able to identify is a much better approach. You can change whether exceptions flows across the boundary - but you ALMOST NEVER should. If your intended user audience doesn't work in the bowels of the IT department, then the details of the exception are not useful to them anyway. Most apps are not for IT, they are BY IT, so flowing exceptions is not a great solution. The exception is not useful to a non-IT user, but is VERY useful to an attacker. We have tried to make CSLA 6 secure by default. CSLA 7 goes one step further to ensure it - unashamedly, but with careful consideration of the consequences. Prior to that, the security decisions were made based on less recent security tenets. Security is an ever moving target, and we have to try to do the best by the developers who use the platform, no matter their experience. Sorry, not sorry. But still sorry, nevertheless! This wasn't an idle decision, but very carefully considered and discussed. |
Beta Was this translation helpful? Give feedback.
-
This is quite a hard thing to explain at a distance, but bear with me. There are two separate ideas that can easily be mixed up in development as a whole:
It is easy to expect to deal with the second by catching exception types in catch statements. However, to do so would be to slightly fail to appreciate the definition of the service contract of the thing being called. The way to define a contract for scenario 1 is to return a type, T. This is what we do every day. Rather than changing our client-side behaviour on an exception type, we should instead change it based on ResultCode (or whatever the property name is that Exceptions can - and almost always do - leak unintended details that are useful to people who want to attack our system. Quite a lot of work has gone into .NET 8 (not CSLA 8, but .NET itself) to standardize how developers see I think the exact implementation of I hope this makes some sense. Like I say, this is a change in the way we traditionally think - are used to thinking, but it is a valuable one. Failure IS an option, and we should program for it - and not with an exception. |
Beta Was this translation helpful? Give feedback.
-
That's enough theory. Back to what this means in practice. CSLA - even CSLA 8, can't make use of However, we can use the idea of what For a CSLA editable type called Customer, we could add a property called ResultCode, which exposes whether the data portal operation succeeded or failed - in our own definition. That property gets set during our data portal operation to a value that defines whether the operation succeeded or not. Often, this will happen in the catch statements of a try/catch in our data access method. What we end developers - users of CSLA - could do, is create an interface - let's call it IResults - whose only purpose is to define that same ResultCode property. We can then have Customer implement IResults. Furthermore, there is a way to add this via inheritance - defining a base type in you solution that inherits |
Beta Was this translation helpful? Give feedback.
Actual exception types do not flow through
MobileFormatter
. The ability to flow exceptions was always quirky, even withBinaryFormatter
and NDCS, and it became more complex over time with modern .NET, and types that may or may not exist on both sides of a remote connection.Instead look at the
ErrorInfo
andBusinessErrorInfo
properties onDataPortalException
. They are intended to provide access to the full exception tree, but in a way that doesn't rely on the .NET type system - so it works reliably across remote boundaries where the same types often can't exist.