Add a Page for the Security Checklist in the Admin View
Review Request #4952 — Created Nov. 13, 2013 and submitted
With this review request I fixed a lot of style issues. This includes:
- Making sure that includes are properly alphabetized;
- Got rid of escaped characters by making the string double-quoted;
- Renamed variables so they are more consistent;
- Aligned strings;
- Removed outer parenthesis where they are not needed on tuples;
- Improved some of the user-visible descriptions;
- Added a docstring for SecurityCheckRunner;
- Fixed blank lines;
- Fixed URLs;
- Fixed indentation in the template;
- Moved HTML styling into CSS tags.In terms of actual functionality, I changed the ExecutableCodeCheck test to be able to fail on multiple file types. Before it would end the test on the first failed file type and return that to the user. Now it will return a list of each file type that fails.
I've also included some screenshots to show what various success/failure statuses look like.
Ran through all tests and they succeeded when they should and also failed when they should when I introduced failure conditions.
Description | From | Last Updated |
---|---|---|
Since these names are presented to the user, we should mark them for localization. Basically, at the top of this … |
david | |
This is a good start, but I think we'll want to have this go through a range of different file … |
david | |
In order to be more consistent with python's unit test frameworks, can we capitalize this "setUp"? In unittest, the setUp … |
david | |
And "tearDown" here. |
david | |
This isn't catching any exceptions, and the open() call is leaking an open file. For the open file, you can … |
david | |
Same thing here with localization. Perhaps call this one "Checking ALLOWED_HOSTS setting" ? |
david | |
It's a little confusing to have "result" and "results" here. Can we name these better? |
david | |
I think we're going to want a little bit more complexity in the results than just a true/false value. My … |
david | |
While I think it would be nice to eventually use entry points for this, for now I think just using … |
david | |
This probably doesn't need (and shouldn't have) the admin-dashboard ID. |
david | |
This stuff looks like it was copied from the admin dashboard and can be removed. |
david | |
Please indent HTML with 1 space. |
david | |
I don't think you intended to change this file. Please revert it. |
david | |
No blank space here (both "django" and "djblets" are "third party" with respect to the review board codebase). |
david | |
Add an extra blank line here. |
david | |
Remove this blank line. |
david | |
Remove this blank line. |
david | |
This is pretty good but I'd like to change the first sentence a bit. How about: "A misconfiguration in the … |
david | |
Can we add one additional piece of metadata here for instructions to fix it? For this check, we'd want the … |
david | |
This should probably be `settings.MEDIA_URL + 'uploaded/files/' |
david | |
We should skip saving, tearing down, and the actual tests in the case that the user is using s3 (or … |
david | |
This line looks too long (> 80 columns). There's also some changes I'd like to make to the string. Let's … |
david | |
This should also use _() and string formatting instead of concatenation. |
david | |
Remove this blank line. |
david | |
Once again, we should include instructions for how to fix it (shown when the test fails). This one would say … |
david | |
This string should be marked for translation. |
david | |
This string, too. |
david | |
Remove this blank line. |
david | |
These lines are all indented 4 spaces too many. |
david | |
Add an extra blank line here. |
david | |
Should be in alphabetical order (base before storage). |
chipx86 | |
Two blank lines. |
chipx86 | |
These should just default to None. |
chipx86 | |
The camelCase in unittest is a holdover from early days of Python. We shouldn't duplicate it here. Instead, just call … |
chipx86 | |
And teardown. |
chipx86 | |
When you have to escape a single quote, it's best to just use double quotes for the string itself, to … |
chipx86 | |
Can we call this storage instead of fss? It's a more standard variable name for an instance of a Storage … |
chipx86 | |
Would be better as file_checks. |
chipx86 | |
The strings should all be aligned. |
chipx86 | |
Can you break this into two lines, mimicking the newline? |
chipx86 | |
Parameters should be aligned. |
chipx86 | |
The %s will automatically cast to the string, so no need for six.text_type(e) here. |
chipx86 | |
No need for the outer parens here, as it's one line and the comma will ensure it'll be returned as … |
chipx86 | |
Same here. |
chipx86 | |
Parameters need to align. |
chipx86 | |
Not really worth talking about Django. "That Review Board will consider valid for this server" is probably fine. |
chipx86 | |
Make sure the strings align. |
chipx86 | |
Lots of escaping. Should just use double quotes to solve this. |
chipx86 | |
A quicker way would be: if '*' in settings.ALLOWED_HOSTS: result = False ... |
chipx86 | |
Might be worth expanding on this, stating how it'll respond to any host, and how that's unsafe. |
chipx86 | |
No need for these parens. |
chipx86 | |
Mind adding a docstring? |
chipx86 | |
Blank line between these. |
chipx86 | |
Typically, you'd want iteritems(), since it doesn't make a copy of the list of items. Python 3 renames this to … |
chipx86 | |
The }) should align with all_test_results |
chipx86 | |
Should add a trailing comma. |
chipx86 | |
Two blank lines between things on the top level. |
chipx86 | |
Global variables should be at the top of the file, after the imports. Two blank lines on either side. |
chipx86 | |
"Returns" instead of "Gets" |
chipx86 | |
All one line. |
chipx86 | |
"site_domain_method" should only be indented 4 spaces from protocol = |
chipx86 | |
The widget-* URLs are wrong. This regex should be: r'^security/$' The $ prevents security/adfsfsa from matching. |
chipx86 | |
This should be in alphabetical order, so before reviewboard.admin.supports. |
chipx86 | |
Two blank lines. |
chipx86 | |
Should remove this. It'll actually break some server configurations, as many WSGI implementations don't like random things going on stdout. |
chipx86 | |
The })) needs to align with return. |
chipx86 | |
The URLs above based on views.dashboard are done for legacy reasons, but for this one, you should give the URL … |
chipx86 | |
You shouldn't need this. This was only for the graphs on the dashboard. |
chipx86 | |
So a word on indentation in templates. The content of the template, and the template language itself, are indented separately, … |
chipx86 | |
Need a {% trans %}. |
chipx86 | |
Things like border=1, style=, etc. don't belong. These should be defined solely in the CSS. It's not good to mix … |
chipx86 | |
No spaces inside a variable. {{check.name}} would be correct. |
chipx86 | |
This should be localized, and you can use ngettext (included in django.utils.translation) to do the pluralization. It's also ok to … |
david | |
Two blank lines here. |
david | |
Can you put quotes around the `*? Also, we've already explained why it's an issue in the desc text, so … |
david | |
base_site.html already defines this block to be colM, so you shouldn't need this. |
david | |
I don't think these are necessary, either. |
david | |
This should include {{block.super}} as the first line of the block. |
david | |
We shouldn't have any inline styles, only classes and IDs (all styles here should all be in the admin.less file). … |
david | |
What is this here for? |
david |
-
-
Since these names are presented to the user, we should mark them for localization.
Basically, at the top of this file, add this:
from django.utils.translation import ugettext_lazy as _
and then here:
name = _("Executable Code Check")
I think we may also want to think about a good user-visible name for this. Maybe Christian has a good idea?
-
This is a good start, but I think we'll want to have this go through a range of different file extensions (and file types), instead of just checking .php.
-
In order to be more consistent with python's unit test frameworks, can we capitalize this "setUp"?
In unittest, the setUp and tearDown methods are called by the runner, not by the individual test function. We might want to do that here just to make it fit with prior expectations about this pattern.
-
-
This isn't catching any exceptions, and the open() call is leaking an open file.
For the open file, you can use the file as a context manager:
data = urllib2.urlopen(_get_url(self.directory) + to_download).read() with self.fss.open(to_download, 'r') as f: return data == f.read()
That said, won't the value you get from fss.open(to_download).read() be the same as self.php_file?
-
-
-
I think we're going to want a little bit more complexity in the results than just a true/false value.
My instinct here would be to have one of three "results", either pass, fail, or error (if something went wrong during the check), and instructions (or a link to instructions) for how to fix it if it fails.
We'll probably also want the individual checks to have a description field that can explain to the admin what's getting checked.
-
While I think it would be nice to eventually use entry points for this, for now I think just using a statically defined dict is sufficient.
Something like this would also let you get rid of the (un)register_security_check methods, too (which look unused):
```python
_security_checks = {
'test_check': TestSecurityCheck,
'executable_check': ExecutableCodeCheck,
'hosts_check': AllowedHostsCheck,
} -
-
-
-
- Change Summary:
-
Adding review request to students group.
- Groups:
- Summary:
-
Basic executable file check test completed for WIP review.Security Checklist Project
- Description:
-
~ Basic executable file check test completed for WIP review.
~ Added the rest of desired listed functionality for the project.
+ The test runner runs through the two existing checks. The ExecutableCodeCheck now goes through all the file types that were mentioned. Both tests now return pass/fail status as well as some additional information about why they failed (if they fail). - Testing Done:
-
+ Ran through all tests and they succeeded when they should and also failed when they should when I introduced failure conditions.
-
-
No blank space here (both "django" and "djblets" are "third party" with respect to the review board codebase).
-
-
-
-
This is pretty good but I'd like to change the first sentence a bit. How about:
"A misconfiguration in the web server can cause files attached to review requests to be executed."
I'd also change "The types of files being checked" to "The file types being checked".
-
Can we add one additional piece of metadata here for instructions to fix it?
For this check, we'd want the instructions to link to http://support.beanbaginc.com/support/solutions/articles/110173-securing-file-attachments
-
-
We should skip saving, tearing down, and the actual tests in the case that the user is using s3 (or another) storage backend.
I'd make setUp and tearDown no-ops if
settings.DEFAULT_FILE_STORAGE != 'django.core.files.storage.FileSystemStorage'
and have execute() just return success. -
This line looks too long (> 80 columns).
There's also some changes I'd like to make to the string. Let's add translation, use the "six" library to convert to a text type (for python 2/3 compatibility) and use string formatting to include the exception:
_('Uncaught exception during test: %s') % six.text_type(e)
-
-
-
Once again, we should include instructions for how to fix it (shown when the test fails).
This one would say to edit the settings_local.py file in the site's conf directory and add a line like this with their site's URL:
ALLOWED_HOSTS = ['example.com']
-
-
-
-
-
-
A handful of comments, but the good news is that they're almost entirely stylistic things.
Can we see some screenshots showing success, failure, and a mix?
-
-
-
-
The
camelCase
in unittest is a holdover from early days of Python. We shouldn't duplicate it here. Instead, just call thissetup
. -
-
When you have to escape a single quote, it's best to just use double quotes for the string itself, to avoid the escape.
-
Can we call this
storage
instead offss
? It's a more standard variable name for an instance of a Storage class. -
-
-
-
-
-
Just to check for myself, this will fail on the first failed file, right?
How hard would it be to still try every type, and present a list of failed file extensions? That'd prevent the admin from having to make a change, reload the web server, try the checks again, and repeating.
-
No need for the outer parens here, as it's one line and the comma will ensure it'll be returned as a tuple.
-
-
-
Not really worth talking about Django. "That Review Board will consider valid for this server" is probably fine.
-
-
-
-
-
-
-
-
Typically, you'd want
iteritems()
, since it doesn't make a copy of the list of items.Python 3 renames this to
items()
, so we're now using thissix
module to provide abstraction.So, this should be:
for name, cls in six.iteritems(checks):
-
-
-
-
Global variables should be at the top of the file, after the imports. Two blank lines on either side.
-
-
-
-
The
widget-*
URLs are wrong. This regex should be:r'^security/$'
The
$
preventssecurity/adfsfsa
from matching. -
-
-
Should remove this. It'll actually break some server configurations, as many WSGI implementations don't like random things going on stdout.
-
-
The URLs above based on
views.dashboard
are done for legacy reasons, but for this one, you should give the URL a name in theurls.py
file by doing:url(r'^security/$', 'security', name='admin-security-checks')
Then, here, you can do:
{% url 'admin-security-checks' %}
-
-
So a word on indentation in templates.
The content of the template, and the template language itself, are indented separately, as there are times that they don't actually match up, and for some file types it would be flat-out wrong.
So, template tags are indented like:
{% block foo %} {% if bar %} {% for foobar in bar %} ... {% endfor %} {% endif %} {% endblock %}
One space indentation within the template tag markup, relative to the parent template tag.
HTML tags should be indented one space relative to their parent tag, and not to the template tag.
-
-
Things like
border=1
,style=
, etc. don't belong. These should be defined solely in the CSS. It's not good to mix presentation and content in HTML. -
- Summary:
-
Security Checklist ProjectAdd a Page for the Security Checklist in the Admin View
- Description:
-
~ Added the rest of desired listed functionality for the project.
~ The test runner runs through the two existing checks. The ExecutableCodeCheck now goes through all the file types that were mentioned. Both tests now return pass/fail status as well as some additional information about why they failed (if they fail). ~ With this review request I fixed a lot of style issues. This includes:
~ - Making sure that includes are properly alphabetized; + - Got rid of escaped characters by making the string double-quoted; + - Renamed variables so they are more consistent; + - Aligned strings; + - Removed outer parenthesis where they are not needed on tuples; + - Improved some of the user-visible descriptions; + - Added a docstring for SecurityCheckRunner; + - Fixed blank lines; + - Fixed URLs; + - Fixed indentation in the template; + - Moved HTML styling into CSS tags. + + In terms of actual functionality, I changed the ExecutableCodeCheck test to be able to fail on multiple file types. Before it would end the test on the first failed file type and return that to the user. Now it will return a list of each file type that fails.
+ + I've also included some screenshots to show what various success/failure statuses look like.
- Diff:
-
Revision 4 (+306 -5)
- Added Files:
-
-
This should be localized, and you can use ngettext (included in django.utils.translation) to do the pluralization. It's also ok to use join on a single-element list, in which case it will just return the one element, regardless of joiner.
I'd also like to tweak this text a bit.
error_msg = ( ngettext( 'The web server incorrectly executed these file types: %s', 'The web server incorrectly executed this file type: %s', len(failed_exts)) % ', '.join(failed_exts))
-
-
Can you put quotes around the `*?
Also, we've already explained why it's an issue in the desc text, so this probably doesn't need to have the second sentence at all.
-
-
-
-
We shouldn't have any inline styles, only classes and IDs (all styles here should all be in the admin.less file).
Having the error message be a single-element
<ul>
is pretty weird. Can we just make it a text span?I'd also like to consider not doing this as a table with borders, but instead spacing it out with whitespace and headings. That said, changing the look is lower priority than the other fixes.
-
- Change Summary:
-
Fixed all but the remaining open issue. I won't be able to get to it before hard pencils down tomorrow but I can continue to fix it up in the near future.
-
The code looks pretty good to me (aside from the CSS and layout changes, which we talked about). It looks like your review request description somehow got overwritten with a description of the changes in diff r4. Can you change the description on the review request to be a description of what the feature is and an overview of what code changes were done to implement it?