If you'd like this moved to the developers list, just approve my application and reply there.
> When I say that MD5 is the default that applies only to the case that > a hmac_key is not specified. This is 1) for backward compatibility; 2) > because without a key/salt sha512 and md5 are vulnerable to the same > dictionary attacks. Hmm.... Well, I'm looking at the CRYPT class and it appears that in order to use HMAC the *caller* needs to pass in the key parameter. Grepping the source tree I've found a few places where the caller does not supply the key: applications/admin/models/access.py:55 applications/admin/controllers/default.py:78 gluon/main.py:480 gluon/main.py:495 gluon/validators.py:2344 I am of course unfamiliar with the internals of the project, but it would appear to me that admin passwords are never HMAC'd. Can you confirm? I suggest that the key be pulled in from the configuration inside CRYPT so that the caller isn't required to pass it in. I would also suggest that the hash method be placed in configuration. Consolidating the configuration of security mechanisms greatly aids in a security review. If it were consolidated, a reviewer would only have to look at the default configuration. In it's current state, a reviewer needs to look at all the callers of CRYPT to determine the security of CRYPT. I realize some of my suggestions may prove difficult to support backwards compatibility. In many cases this can be worked around to implement and start using newer, safer security controls while maintaining support for older methods. In some cases it's more difficult than others. > If you use "admin" to create a new app, the '<your secret key>' is > automatically replaced with something like Thanks for clarifying! This works. > > * Do not use cgi.escape for HTML escaping because it does not escape > > single quotes and may lead to XSS - Seehttp:// www.pythonsecurity.org/wiki/web2py/#cross-site-scripting-xss > > and http://www.pythonsecurity.org/wiki/cgi/ > > I assume you refer to attribute escaping. When using helpers like > {{=A(link,_href=url)}} then link is escaped using cgi.escape but url > is escaped differently (quotes are escaped). The problem is that the > escape function does not know whether a variable is to be inserted in > html, css, js, attribute, a string in js, etc. etc. and therefore if > the function does know the context it is in it can never always escape > correcly. I do not believe there is a general solution to this > problem. web2py assumes {{=....}} is escaping HTML/XML. If you need to > scape attributes we suggest using helpers. If you need to scape js > code or strings in js code, you may have to do it manually. That's not quite what I was getting at. You're right about needing the context in order to escape correctly though. I think the default escaping should include single and double quotes. cgi.escape escapes double quotes but not single quotes. I thought that the default escaping was going through cgi.escape by way of the xmlescape method, but given the below, that appears to not be the case. I'm a little confused. Here's an example of something I don't think I should be able to do: Controller: return dict(data='" onload="alert(1);" bad="') View: <body class="{{=data}}"></body> Output: <body class="" onload="alert(1);" bad=""></body> The same attack works with single quoted attributes. While you're right, we can't do full proper escaping without knowing the context, I don't think quotes should be permitted in any web context. > I disagree but probably I did not explain this very well. web2py has > two things it calls session. One is the general session managed via > cookie session_id. One is the authentication session stored into the > general session file. When a user logs out the authentication session > information into the general session is deleted. If an attacker where > to intercept the cookie session_id and try to use it to gain access to > the system, it would not work. The session_id is used for the general > session and it does not expire because when the user logs in again, if > the user had a state stored in the session file, you want that state > to be retrieved. Hmmm. I'll have to ponder this. > As mentioned above the "admin" does this and "web2py -S app" should > too (but there is the bug you pointed out). "admin" automatically sets > the hmac_key="sha512:.....", i.e. defaults to SHA512. Thanks, I understand this better now. What's confusing is that the algorithm could be set by the key or digest_alg params, neither of which the caller need provide. It gets a little complicated to determine what code path will execute because of how it depends on these two params. Like I said before, I'd love to see these be statically set in the application configuration so there is only one algorithm and one key that is used throughout the application, with no requirement for the caller. Best, Craig Younkins On Jun 30, 2:16 pm, mdipierro <mdipie...@cs.depaul.edu> wrote: > On 30 Giu, 12:19, Craig Younkins <cyounk...@gmail.com> wrote: > > > "You may also want to ask some questions about form validation, > > default validators and directory traversal attacks in file uploads. " > > > Good idea. I'll add those. > > > I've reviewed what you wrote on the wiki and some parts of the > > application code, and I have a few preliminary recommendations to > > improve security: > > > * Drop support for basic auth. It's really insecure - http://www.pythonsecurity.org/wiki/basicauthentication/ > > Actually this already disabled by default. You have to enable if you > want to use it. People sometimes use it for web services. > > > * Drop MD5 as the default hashing algorithm, use SHA512. MD5 is now considered 'cryptographically broken' > > When I say that MD5 is the default that applies only to the case that > a hmac_key is not specified. This is 1) for backward compatibility; 2) > because without a key/salt sha512 and md5 are vulnerable to the same > dictionary attacks. In all the other cases...(read next answer) > > > * The HMAC secret is by default '<your secret key>', and I don't see > > anywhere in the documentation how to generate a new one or the > > recommendation to do so > > If you use "admin" to create a new app, the '<your secret key>' is > automatically replaced with something like > > auth.settings.hmac_key = 'sha512:06a78549-cf6c-4767-a847-435541210976' > > The 'sha512' forces web2py to use sha512. This is the normal behavior > for all new applications unless the the "admin" interface is bypassed. > In this case the user has to come up with a unique hmac_key on his > own. > > > * Do not use cgi.escape for HTML escaping because it does not escape > > single quotes and may lead to XSS - Seehttp:// www.pythonsecurity.org/wiki/web2py/#cross-site-scripting-xss > > and http://www.pythonsecurity.org/wiki/cgi/ > > I assume you refer to attribute escaping. When using helpers like > {{=A(link,_href=url)}} then link is escaped using cgi.escape but url > is escaped differently (quotes are escaped). The problem is that the > escape function does not know whether a variable is to be inserted in > html, css, js, attribute, a string in js, etc. etc. and therefore if > the function does know the context it is in it can never always escape > correcly. I do not believe there is a general solution to this > problem. web2py assumes {{=....}} is escaping HTML/XML. If you need to > scape attributes we suggest using helpers. If you need to scape js > code or strings in js code, you may have to do it manually. > > > * Session IDs should time out when the authentication information > > does, and the user should get a new session ID when they > > reauthenticate. This defense will help ensure that even if a session > > ID is leaked, it will only be useful for a limited amount of time. It > > sounds like users always have the same session ID. > > I disagree but probably I did not explain this very well. web2py has > two things it calls session. One is the general session managed via > cookie session_id. One is the authentication session stored into the > general session file. When a user logs out the authentication session > information into the general session is deleted. If an attacker where > to intercept the cookie session_id and try to use it to gain access to > the system, it would not work. The session_id is used for the general > session and it does not expire because when the user logs in again, if > the user had a state stored in the session file, you want that state > to be retrieved. > > Another way to see this is that some application do not use > authentication at all and still they need to use a session to track > users. > > > Questions: > > > "If not key/salt is provided is provided web2py uses MD5, but is a key/ > > salt is provided (and the scaffolding application generates one > > automatically) it uses HMAC+MD5 or HMAC+SHA512." > > > I ran 'python web2py.py -S testapp' but it did not generate a new > > value for auth.settings.hmac_key in db.py. Should it have? > > This is a bug. I just fixed it in trunk. Thank you! > > > It appears to use MD5 by default unless an alternative is specified, > > such as SHA512. > > As mentioned above the "admin" does this and "web2py -S app" should > too (but there is the bug you pointed out). "admin" automatically sets > the hmac_key="sha512:.....", i.e. defaults to SHA512. > > This is a very useful discussion. > > Massimo > > > > > Please feel free to discuss! > > > Craig Younkins > > > On Jun 30, 9:58 am, mdipierro <mdipie...@cs.depaul.edu> wrote: > > > > Hi Craig, > > > > You may also want to ask some questions about form validation, default > > > validators and directory traversal attacks in file uploads. > > > > Massimo > > > > On 29 Giu, 11:08, Craig Younkins <cyounk...@gmail.com> wrote: > > > > > Hello there! My name is Craig Younkins. I'm a summer intern at OWASP, > > > > the Open Web Application Security Project. This summer I'm working > > > > heavily on web security in Python. > > > > > First, I would like to praise Dr. Di Pierro and all the web2py > > > > contributors for their focus on security. Examining the OWASP Top 10 > > > > (http://www.web2py.com/examples/default/security) is a great way to > > > > start. Keep it up! > > > > > Second, I'd like to invite the web2py community over to a site I've > > > > started about security in Python -http://www.pythonsecurity.org. The > > > > site aims to be the central hub for security in Python, and right now > > > > has a focus on web security. Inside there are articles specific to > > > > software like frameworks as well as articles related to security > > > > topics like cross-site scripting. We also have a Google Group (http:// > > > > groups.google.com/group/python-security/topics) which I encourage the > > > > developers to join. There you can get answers to your Python security > > > > questions. I hope you check it out! > > > > > Lastly, I'd like to encourage you to take a look at web2py's page on > > > > PythonSecurity.org -http://www.pythonsecurity.org/wiki/web2py/. I > > > > haven't had the time yet to examine web2py in detail, but on that page > > > > there is a pretty well-defined template of questions to be answered. > > > > Going through the list there will help the developers see areas in > > > > web2py that could use improvement, as well as documenting the > > > > strengths for other frameworks to model off of. > > > > > Thanks! > > > > > Craig Younkins