Forum OpenACS Q&A: Re: Thanks for ETP 2

11: Re: Thanks for ETP 2 (response to 10)
Posted by Jeff Davis on
style has the same problem as img in that you could have a background image in the style attr which fetched a page that took some action. The reason you worry about img src is that unless you have a really paranoid admin, images are loaded automatically when the page is loaded, whereas a malicious href still needs to be clicked on. Of course if you are a bad guy you could always just have an innocuous looking href do a redirect to the action page as easily as put the malicious link in line.

class I think would be safe if a malicious user can't control the css.

Tom's right that we should be checking for POST for actions, although I think even better is to provide a signed nonce which would be something like "user_id,session_id,form_name,server_secret" hashed which could be used to validate that the POST came from a form actually served to the given user.

Maybe I will look at adding a "nonce" type for form builder which could be used to do this.

12: Re: Thanks for ETP 2 (response to 11)
Posted by Jeff Davis on
Oh, and for anyone interested in the "make someone read an image to do action X" stuff here is a link to the captcha project.
16: signed nonce (response to 11)
Posted by Andrew Piskorski on
Jeff, on using a "signed nonce" to verify that form submissions haven't been tampered with, doesn't OpenACS already have facilities to do that sort of thing? I was pretty sure it did...
17: Re: signed nonce (response to 16)
Posted by Jeff Davis on
Andrew, it does have facilities for signing things, but there is nothing in place to insure that the signed variable sent back is the signed variable sent to the browser.

In ad_form for example the key is signed but the signature says:

<input type="hidden" 
   value="851 0 2D43063DA4AFDC46574E81151ED48C64939CF3AC" />
the 851 is the token_id and 0 is the expire time (does not expire) and the hash is:
ns_sha1 "$value$token_id$expire_time$secret_token"
Now, all you need to do to forge this is to get some other form to sign an integer (any form which lets you enter an integer which is subsequently served back signed would work) since there is nothing there tied to the session or a shared secret or anything like that.

Some ways to fix this would include having a shared secret (a random string in a session cookie for example) or a server side secret which is session specific (pick a token_id for the session but don't send it in the request).

One other thing I realized in looking at this is that as far as I can tell, we don't ever expire tokens which is probably a mistake. We should probably have a token lifetime parameter and sweep expired tokens. We should have