Cross-site scripting (XSS) is a real danger when administrating Drupal sites. Any (contrib) module may have a security bug in it, which allows hackers on the website to add a little script that posts forms with malicious input. But also other users with Full HTML permissions may have a bad intention. Especially when hosting several Drupal sites on the same server, this is a potential risk. Some good examples of dangerous forms that are vulnerable of XSS are the block admin page and the View contextual argument page, in which a PHP setting can be set. Potentially, this PHP code can containing anything; from removing all the sites files to sql dumping the complete database and providing it for download to the hacker. Note that disabling the PHP filter alone does not protect you from this danger; it is relatively easy to enable the module via XSS by posting the module page, as I have found out for myself. This module attempts to provide an answer against this risk for website administrators. It does so by adding a little captcha which is unbreakable by cross-site scripts. Although this module provides great protection for XSS for the forms it is applied to, the captcha can be quite annoying in practice so this module, by default, adds it only to forms that are considered 'risky'.
I have searched for other contrib modules that do the same but found none. Still, I think this is an essential module for websites that need higher protection or that, for some reason or another, can't be updated regularly.
My module is Drupal 7-only, but could be converted pretty easily to Drupal 6. If there are loads of feature requests for this I might give it a go.
Project page: http://drupal.org/sandbox/bvanmeurs/1543016
Git: git clone --branch 7.x-1.x http://git.drupal.org/sandbox/bvanmeurs/1543016.git xssecurity
Unfortunatly, I don't have enough time to do 3 reviews to get a bonus status. But at least I've made one in return:
Viewport module review
Thanks to anyone who wants to take the time to review this module!
| Comment | File | Size | Author |
|---|---|---|---|
| #11 | drupalcs-result.txt | 3.5 KB | klausi |
Comments
Comment #1
ourwayoflife commentedThere are still files other than README.txt in the master branch, make sure to remove them. See also step 5 in http://drupal.org/node/1127732
You also remove the translations folder, translations are done on http://localize.drupal.org as well as remove "version" from the info file, it will be added by drupal.org packaging automatically.
Remove all old CVS $Id tags, they are not needed anymore.
There are other stuffs to clean up. For details: http://ventral.org/pareview/httpgitdrupalorgsandboxbvanmeurs1506718git
Manual review:
* code fully documented (great)
* missing README.txt in the current branch?
* included files not placed inside a folder
Comment #2
musikpirat commentedEdit: Typing to slow, most has been said above. :)
Your git clone url is not usable by onyone except you. Better use this one:
Comment #3
bvanmeurs commentedThanks both!
ourwayoflife, that link is great. I will look into it quickly.
Comment #4
klausiSetting the status accordingly, switch back to "needs review" when you are ready.
Comment #5
bvanmeurs commentedI've fixed the errors displayed on Ventral (very handy site btw!), pushed it to the repo and am awaiting review again. It was an interesting experience that made me realize I wasn't following all coding styles yet.
Thanks for your time!
Bas
Comment #6
eiriksmFirst of all, great idea, beautiful looking code. And it seems to be doing its job. However:
Automated review:
See http://ventral.org/pareview/httpgitdrupalorgsandboxbvanmeurs1506718git
Manual review:
Well, small stuff.
xssecurity.module, line 63 and 72.
I was told in my own project application that page callbacks should be public functions, so you should remove '_'.
xssecurity.module, line 80 and many others:
* Returns TRUE iff forms with the specified form id should be considered risky; returns NULL if the form id is not specified in the settings or known.First of all, this is a long line. But unless you mean another word "iff", then "if" is written with one f. This is done several times in the same file.
I also find it confusing that you can't disable all forms temporarily on the admin page, where you only can disable the actual form you are on right now. Should it not be an option to disable all protected forms for an hour (yes i know i can turn off the module, but still?)
And the default text you have on that checkbox (which also applies to i.e the modules form) says "If you enable this checkbox, all forms with form id %form_id will be unlocked for the next hour.". Is it not an ID because it only is _one_ form with that ID? Should this not be reformulated?
In conclusion
Coming from a fellow project applicant, this a hard thing to do, but I think I have to change the status back to "needs work".
EDIT: Put a link to the automated review instead.
Comment #7
patrickd commented@eiriksm thanks for your participation, but please do not paste these ugly automated reports in here, just provide a link or an attachment containing it. as you can still edit your comment, please short it.
Comment #8
bvanmeurs commentedHi eirksm,
Thanks for your comments! I've changed 'disable all forms' functionality, so that truely ALL XSSecurity is disabled, regardless of the form. I think this is more logical, because if you disable XSSecurity for one form and not for other forms, your website is already theoretically at 'risk' anyway. This method makes it also easier to change the current website.
One question about your comment about page callbacks that have to be public (no underscore prefix). Does this also apply to access callbacks, form callbacks and validation/submit callbacks?
By the way, I've been struggeling with git. Ever since I tried to undo a push with rebase command, I'm getting the following message:
$ git push origin 7.x-1.x
error: Cannot access URL http://git.drupal.org/sandbox/bvanmeurs/1506718.git/, r
eturn code 22
fatal: git-http-push failed
Even when I pull the current version, do a small change, commit and push, I am getting this message. As a consequence, I decided to create a completely new sandbox with the current version.
The new url is: http://drupal.org/node/1543016
Comment #8.0
bvanmeurs commentedChange git clone format
Comment #9
bvanmeurs commentedForgot to set to 'needs review'. I've made the necessary changes and would love to obtain the ability to create a full project!
Comment #10
scot.hubbard commentedHi bvanmeurs,
I have just conducted a review of your module and all I could find were minor coding standards issues (mainly comment line lengths, see: http://ventral.org/pareview/httpgitdrupalorgsandboxbvanmeurs1543016git-7...).
The module installed and uninstalled cleanly and worked very well while installed. All issues already highlighted above appear to have been fixed.
For me this module is RTBC, so I am changing the status accordingly.
Comment #11
klausiReview of the 7.x-dev branch:
This automated report was generated with PAReview.sh, your friendly project application review script. You can also use the online version to check your project. Get a review bonus and we will come back to your application sooner.
manual review:
Comment #12
bvanmeurs commentedThanks Klausi, your comments are extremely helpful.
Note to myself: also provide a form_state 'no_xssecurity' which can be used to disable xssecurity of a form programmatically. And also don't apply the captcha when a form is submitted programmatically (!empty($form_state['programmed']).
Comment #12.0
bvanmeurs commentedChanged the git branch and project url, because of problems with the previous sandbox git.
Comment #13
bvanmeurs commentedHi Klausi,
I've fixed the issues that you mentioned. Except for two:
7. Drupal behaviors.
If I undertand correctly, behaviors were introduced to allow new HTML parts (loaded using AJAX) to be applied to at run-time. This is very handy and logical for statements such as:
$('.example').hide()In my case, this is not a good thing. This is simply be a javascript checking periodically for new XSS attempts using setTimeout, which is started on the document ready event. There's no need to apply this to new html. Therefore, it is not a good idea to add it as a behavior. Please correct me if I'm wrong.
8. #type => value vs #type => hidden
This is not possible. When submitting a form containing a captcha this will lead to problems, because the form builder hook (xssecurity_form_alter) would overwrite the previous captcha (the one that the user has given the answer for) with a new one. Unfortunatly, there is no way at all at this point to find the captcha id of the previous captcha; otherwise we could have chosen to save that id in the form_state and use it later in the validation hook where we check if the captcha anstwer was entered correctly.
In order to be able to find the original captcha in the validation hook, I have to read the $_REQUEST array to get the original captcha id (see xssecurity.module lines 512-521). I had no alternative because of the mentioned problem. Would we use a 'value' input there would be no way at all to get the captcha id, not even using the $_REQUEST array.
I think this is a weakness in the Form API, but it is not something I can solve.
All the comments are fixed. The automatic reviewer gives no messages any more (http://ventral.org/pareview/httpgitdrupalorgsandboxbvanmeurs1543016git). And I've added an option to disable XSSecurity programmatically by setting form_state['no_xssecurity'].
Thanks!
Bas
Comment #14
heine commentedProtecting against XSS is a commendable goal.
The module contains a few flaws, one critical.
A sophisticated XSS payload targeting a user with the permission "administer site configuration" could submit any desired form via the following approach:
- Submit the desired form
- Fetch admin/config/system/xssecurity/xss-attempts and read the correct answer
- Submit the desired form with the answer retrieved
To remedy, generate a new captcha when it is answered. Do not output the correct answer.
In addition:
- Captchas that are answered should be removed from the session to prevent re-use.
- The captcha is too easy IMO (though not tested), it could probably decoded by a JS captcha breaker in a short time.
Comment #15
bvanmeurs commentedHi Heine,
Thanks for your comment, you are absolutely right. The captchas should be removed after being used, by unsetting them in the session.
However, I found a more serious problem. As far as I was aware, it was impossible to read the binary data of an image in javascript. But I found out that the canvas element allows to do just this; basically making the captcha breakable. This means that my method is basically not good enough to secure against XSS.
Also, I lately realised that XSS is still possible by waiting until some form is visited and then secretly setting the form inputs upon manual form submission, rather than posting the form using ajax.
As a matter of fact, I began to realise that there really is no way to fully protect against XSS using this method, so it's probably better to abandon the project.
However..
Would it still be possible to get a full project status so that I don't have to go through the application procedure again? I'm aware now of how to write module code and intend on contributing in the future.
Kind regards,
Bas
Comment #16
drupwash commentedNice and good work. :)
Comment #17
gregglesThis seems like a bit of a weird situation given that you don't plan to contribute this project but do wish to use it for approval.
@bvanmeurs - maybe you would go for the review bonus one more time to finish this off? http://drupal.org/node/1410826
Comment #18
koppie commentedChanging the status to see if @bvanmeurs is still interested in getting this project approved. I think the idea is still a good one - XSS security holes show up in Drupal from time to time and it would be nice to have a module that would help prevent them.
Please clean up your git branches:
Even if you don't intend to submit this module, the git work will help you become a better Drupal contributor. I know it helped me. :-)
Comment #19
bvanmeurs commentedMy approach has changed now, the idea is to no longer check for XSS, but to require the user to re-enter his password when the submitted form is known to be a risky one, such as a block that has the PHP filter turned on.
This approach works but I have no plans to release it as I have given up on ever getting the full project permissions. After several attempts to post a project, someone always seems to pop up another requirement.
Comment #20
klausiProject 1: http://drupal.org/node/1842466
Project 2: http://drupal.org/node/1512124
As successful completion of the project application process results in the applicant being granted the 'Create Full Projects' permission, there is no need to take multiple applications through the process. Once the first application has been successfully approved, then the applicant can promote other projects without review. Because of this, posting multiple applications is not necessary, and results in additional workload for reviewers ... which in turn results in longer wait times for everyone in the queue. With this in mind, your secondary applications have been marked as 'closed(duplicate)', with only one application left open (chosen at random).
If you prefer that we proceed through this review process with a different application than the one which was left open, then feel free to close the 'open' application as a duplicate, and re-open one of the project applications which had been closed.
Comment #20.0
klausiChange the branch according to the review comment.
Comment #21
avpaderno