IMHO, Struts already provides a solid framework for developing thread-safe, secure web apps. At the end of the day, developers need to understand and adhere to basic security and concurrency best practices. I can, however, offer one idea that is essentially an extension to the J2EE spec:
Struts apps running under 2.3-compliant containers (e.g. Tomcat 4) can use J2EE container-managed security to protect URIs. However, the spec only provides support for role-based access control. Most real apps require method+data-level authorization control, leaving us to develop external "authorization services" or application-based security of some kind. What would be interesting to add to Struts would be container+framework-managed method+data access control for Actions. What I have in mind here is something like the following. Extend the Realm concept to carry along a list of user attributes to be used for Action authorization. These could just be the all the columns other than userCred and userName in the userTable in a JDBC Realm, for example. Then support "authProperty" and "realmProperty" attributes in Action declarations that force a check of form bean data against user attributes in the Realm data source before the action is invoked. For example, the Action declaration, <action path="/transferFunds" type="com.big.bank.MoveMoneyAction" name="transferForm" authProperty="accountNumber" realmProperty="acct_num" scope="request" input="/transfer.jsp"/> would force the accountNumber property of the transferForm to be checked against the "acct_num" in the Realm data source before MoveMoneyAction.perform() is invoked. To handle the more general case in which the realmProperty is a list (e.g. a list of several accounts associated with a principal), a more complex setup would be required, but the basic idea of checking form bean fields against user properties still applies. I am a Struts newbie with experience limited to 1.0, so the ideas above may not be expressed in the best "Struts way"; but I think that the basic concept deserves consideration. Apologies if this has already been considered and rejected. I didn't see much in the archives on authorization... Craig R. McClanahan wrote: > > > On Mon, 1 Jul 2002, Jing Zhou wrote: > > > Date: Mon, 1 Jul 2002 14:41:25 -0500 > > From: Jing Zhou <[EMAIL PROTECTED]> > > Reply-To: Struts Developers List <[EMAIL PROTECTED]> > > To: Struts Developers List <[EMAIL PROTECTED]> > > Subject: Re: Security issues with Struts > > > > I believe Struts have provide a basic mechanism to resolve > > the problems associated with the multiple submits. But when > > considering this in a security issue context, we might have rooms > > to enhance the mechanism - here is my little thoughts: > > > > 1) Since the transaction token is visible by client browser, users > > could use the same token to cheat Struts by a client program. > > > > A snooper could make the initial submit for a particular form (if they > could get it in faster), but couldn't do much else. However, the security > implications of exposing the session id are *much* more serious than > exposing the transaction token. If data exposure is an issue, use an SSL > connection. > > > 2) Even though request scoped form beans plus a transaction > > token make Struts thread safe, but I observed developers still make > > mistakes by assigning attributes from the request scoped form beans > > to their own version of session scoped java objects, which is > > possibly participating in a transaction from the previous request. > > Any non-trivial application have session scoped objects, so this > > is very likely to happen in general. > > > > I'm not sure what a framework can do about this in any general way. Do > you have some specific suggestions? I fear that just "single thread all > access to the session" is going to cause more problems than it would > solve. > > > 3) The session scoped form bean plus a transaction token may not > > work correctly all the time: Before the first request reach the > > statement isTokenValid(request, true), the second request might > > already corrupt the session scoped form bean by populating bad > > data. Therefore it corrupts the transaction state of the first request, > > if the form bean is participating in that transaction. > > > > Session scope form beans are already susceptible to problems of > simultaneous access, even without taking transaction tokens into > consideration. That is why request scope form beans are generally > recommended. > > > Here are what I am doing in our own project and hopefully it > > will help Struts: > > > > We created a client transaction context (relative to EJB server) > > which manage both JDBC connection based transaction and JTA > > UserTransaction based transaction. In our own version of the > > RequestProcessor, we detect the transaction context before > > populating the form bean. If an active client transaction context > > found in the HttpSession, there are two choices, let the request > > wait or throw an exception. I prefer the second one, which has a > > consistent semantic with SessionBean defined by EJB 2.0 spec: > > Container will throw exception if there is a concurrent access > > to the business method of the same stateful SessionBean instance. > > In other words, Struts could guard the container in early stage and > > solve the potential problems 1-3, and many bad comments on > > the session scoped form beans will be gone :-) > > > > Is my thoughts valid? Any further thoughts? > > > > Many (maybe most?) Struts based apps don't use EJBs. Is there a way we > could define the semantics of this sort of things in terms of APIs that > Struts could support, that don't rely on them? > > > Jing > > > > Craig > > > > > > ----- Original Message ----- > > From: "Craig R. McClanahan" <[EMAIL PROTECTED]> > > To: "Struts Developers List" <[EMAIL PROTECTED]> > > Sent: Monday, July 01, 2002 11:54 AM > > Subject: Re: Security issues with Struts > > > > > > > There are at least a couple of issues that I can pull out of your > problem > > > description -- here's my thoughts on them. > > > > > > REUSE OF FORM BEANS > > > > > > You only have to worry about reuse of the same physical form bean on > > > multiple requests if you are using session scope to save them in. > If you > > > are using request scope (recommended for performance anyway, > because it > > > reduces the memory load on the server), a new bean gets created > populated, > > > and validated for each request. That still leaves the problem of > > > detecting when the user submits the "same" form twice ... > > > > > > DETECTING MULTIPLE SUBMITS > > > > > > This is a general issue for all web applications, not specific to > Struts. > > > However, Struts provides a solution based on the concept of a > "transaction > > > token" that can be used to easily detect when the user tries something > > > like this. It works as follows: > > > > > > * In your Action that sets up the input form, call the method: > > > > > > saveToken(request) > > > > > > somewhere along the way, before forwarding to the actual page. > > > This records a serial number in the user's session. > > > > > > * When the <html:form> tag actually renders the form, it sees the > > > serial number and generates a hidden field to include it's value > > > along with the rest of your fields. > > > > > > * In the Action that receives the form (after validation), you can > > > call the method: > > > > > > isTokenValid(request, true); > > > > > > to check the token included in the request (if any), and clear the > > > value saved in the session (which is normally what you want to do). > > > This method will return false if there is no token at all in the > > > form, or if the token doesn't match the saved value. The fact that > > > you are resetting the saved value means that it will also return > > > false if the user submits a form, presses stop, and submits it > again. > > > > > > I believe that your session synchronization approach isn't > necessary to > > > deal with the particular problem you've described (although it > might be > > > useful for other application-specific reasons). I hesitate to add > > > something like this to the framework itself, though -- managing > > > simultaneous requests to the same session has such a wide range of > > > possible impacts that I don't think a single simple solution is > going to > > > cover all of the use cases. And using request scope for form > beans covers > > > quite a large subset of the possible impacts all by itself (at the > cost, > > > of course, of having to include hidden variables on your forms for > > > multi-page form beans). > > > > > > Craig > > > > > > > > > > > > On Mon, 1 Jul 2002, Marcel Kruzel wrote: > > > > > > > Date: Mon, 01 Jul 2002 08:46:11 +0200 > > > > From: Marcel Kruzel <[EMAIL PROTECTED]> > > > > Reply-To: Struts Developers List <[EMAIL PROTECTED]> > > > > To: [EMAIL PROTECTED] > > > > Subject: Security issues with Struts > > > > > > > > Hello Struts developers, > > > > > > > > We are now developing an internet banking > > > > application with Stuts of course. > > > > Of course, we are highly concerned > > > > in possible security holes in the framework > > > > (or in the application using the framework). > > > > I believe, there is one, that, when properly > > > > used, can cause some troubles for developers! > > > > > > > > Here it is: > > > > > > > > Imagine a scenario, where user submits a form, > > > > the Struts automatically populate the > > > > form bean and then > > > > the validation of the parameters takes place. > > > > After that, if OK, the perform method is called. > > > > Here, I already know, that the > > > > params were ok, so I write the > > > > transaction to database. The problem here > > > > is the perform method. When precisely at the > > > > moment of perform method call user decides > > > > to submit the form once again (with > > > > different values of course), the form bean > > > > is again populated, and possibly wrong > > > > (not validated) data might be writen to database > > > > (by the first thread, that is not aware > > > > of the second submit). > > > > I am afraid, there is not a possibility to > > > > synchronize acccess to the form, > > > > since the population of form bean is automatic. > > > > > > > > I know, that the solution to the problem here is > > > > in the perform method > > > > to make copy of the parameters and then validate > > > > them again. Or, I can > > > > make validation only in the perform method, > > > > but first I have to remove the > > > > form bean from session, then validate > > > > and then write to database, and then possibly > > > > return that form bean to the session. > > > > > > > > Sorry for so long description, > > > > but I tried to make myself as clear as possible. > > > > > > > > My preferred solution to the problem would be: > > > > In the struts-config.xml put an attribute > > > > to action, describing, that handling > > > > such an action requires session synchronization. > > > > Thus everything, starting from form population > > > > and ending with "return mapping.findForward(...)" > > > > would be synchronized on a session object. > > > > (I do this synchronization on a session > > > > anyway - in each perform method). > > > > > > > > So, what do You think? > > > > > > > > Thanx to all contributors > > > > for such a great framework, > > > > and enjoy the summer. > > > > > > > > Marcel Kruzel > > > > Czech Republic > > > > > > > > > > > > > > > > -- > > > > To unsubscribe, e-mail: > > < mailto:[EMAIL PROTECTED] > > > > > For additional commands, e-mail: > > < mailto:[EMAIL PROTECTED] > > > > > > > > > > > > > > > > > > -- > > > To unsubscribe, e-mail: > > < mailto:[EMAIL PROTECTED] > > > > For additional commands, e-mail: > > < mailto:[EMAIL PROTECTED] > > > > > > > > > > > > > -- > > To unsubscribe, e-mail: < > mailto:[EMAIL PROTECTED] > > > For additional commands, e-mail: < > mailto:[EMAIL PROTECTED] > > > > > > > > -- > To unsubscribe, e-mail: < > mailto:[EMAIL PROTECTED] > > For additional commands, e-mail: < > mailto:[EMAIL PROTECTED] > > -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>