Request statistics is a tool for site owners and developers for use during the planning of a responsive design project. The module samples relevant request information without the overhead of Browscap or a full statistical recording application.
Low overhead
You can switch the recording on and off for short low overhead samples then report the results on your own time with no ongoing overhead. All the data is available through Views for custom reports.
Documentation
The current documentation is at the following address.
https://www.drupal.org/sandbox/peter/2484353
The documentation will include information on adding additional data.
Workload reduction
There are several sites using the module for current projects. The information from the reports has reduced their workload and simplified their image related workflow by showing them the characteristics of the most common visitors.
Demo
A demo if the reports is available at http://02g.org/request-statistics.
Git
git clone --branch 7.x-1.x http://git.drupal.org/sandbox/peter/2484353.git request_statistics
cd request_statistics
Reviews of other projects
Manual reviews of other projects
https://www.drupal.org/node/2488462#comment-9970599
https://www.drupal.org/node/1167022#comment-5596872
https://www.drupal.org/node/1421554#comment-5596760
https://www.drupal.org/node/1269194#comment-5598582
https://www.drupal.org/node/1387212#comment-5598628
https://www.drupal.org/node/1684898#comment-6900784
https://www.drupal.org/node/1785088#comment-6903682
Security
There is no need for security on the modules. The data is all public. Any hacker can look at Drupal code and see that the user id is an integer. The user agent string looks impressive but it is published for public consumption at Browscap.
You only switch the recording on for short samples. The information collected is less than what Alexa publishes about your Web site. If you leave the recording on permanently, there is a recording overhead and the possibility of a hacker creating a flood attack. There is exactly zero difference of a denial of Service attack with the recording on or off.
The main extra information is visitor device characteristics. This helps your non developers decide priorities. The data is of absolutely no use to your competitors or anyone else outside your responsive design project.
| Comment | File | Size | Author |
|---|---|---|---|
| #10 | d7_request_statistics-2495015-10.patch | 921 bytes | ayesh |
Comments
Comment #1
PA robot commentedWe are currently quite busy with all the project applications and we prefer projects with a review bonus. Please help reviewing and put yourself on the high priority list, then we will take a look at your project right away :-)
Also, you should get your friends, colleagues or other community members involved to review this application. Let them go through the review checklist and post a comment that sets this issue to "needs work" (they found some problems with the project) or "reviewed & tested by the community" (they found no major flaws).
I'm a robot and this is an automated message from Project Applications Scraper.
Comment #2
everright commentedHi peterx,
This is a good module. But I have found 1 issue of permission.
Automated Review
This module pass the automatic review.
Manual Review
The starred items (*) are fairly big issues and warrant going back to Needs Work. Items marked with a plus sign (+) are important and should be addressed before a stable project release. The rest of the comments in the code walkthrough are recommendations.
If added, please don't remove the security tag, we keep that for statistics and to show examples of security problems.
This review uses the Project Application Review Template.
Permission issues
line 35 of file "request_statistics_record_menu.php", access callback is always TRUE, so any user can see the record statistics admin page without permission. I think you need to add access control for that, also for all views, becuase your views also not set access control yet.
Suggestion
Create a folder for each sub-modules, so modules are able to clearly read and well-structured.
Comment #3
klausiGood catch, this seems to be a security blocker. And please don't remove the security tag, we keep that for statistics and to show examples of security problems.
Comment #4
peterx commentedDirectory structure changed to the suggestion in https://www.drupal.org/node/2495015#comment-9964819.
Comment #5
peterx commented"line 35 of file "request_statistics_record_menu.php", access callback is always TRUE, so any user can see the record statistics admin page without permission."
No security problem there. request_statistics_record_menu.php is not connected to any admin page. Please remove the security issue tag.
"also for all views, becuase your views also not set access control yet."
Not a security issue either. The views are protected by the following Drupal core admin permission.
Use the administration pages and help
The data recorded by the module does not open up a security risk. Adding a fake permission to the views would increase problems when people clone the views, something they are encouraged to do.
Comment #6
everright commentedHi Peterx,
What i mean is all users can see admin/reports/request-statistics & admin/reports/request-statistics/* pages without any permission. but that reports page will be display statistics information which include user id, browser info, etc,.
Comment #7
peterx commentedHello Everright,
I tested access on two of the sites using the code and did not have access. To make life easier and allow for any inconsistencies across Drupal systems, I added the admin pages permission to the view module and the views. You can test the current version at the following demonstration site.
http://02g.org/admin/reports/request-statistics
http://02g.org/admin/reports/request-statistics/browser-type
The demo site will eventually have the views duplicated at the following public address.
http://02g.org/admin/reports/request-statistics
Given that the visitors cannot access the Views UI module, they cannot add the user profile information to those reports. The user id is useless and everyone already knows that user id 1 is the admin id.
Comment #8
everright commentedHi Peterx,
I have test again, permission worked well.
Comment #9
everright commentedComment #10
ayesh commentedHi Peter,
I checked your code at commit 71edabf7b884462249751e81dd26942dc09312ea, and it indeed contained the security issue mentioned #2. I can also see that you have fixed it in the latest version.
Please note that `none` access setting in View means that there is no access restriction. It does not mean nobody can access the view. I have often found myself forgetting to set access too.
I too can confirm there was a security issue in the module, so I think we should leave the Security tag. Again, don't worry about the tag, They are purely for stats and educational. There are many modules which had this tag and yet they passed the review.
This PAReview: Security tag is only for educational and statistical purposes. It doesn't mean the current version of the project contains any security issues, and it's certainly not a blocker once fixed.
Manual review
- Package name of the module suit would make more sense if use "Request statistics" (instead of "Request").
- Since this module serializes the user input data (RequestStatisticsRecordPageCallback::pageCallback), note that you should be careful when unserializing them. I did not see the module unserializing them itself, but if you plan to do, please try to avoid Object Injection attacks.
- In the request recording JS file (request_statistics_record.js), the script always assumes the site is run in the top level folder. I had my test site in a sub folder, and I did not get any stats because the JS file pushed data to a different URL. See the attached patch for a fix. Always use Drupal.settings.basePath to get the base path. It will be either "/" or the path to the sub folder, so you can safely assume this works any site setup regardless of the installed location. I will set this application to Needs Work because of this.
- Consider adding some conditional reporting mechanism to prevent repeated submissions. .resize() event can be called thousands of times, and this snippet can this trigger loads of requests to the server. A time delay would do the trick.
I will use the module for some to gather some statistics in the database, and provide another review if necessary.
Comment #11
ayesh commentedComment #12
peterx commentedComment #13
peterx commented"Please note that `none` access setting in View means that there is no access restriction. It does not mean nobody can access the view."
As noted in the documentation, a permission was not set so anyone can use the data, clone the views and rework the data all they like. Due to the artificial requirement to add a permission to satisfy this review, I added a permission. I should have added the permission to view published data. I may move the reports of of the admin area just to make it clear that non administrators view the data.
The only data to be limited is access to the user profile and that is limited by the security in the user module. The user id is already public by virtue of a million hackers knowing it is an integer they can create for an attack. Web browser user agent strings are public and are listed at browscap for the convenience of all hackers.
How many times do I have to repeat that people outside of the Web site administrator are supposed to see the data?
Comment #14
peterx commented"Package name of the module suit would make more sense if use "Request statistics" (instead of "Request")."
I removed the package line from .info to simplify the review process. The original package name covers a large group of related modules but I am not submitting the rest.
Comment #15
peterx commentedI understand the problem of resizing and will eventually add a delay. The typical sample periods are an hour every few months. On a very large site, several days of recording produced NO resizes.
There were a tiny number of swaps from portrait to landscape. Adding a orientation swap record is more important to the users of this module. I can add a delay when I add the swap record.
Comment #16
peterx commentedResize wait is in.
Comment #17
peterx commentedComment #18
peterx commented" Since this module serializes the user input data (RequestStatisticsRecordPageCallback::pageCallback), note that you should be careful when unserializing them"
There is no reason to unserialize data set to watchdog for logging. If the serialize() function is a problem, I can replace it with var_dump() wrapped in an output buffer capture system.
Comment #19
peterx commentedThe demo is in 02g.org. As you can see by the displayed data, there is nothing a hacker can use, there never was a security issue.
Comment #20
peterx commentedComment #21
peterx commentedPAReviews attached. Security documented. Demo site online. The project is complete for most of the sites using the code.
Comment #22
ayesh commentedHi Peter,
The security issue raised a few days has nothing to do with module's progression. It merely works as a bookmark for others to learn from it. I do not want to take this any further, but please note @everright mentioned about the unprotected Views pages. It's perfectly OK to leave the Ajax path unprotected. Even the Drupal core statistics module does that. But leaving site information available to others by default is definitely an issue.
Take the "Request statistics path" and "Request statistics visitor by visitor" views for example. It's known that Drupal user IDs are unsigned integers. But the exact user IDs cannot be determined by anonymous users if they don't have permission to access user profiles. They can of course tinker with URLs to check 403 vs 404 statuses, but that is not a reason to leave them available in plain sight.
Code shown in Everright's #2 comment is not exactly where the security is. rsr->menu()'s router item does not need protection, but RequestStatisticsViewMenu->menu()'s menu router item does.
- In request_statistics_view_reports.php file, the
t("@text")can cause problems in translation because it has no string literal in it. You can usecheck_plain($display_options['display_description'])to achieve the same.I'll leave for you or another senior git administrator to decide if the Security tag should stay. I vote to keep it. Nonetheless, now that it is fixed along with other known bugs so far, I'm changing status to RTBC.
Comment #23
mpdonadioReviewing next. Please don't remove the security tag, we keep that for statistics and to show examples of security problems.
Comment #24
mpdonadioAutomated Review
Review of the 7.x-1.x branch (commit b027e11):
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. You have to get a review bonus to get a review from me.
Manual Review
has open access. This takes POST data, and writes to the database w/o a token check. An attacker could insert bogus data int
the tables, update any row, and could also write a curl script that fills up the database (ie, a DOS). You need to look
into drupal_get_token() and drupal_valid_token(). I am deeming this a security problem that needs to be fixed.
(*) In RequestStatisticsViewMenu::menu(), the permission 'access administration pages' is too loose. There is potential
for information disclosure about uid 1 habits. Define your own permission, or use 'administer site configuration'.
Your .info file should use the files[] directive for the includes so you can leverage the autoloader instead of manually including files.
Schema should list of FK for documentation purposes, and FK column names should really match up with the name in the foreign table (eg, uid). I suspect your FKs should also be indexed, as then will be used with joins.
request_statistics() should use drupal_static instead of the PHP static.
The JS should use behaviors instead of .ready(). Some minor formatting problems, too.
Not a huge fan of the way OO got implemented here. It breaks the pattern of Drupal conventions, and makes this a lot harder to trace out.
In general #attached is preferred over drupal_add_js(). Since you are using this from a hook_init(), it will get called for 404s, image deritive creation, and other things that are not direct page views.
Why do you define a view and then manually call it in a page callback? Just add a Page display to the view and set a path.
The starred items (*) are fairly big issues and warrant going back to Needs Work. Items marked with a plus sign (+) are important and should be addressed before a stable project release. The rest of the comments in the code walkthrough are recommendations.
If added, please don't remove the security tag, we keep that for statistics and to show examples of security problems.
This review uses the Project Application Review Template.
Comment #25
mpdonadio@Ayesh, when you set RTBC on a module, you can assign it to one of the other admins for a second look. Typically, we don't bug @klausi, except for second opinions on security related issues, but you can pick anyone who is active. That way, it will show up in our queues, and we can get to them quicker.
Comment #26
ayesh commentedThanks Matthew. You are right I should have been careful. Sorry.
However, for the security issue, Drupal core statistics module does a similar thing to add a row.
Please see http://cgit.drupalcode.org/drupal/tree/modules/statistics/statistics.php...
I'm completely agreeing with the hook_init though. It's not in D8, and majority of D7 modules are using it already.
Comment #27
mpdonadioOK, checked with @klausi on this one.
The open path w/o a token check is not a blocker.
The permission of the view is b/c it is potential information disclosure. I will approve the application if the view is changed to use a custom permission or 'administer site configuration'.
Comment #28
peterx commentedOpen path without a token?
I can understand someone requiring the use of a token in case someone else accidentally leaves the recording on past the sample time. How do tokens work with cached anonymous pages?
As far as I can see, the only current solution is to install Security Kit or copy code from Security Kit. The Security Kit configuration is way too complex and the slightest mistake in configuring Security Kit will cause more damage to user access than a few extra rows in the Request statistics sample data.
A safer option would be to simply switch the sample off after a set number of samples, say 1000.
Comment #29
peterx commentedpermission 'administer site configuration'
The reports currently use 'access administration pages' because Drupal core uses that for reports. I changed the views to 'administer site configuration'.
Comment #30
peterx commentedEmpty line added to end of README.txt.
http://pareview.sh/pareview/httpgitdrupalorgsandboxpeter2484353git
Comment #31
peterx commented"Your .info file should use the files[] directive for the includes so you can leverage the autoloader instead of manually including files."
I changed this module. Some modules have to use manual includes because they have to use hook boot and Drupal autoloader is unreliable in hook boot.
Comment #32
peterx commented"Why do you define a view and then manually call it in a page callback? Just add a Page display to the view and set a path."
Because Views failed to work when I tried to do things the way Views recommends. There are some serious problems with the way Views handles menu entries. There are several issues posted. When you bypass the Views problems with manual control of the menu entries, you have to take over the whole lot.
Comment #33
peterx commented'In general #attached is preferred over drupal_add_js()'
I looked through many examples in Drupal core. They were all for forms. I am not using forms. drupal_add_js() worked. The choice was to spend more time on #attached or to study and pass exams.
Comment #34
peterx commented"Not a huge fan of the way OO got implemented here. It breaks the pattern of Drupal conventions, and makes this a lot harder to trace out."
I can understand the problem. Drupal 7 has some weird conventions. Drupal 8 does everything different. Pareview appears to be asking for Drupal 8 conventions in Drupal 7 code but not all Drupal 8 conventions. Either way, the result is excessive memory usage.
I code for performance, reliability, and serviceability based on measuring what works. Part of the OO approach is reducing memory usage.
Comment #35
peterx commented"request_statistics() should use drupal_static instead of the PHP static."
Why? request_statistics() is not storing data. There is no requirement to reset anything during a page request. In fact the opposite is true, the object has to remain the same. request_statistics() fits the Drupal documentation for drupal_static() as a case where you do not use drupal_static().
Comment #36
mpdonadioI will look at this tomorrow.
Comment #37
mpdonadioAutomated Review
Review of the 7.x-1.x branch (commit 675f322):
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. You have to get a review bonus to get a review from me.
Manual Review
I read `git diff b027e11`, and saw several of my recommendations were implemented, and my security concern was addressed. As the security concern was the only blocker, this is back to RTBC.
If added, please don't remove the security tag, we keep that for statistics and to show examples of security problems.
This review uses the Project Application Review Template.
Comment #38
mpdonadioThanks for your contribution, peterx!
I updated your account so you can promote this to a full project and also create new projects as either a sandbox or a "full" project.
Here are some recommended readings to help with excellent maintainership:
You can find lots more contributors chatting on IRC in #drupal-contribute. So, come hang out and stay involved!
Thanks, also, for your patience with the review process. Anyone is welcome to participate in the review process. Please consider reviewing other projects that are pending review. I encourage you to learn more about that process and join the group of reviewers.
Thanks to the dedicated reviewer(s) as well.
Comment #39
awasson commentedNice work Peter. That's a module I'll be using. Congrats!