I'm not sure this solves the problem Rick... partially it does...

As Paul pointed out, the cancel function itself is a legitimate case. In that situation, you wouldn't want the form to be populated (you wouldn't care if it was or wasn't I suppose, but ideally why bother doing the extra work?) and you wouldn't want validate() to be called because it might reject the request when it shouldn't...

For example... say I have a 3-page wizard flow. After each page I stick the entered values in session. On the third page I have the capability of clicking cancel. When this occurs, I'm going to want to clear out the stored values from session. Imagine that the last page *also* has some entry fields that are usually validated, and let's say one of them is required. If the user clicks cancel, whether you call validate from the Action or not, the user is forced to enter a value just to get past validation, even if they click cancel! The UI would appear broken to the user, and rightly so.

Now, you may say that "yeah, but I would call isCancelled() before I do the validation", and indeed, that would make the UI work as it should. The problem though is that you will have to remember to do that check IN EVERY ACTION, or risk having a similar UI issue elsewhere. It's just extra code you have to copy-and-paste, or have your own base Action class to extend from.

I agree, if everyone did as you suggest this issue wouldn't be as severe. In fact, you would take care of the security issue (assuming *every* Action called validate()), but you would trade it in for a broken UI mechanism anytime the cancel button was involved. Not as big a deal, but still not the best answer :)

Frank

Rick Reumann wrote:
All of this just adds *ONE MORE REASON* to my list of *NEVER EVER* use validate="true". I always call validation manually from my Action class and the sooner people get into a habit of this the way better off they will be. If you validate or call the form's validate method manually from your Action class all these problems go away including the problem we get posted here on the list at least a couple times a week concerning list items going out of scope when validation fails. Validating manually also solves the problem Paul addresses as form validation ALWAYS takes place.

I think the bug is sort of in validate='true' :) I think that should just be dropped and when people need to validate they just call it from their Action class.
http://www.learntechnology.net/validate-manually.do

The code is this simple to add:
ActionErrors errors = form.validate( mapping, request );
        if ( errors != null && !errors.isEmpty ) {
            saveErrors(request, errors);
            setUp(request); //preps request for lists and stuff
            return (mapping.findForward(UIconstants.VALIDATION_FAILURE));
        }

You could even add that to a utility method so it's just one line of code.

Now you have either one line of code in your Action or one line of code in your ActionMapping, yet the first scenario solves all these problems.

(side note, I don't even really like using the validator so I don't even call form.validate() but call a validation method in my action class that does my validation, but I know most like to use the validator so I'm showing how easy it is to call manually).


Frank W. Zammetti wrote:
Rick Reumann wrote:
Maybe I'm missing how the above would happen. How would passing in the canceled parameter end up getting them access to a table? Oh wait, maybe this is with regular Actions with just an execute? It's been so long since I used a non Dispatch Action I'm not aware of the behavior. So I have an Action called "GetMeATable" with an execute method that returns a table from the db, if I pass in through a get parameter the canceled param it will still execute that action?

Right, ordinary Action we're talking about. All Struts does is put a request attribute in place to indicate the Action is being canceled. It then goes on to populate the form, but *NOT* call validate() on it. So, the problem arises if your Action doesn't check for the canceled attribute and validate() is meant to stop a given request (as in my scenario where it was checking for one of the allowed table names).

As I Wrote this, I see that Paul responded and said it's a problem with DispatchActions too, and I think he's right. In fact, his response sums up my own pretty well :)

Even if the above is true, I'm not so sure that's a big deal as far as Struts goes in regard to it being a 'security problem with Struts'. You can always find a ton of security loop holes if you don't truly check that the logged in user has access to some backend procedure. For example if you have an update dispatch method or an "UpdateAction" you could easily type in the url someUrl?dispath=update&id=42&whatever=something etc and have it go through and be processed.

Well, let me put it this way... if I worked for Microsoft, to me at least, this would be a non-critical bug. Patch it on the regular second Tuesday of the month cycle :) But I *do* think it is a bug (a logic bug in this case) and *is* a security hole, even if arguably a small one. Your absolutely right though, there are far more severe security holes that a developer can open up without help from Struts :) I don't think that should make anyone less interested in plugging this one though.

Bottom line is if security is an issue, no one should ever rely on the validate method. That's just silly. I'm sure the docs even state that the purpose of the validate method is to just validate data entry (required fields, no Strings in number fields, etc.).

But, how someone defines "data entry" can come into play... for instance, in the scenario I described, selecting a table, from a select say, would count as data entry, wouldn't it? Try this... let's say we're talking about a *REALLY* bad developer and for some reason he has a *TEXT* field for entering the table name, and then goes on to check if it is an allowed value in validate(). Stupid design, in the extreme! But an improper use of validate()? Probably not (debatable at least).

Let me try and come up with a better example...

Let's say my bank's web site allows me to have a primary user account, and I can link to this account all my checking accounts and savings account to see them all in one "dashboard" display. I have to fill out a form to have an account added. The form has account number on it.

Let's say one of the validations is to be sure the checksum of the entered account number matches one that would only be valid for me. It's a relatively simple math check, so it's done in validate() because really we're checking that the entered value is "valid".

Now, the Action behind it calls some DAO to add the account for me. But, it reasonably assumes that the data it gets in the form is valid. So, if validate() is not executed, I could conceivably enter an account number that isn't mine and have it attached to my user account and see its details.

None of this sounds especially out of the ordinary to me (I work in the financial industry), and I can certainly see where some developers would do it exactly this way (assuming my mythical checksum thing were real- I've never seen that though). I doubt too many people would say it's a "wrong" approach (we could of course argue architecture, that's always the case, but nothing stands out as patently "wrong" to me about this design).

Yea there are plenty. I remember someone on the list here a while back came up with this pretty cool scheme to mask dispatch action method names. It was pretty cool even though I never needed it. If I remember correctly, it acted sort of like the token mechanism - a random string was created before going to a page and that string was decoded on the server side into finding the proper dispatch method to call. To me it's just much simpler to make sure you validate the user logged in really can do what they are attempting to do somewhere on the server side or with filters.

I think the problem here though is that this is a fairly subtle thing, and something that could possibly be exploited in such a way that the request looks legitimate, and in fact is, as far as the filters and security checks go, but are not in terms of the logic of the application.

I don't want to blow this out of proportion... I think the way most people architect their solutions, this probably wouldn't be a problem for most people.

But, even if we all agreed that it wasn't a security problem per se, it just logically does not make sense as far as I can see... if Struts is going to populate the form, I can't think of a good reason it wouldn't call validate() too, like any other request, just because the action was canceled. Like I said, maybe someone can come up with a reasonable explanation for that behavior, but I can't see it :)



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]





--
Frank W. Zammetti
Founder and Chief Software Architect
Omnytex Technologies
http://www.omnytex.com
AIM: fzammetti
Yahoo: fzammetti
MSN: [EMAIL PROTECTED]

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to