Expand my Community achievements bar.

Dive into Adobe Summit 2024! Explore curated list of AEM sessions & labs, register, connect with experts, ask questions, engage, and share insights. Don't miss the excitement.

Flex - WebServices Security Problem

Avatar

Level 2
Producing a number of applications using Flex , FDS and
WebServices but have a security hole.



using FireFox and a Plugin called TamperData you are able to
see and tamper with the data before it is encrypted,

and sent to the webservice.



e.g. an application pulls in the users username from the
surrounding environment (portal),

and requests that user's (bob) information from a web
service, but before the request is sent

bob can tamper with the outgoing SOAP message and request
someone elses information.



Does this make sense ??
6 Replies

Avatar

Former Community Member
The solution is simply to lock down the WebService so that
only authenticated

users can request information.





Avatar

Level 4
Peter, I'd assume that if the data was in any way sensitive
enough to worry about that, then the service would already be
locked down for authenticated users only.



But I think the point at issue here, is even once
authenticated, if the username is an actual parameter passed to the
Webservice, the same problem will still exist, except now the user
will need to be authenticated before they can see other peoples
data.



As far as I'm aware (I'd like to be wrong) but since
WebServices usually just POJOs, they lack the normal request
information something like a Servlet can access, i.e. who is
calling me, what IP are they on, what agent made the request.



In my humble opinion, there is no "simple" solution to this
security issue. I'd really love to be wrong though.



One approach I can think of is sticking to purely using
webservices, and making it so that every client generates a digital
key pair, then transmits the public portion to be stored on the
server. In each request, they must then sign some parameter for the
webservice with their private key. Then at the server, the public
key for the username requested is used to decrypt the param, and if
it decodes to the expected value the service can send the data.
Now, the user would not only have to know someones username to
tamper with the call to the webservice, but would also have to have
the other persons private key.



I imagine the overhead and developer time would be pretty
high, but it would at least prevent them from tampering with the
soap request to ask for someones private data.



The other way might be to route requests via a servlet, and
check the username authenticated with the container matches that in
the request, and then only relay the call if it does.



edit (note): I'm basing this on my experience of WebServices
on Jboss 3.2, where the container takes care of the authentication,
then calls a POJO. I believe on .NET and maybe some more recent
Java app servers it may be possible to query the authenticated user
within a web service method. edit: actually, it seems that this is
possible on most platforms, I'd just completely forgotten about it
was no good for my requirement that the container managed and
cached authentication rather than check credentials on every
request.... also you could just use a password stored on the server
which you check with every request instead of a private key system
as i mentioned, that is almost certainly overkill.

Avatar

Level 1
Gary, you have a Web Service with authentication enabled for
it? yes?



Are you using Java? Axis? if it's .Net and C# its out of my
domain knowledge so I'll only talk about the java/axis.



You can get the actual httprequest from axis via some
threadlocal capable object (I can try to help with that if you need
to).



From the httprequest you can do getUserPrincipal which will
have the http authenticated user. The model you have designed is
riddled with security issues. You should be using the
getUserPrincipal to pull the user that was authenticated via http
instead of relying on the Flex application to tell you which user
is making the current request.

Avatar

Level 4
bdeen, I wish I'd know that earlier, thanks for telling me. I
just didn't know where to start looking as I'd made all my web
services using the wizards in eclipse and hadn't known where to
start. I'd assumed I would need to get that information from JBoss
somehow and couldn't find it anyway, but querying axis for it makes
perfect sense.



Looks you can also get the SOAP header information which I'd
been banging my head trying to find too. Do you know if the
org.apache.axis.MessageContext.getCurrentContext() is the right
method to use inside my web service class?

Avatar

Level 1
Robert,

If you are using Axis then yes I believe you have the correct
class. It should be a threadlocal implementation. If however you
are using the jboss-ws implementation and java 5.0 then you can do





@Resource

WebServiceContext wsCtx = null;

to inject the webservicecontext which will allow you to
retrieve every object you would need.



So you first need to find out if you are using the jboss
implementation or the Axis implementation of web services.



then it should be fairly easy from there, i believe the
WebServiceContext has a getUserPrincipal.



However, if you need to get a user or identify a role I would
suggest the following way



Place your actual logic in a SLSB on the backend (Or use a
SLSB as the WebService backend), and use the SessionContext, I
would also but a restriction on the bean itself with a role that
the user should have. that way if you have a common user versuses
an admin user you can identify the methods they can call or should
be allowed to call.



Here's a small JEE5 Java 5 example



@Stateless // the type of JEE Bean it is

@Local(ExampleLocalService.class) // identifies a local
interface to pull off of JNDI

public class ExampleLocalServiceBean implements
ExampleLocalService{

@Resource // injected resource, the app server should know
where to get this and be able to set this.

private SessionContext sessionContext;



@RolesAllowed( "WebServiceUser" )

public void doSomethingCommon(){

Principal loggedInUser =
sessionContext.getCallerPrincipal();

System.out.println(loggedInUser.getName());

}



@RolesAllowed("WebServiceAdmin")

public void doSomethingAdmin(){



Principal loggedInUser =
sessionContext.getCallerPrincipal();

System.out.println(loggedInUser.getName());

}





}

Avatar

Level 4
That information is really handy, thanks.



All my future projects are likely to be JEE5 and I'm working
through some books on the subject at the moment.



The projects I've done so far made use of Livecycle 7 on
JBoss 3.2.5, which as far as I'm aware doesn't have a jboss-ws
implementation as it's based on the J2EE 1.3 standards.




http://wiki.jboss.org/wiki/Wiki.jsp?page=WebServiceStacks



I may well rewrite one or two methods in some of those
services now I know an easy way to get the authenticated user in an
axis method, so many thanks again for the tips.