Re: Can't send back null class reference as SOAP Header?
- From: "Joseph Geretz" <jgeretz@xxxxxxxxxx>
- Date: Fri, 23 Feb 2007 01:43:32 -0500
Hi John,
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.
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.
Joseph, Joseph, Joseph.
It sounds like your service is stateful. I thought we had agreed you
wouldn't do that anymore... ;-) ;-) ;-)
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! ;-)
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!
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.
If they then retry the request, the flag won't be sent, will it?
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.
What if you decide to revoke authorization?
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.
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.
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.
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.
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?
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
sending back a null instance of the class from the server. In my initial
attempt, this didn't work. I found out that setting the class on the server
to null resulted in no header transmission (seemingly) which had the effect
of leaving the header in place at the client. I am merely requesting whether
it is possible to blank out the header at the client by setting the class
instance to null on the server. Of course, a workaround I can use is to
simply blank out all fields in the class I use to represent the header on
the server, which results in the header being sent back to the client which
results in the fields being blanked out at the client. However, simply
sending back a null class instance would be more convenient way of killing
the header. (Within the software that is. If the user has written the value
down on a post-it note I just don't have the technical means of effecting an
erasure.)
BTW, I've implemented a variety of stateless applications very successfully
in the past using IIS/ASP, MTS and COM+. I appreciate the advice which you
provide, but when you get into basic fundamental concepts regarding
stateless architectures, I'm as familiar with these issues as you are.
Although the medium of Web Services differs in detail from ASP, the concepts
remain the same. The SOAP header is roughly equivalent to the HTTP cookie.
I'm just curious about a few technical implementation details.
Thanks for your advice,
Joseph Geretz -
"John Saunders" <john.saunders at trizetto.com> wrote in message
news:%233F41FuVHHA.4764@xxxxxxxxxxxxxxxxxxxxxxx
"Joseph Geretz" <jgeretz@xxxxxxxxxx> wrote in message
news:%232NRN4sVHHA.3500@xxxxxxxxxxxxxxxxxxxxxxx
Hi John,
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.
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.
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.
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.
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!
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.
What if you decide to revoke authorization?
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.
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.
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.
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.
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.
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?
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
.
- References:
- Can't send back null class reference as SOAP Header?
- From: Joseph Geretz
- Re: Can't send back null class reference as SOAP Header?
- From: John Saunders
- Re: Can't send back null class reference as SOAP Header?
- From: Joseph Geretz
- Re: Can't send back null class reference as SOAP Header?
- From: John Saunders
- Can't send back null class reference as SOAP Header?
- Prev by Date: Re: Can't send back null class reference as SOAP Header?
- Next by Date: Returning Dataset or Datatable via Web Service
- Previous by thread: Re: Can't send back null class reference as SOAP Header?
- Next by thread: .net client not getting a response from java web service
- Index(es):
Loading