all groups > dotnet web services > february 2007 >
You're in the

dotnet web services

group:

Can't send back null class reference as SOAP Header?


Can't send back null class reference as SOAP Header? Joseph Geretz
2/21/2007 9:07:26 PM
dotnet web services:
We use a Soap Header to pass a token class (m_Token) back and forth with
authenticated session information. Given the following implementation for
our Logout method, I vastly prefer to simply code m_Token = null in order to
destroy the session token when the user logs out. However, I'm finding that
setting class instance to null results in no header being sent back to the
client, with the result that the client actually remains with an
authenticated session token even after logging out.

I've worked aroudn this by coding statements to explicitly blank out every
member variable, however I'm not happy with this approach since it's less
maintainable; every time we add a new item to the Token we'll need to worry
about explicitly blanking it out at session termination. Is there any way to
send back a null class reference to destroy the token entrirely?

Thanks for your advice,

- Joe Geretz -

[WebMethod]
[SoapHeader("m_Token", Direction = SoapHeaderDirection.InOut)]
public void Logout()
{
try
{
m_AppCache.Remove(m_Token.SID);
}
catch
{
}

// m_Token = null;

m_Token.SID = "";
m_Token.UID = "";
m_Token.UserName = "";
m_Token.UserPWD = "";
m_Token.Dirty = false;
}

Re: Can't send back null class reference as SOAP Header? John Saunders
2/22/2007 1:14:24 PM
[quoted text, click to view]

Joseph, it's up to the server to decide whether a particular token is still
authenticated or not. Consider that even if you managed to send a "blank"
token to the client, a malicious client could still hold on to the token you
had sent earlier.

You need to have something like a table of valid sessions, and when you log
out, you need to remove your token from that table. Then it doesn't matter
whether or not the client sends you a previously-valid token: it's not valid
any longer.

John

Re: Can't send back null class reference as SOAP Header? Joseph Geretz
2/22/2007 5:10:44 PM
Hi John,

[quoted text, click to view]

This substantially reflects what we are doing. However, to make cache
expiration transparent to the client, we keep enough information in the
token to reauthenticate the session when a token comes in with no
corresponding entry in the server-side session cache.

We send back a flag via the SOAP header when this occurs. It's up to the
client to decide what type of time out security they want to implement.
Ultimately, if the client chooses not to enforce idle-timeout security, our
application server is OK with that. We expire the session cache on the
server to conserve resources, however we recreate it on the fly when the
next transaction comes in from a previously authenticated client.

From a security perspective, I don't see any difference in sending
information once (at login) vs sending the same information back and forth
thousands of times. If the wire is secure, then there's no problem. If the
wire is not secure, then the information is at risk regardless of whether it
is simply sent at login time or whether it is sent with every transaction.

[quoted text, click to view]

Is this really an issue? A malicious client might do anything, once a
session has been established. A malicious client might simply not log off
altogether. Or a malicious client might collect user information and use it
later on in a malicious way. Ultimately, it's going to be up to the users.
If they use our application to interact with our web services, then they
won't have any problem. On the other hand if they use some other system to
interface with our application services, then they need to either trust that
software client, or not use it.

I'm still wondering how to kill a SOAP header. Can it simply be nulled out
of existence, or does all of its data need to be reset to empty values once
the header has been created?

Thanks,

Joseph Geretz

[quoted text, click to view]


Re: Can't send back null class reference as SOAP Header? John Saunders
2/22/2007 7:27:52 PM
[quoted text, click to view]

You have just described what would happen if the token were intercepted by a
hacker and replayed a month later. I hope you eventually expire the
credentials you've stored in the token, otherwise a hacker will be able to
impersonate your users forever.

[quoted text, click to view]

Joseph, Joseph, Joseph.

It sounds like your service is stateful. I thought we had agreed you
wouldn't do that anymore... ;-) ;-) ;-)

What happens if the client doesn't receive the response containing the flag?
If they then retry the request, the flag won't be sent, will it? Then that
flag had better not be important!

[quoted text, click to view]


What if you decide to revoke authorization?

[quoted text, click to view]

Except that it's thousands of times more at risk if you send it thousands of
times. This is the Internet. Assume the presence of hackers.

[quoted text, click to view]

Someone, either your users or some hacker, will do every evil thing you
permit them to do. If you don't want them to do evil, then don't permit them
to do evil. You're making it easy for them.

[quoted text, click to view]


Kill it how? Once you've sent it, it exists. Imagine a client program which
simply saves the SOAP header to disk. How would you "null" that out?

It's a whole big different world out there. It's quite different from
"client-server", COM, RPC, etc. You are not in control like you used to be.
This takes getting used to.

This is one of many reasons that I strongly encourage the use of stateless
web services. It requires any of us who were used to stateful client-server
interactions to immediately reset our assumptions. Without the Big Reset,
you're going to be losing your assumptions one mistake at a time, over the
course of several years.

I'd almost go as far as to say, "if it seems familiar, then it's probably
wrong". Almost, but not quite.

John

Re: Can't send back null class reference as SOAP Header? Joseph Geretz
2/23/2007 1:43:32 AM
Hi John,

[quoted text, click to view]

You're avoiding the issue. What if the login credentials were intercepted
and were used a month later to log in? It's the same issue. This is an issue
which must be addressed by wire security.

[quoted text, click to view]

John, John, John, we've been over this already. No, the server is stateful;
services themselves are stateless. State is maintained on the server (no
different than being maintained in the database, really) the token
transports the key to the state and it marshals between server and client
and back again. Thus, the client actually maintains the key to the state
which is maintained on the server. There's nothing 'stateful' about this, at
least in the sense of statefulness which would be detrimental. Note also,
that in-memory state represents metadata which describes the user in
general, not the state of transactions which the user is performing. The
only state which is being persisted in the server cache, reflects
information which is already in the database, simply being cached in memory
for performance reasons. It's like an in-memory database. I know state is
'evil' but you're not suggesting we scrap our application database are you?
After all it maintains state! ;-)

[quoted text, click to view]

The flag isn't important at all. The flag would direct the user interface
that data may have changed on the server (e.g. user profile information) and
so a nimble UI will refetch that information and adjust itself accordingly
(for example, disable certain buttons at the UI) however, ultimately this is
not important at all. Since all application security enforcement is done on
the server, if the UI isn't properly enforcing security what will result
will be an *inconvenient* experience for the user; however security as far
as the application itself is concerned cannot be breached since the
information on the server will always be up to date and will be used to
enforce security on every transaction. So we can play all the what if
scenarios we like regarding the client application, which after all, under
the best conditions might have any sort of bug in it which would prevent if
form applying the proper security policies for the current user at the UI.
However, as long as the application functions properly on the server,
problems at the UI client won't affect the integrity of the application.

[quoted text, click to view]

This is not correct. The header is defined as Direction.InOut on every
application method (except login of course). The way it works is that the
Server sets this flag to True. It's up to the client to detect this flag, do
what it needs to do and then set the flag to false. So until this happens,
the flag is travelling back and forth unchanged. the most sophistication
client will check the flag after every transaction. A less sophisticated
client might only check this flag when entering a new application mode. A
poorly designed client might never check this flag at all. In this worst
case, this would result in a lousy user experience, but as described above,
would not compromise the integrity of the application on the server at all.

[quoted text, click to view]

Not a problem. We've taken this into account with our design. As I
described, recreation of the cache involves the 'behind-the-scenes' login;
the same login function which is used for a manual user login. So revocation
of a user's credentials involves deactivating the user in the application
database, finding an active session(s) in the cache if the user is currently
logged in, and removing that session(s) from the cache. On the next
transaction, the session won't exist. The first thing that will happen is
that the credentials in the token will be used to attempt a login. This
login will fail, case closed, the user is done for and that's the end of the
story.

[quoted text, click to view]

Either you're transmissions are secure or they aren't. If you're using
128bit encryption (which we intend to use for internet deployments) no one
is going to crack this whether the information is sent once or whether it is
sent a thousand times. What you're saying is, that when I do business over
the internet, each transaction is successively riskier that those preceding
it. I don't see it that way. If SSL is in place, then the transaction is
deemed to be secure. If not, then Amazon is going to be out of business.

Ultimately, if secure wire protocol is in place, and the server environment
is under my control, then the only point which can be abused is at the point
of origination - this is the end-user himself. But the header doesn't
contain any information that the user didn't enter himself in the first
place! So your concern about the end-user abusing the token, is tantamount
to being concerned that someone will abuse their own password. OK, I won't
say that that's not a concern. But it's not my concern.

[quoted text, click to view]

Let's just get the terminology straight. Before the first transaction, the
class whch represents the header via the proxy at the client is null. Once I
send back the header, this class is instantiated by the proxy to represent
the information in the header. If I send a value of 'asasdafsdf', I can
'kill' it by sending '' on the next transaction. (Of course, the user could
have saved the original string to a jump drive, they could have written it
down on a post-it note, they could have disclosed it to their mother-in-law,
or written it a hundred times on the blackboard - whatever. None of that is
the point.) What I've done is 'killed' the original value of 'asasdafsdf' by
overwriting it with ''. What I'd like to find out is whether the entire
class which represents the soap header can be killed in one shot by simply
AddThis Social Bookmark Button