Sandbox: https://www.drupal.org/sandbox/offlein/2491739
Git clone command: git clone --branch 7.x-1.x http://git.drupal.org/sandbox/Offlein/2491739.git

Hi,

This is a project that we needed internally here at the UN and I thought would be good for public consumption.

I've created an easy-to-use interface for manipulating the raw table data of any table owned by the Data module. It uses the external jQWidgets library, provided by the Libraries module.

Once installed, a new tab is added to the Data table user interface called "Manipulate Data". From here you will be presented with an interactive table that updates the database table in question via AJAX calls as the user makes changes.

This module comes with an optional data_manipulate_access module, which provides per-user access control for manipulating table data via the data_manipulate_ui interface.

Comments

PA robot’s picture

Status: Needs review » Needs work

There are some errors reported by automated review tools, did you already check them? See http://pareview.sh/pareview/httpgitdrupalorgsandboxOfflein2491739git

We 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.

awasson’s picture

I've started to give this a bit of a review but first I recommend that you run it through Pareview and work through the warnings and errors that it has detected. You can have a look at the results here: http://pareview.sh/pareview/httpgitdrupalorgsandboxofflein2491739git

Once you've worked through the errors and committed them to your sandbox, you can run it again as often as necessary by clicking the repeat review tab.

EDIT:

I will be delving deeper into this once you've followed up on the PAReview errors but this is my review according to the reviewing template: https://groups.drupal.org/node/427683

Individual user account
Yes: Follows the guidelines for individual user accounts.

No duplication
Yes: Does not cause module duplication and/or fragmentation.

Master Branch
Yes: Follows the guidelines for master branch.

Licensing
Yes: Follows the licensing requirements.

3rd party assets/code
Yes: Follows the guidelines for 3rd party assets/code.

README.txt/README.md
Yes: Follows the guidelines for in-project documentation and/or the README Template.

Code long/complex enough for review
Yes: Follows the guidelines for project length and complexity.

Secure code
No: See comment re cross site request forgery (CSRF) vulnerability by Ayesh: https://www.drupal.org/node/2492195#comment-9955719

Coding style & Drupal API usage
No: Fails PAReview

Cheers,
Andrew

awasson’s picture

Oh, you'll need to adjust your info file to tell it add a dependency for jquery_update.

Ayesh’s picture

Issue tags: +PAreview: security

Hi there,
Thanks for submitting the application. I don't use the Data module often (never came across a need), but this project had me wonder why there isn't such a module to do this! Well, here we are with a new project that provides a neat UI to do that.

Unfortunately, this module does not protect itself against cross site request forgery (CSRF). It's a straight forward exploit, and requires to trick someone with data_manipulate_ui_access permission passing. Note that the attacker can trick him to follow certain action that he didn't intend. This can be done with Javascript too (with same-origin policies bypassed).

<form action="http://dev/work/applications/ajax/data_manipulate_ui/test" method="post"> 
<input type='hidden' name='{"row":{"test":69},"id":null, "escape": "' value='escaped"}' />
<input type="submit" value="This is completely harmless. Trust me" />
</form>

Let me take you through this:
First, we create a fake form with method=post, so we are essentially trying to add a row to the test table. Notice the action URL.

Now, we need to pass a valid json string, to be decoded server side. Module expects the row to be there, and we feed all the data we need into the test. Since forms follow the normal HTTP query parameters, we leave an open quote (notice the "escape": "), so the equal sign added by the browser gets ignored in the json_decode operation.

At the server side, we end up with an array that has 3 keys: row (= array(test => 69)), id (= null), and escape (= '=escaped').

Since this input field is a hidden one, the administrator we are tricking into doesn't notice this without checking the actual HTML. You can change the appearance of the Submit button to look completely innocent. It's also possible to submit the form with Javascript; on document.ready even.

In cases like this, we definitely need to validate the form with an anti-CSRF token. It is possible to administrator to visit some page, and load the form. But browsers forbid that with the same-origin policy. Notice how the link to enable a theme works. It has a session-dependent token that can't be guessed by outsiders.

In your module, you can add a CSRF token to be passed along with the request, and validate it at the server side. drupal_get_token() and drupal_valid_token() are great candidates.

Offlein’s picture

Hello,

Thanks so much for the help, guys... And thank you sincerely for the compliment on the module idea. :)

I corrected all the last PAReview stuff. It still reports errors about function name prefixes, but -- and maybe I did this wrong? -- you'll notice I include a submodule in this project. The main module is data_manipulate_ui, but there's a data_manipulate_access directory within. The fact that the files within the "data_manipulate_access" directory aren't prefixed with "data_manipulate_ui" is throwing errors, but I think that should be fine, right? It's just a red herring?

Regarding the CSRF: Right! OK! So, I've done this:

  1. Created a CSRF token via drupal_get_token(), passed with the table name as an argument. Is that fair?
  2. I've added the CSRF token string to the page via the Drupal Javascript settings object (Drupal.settings.data_manipulate_ui.csrf_token).
  3. Upon any update requests (POST, PUT, DELETE) I include the CSRF token as part of the body of the request.
  4. When parsing the request, the first thing the AJAX callback does is check that there IS a CSRF token at all, and then ensure that it returns TRUE for drupal_valid_token() -- with the table name passed in.
  5. If it was not included or it was invalid, it will throw an error explaining "Invalid or null CSRF token."

Is this acceptable?

Ayesh’s picture

Thanks Craig. Yep, the CSRF handling looks perfect now!

The pareview complains about the module name is valid for some extent though.

views module has views, views_ui. Rules module has rules, rules_admin, etc. Usually the base module name is prefixed by sub modules.
This is purely a question: Is there any reason why you didn't use data_manipulate_ui_access for the module name? That is what pareview is expecting, and makes more sense to me too, because this module is only restricting access to the UI (of data_manipulate_ui module). However, I don't think this is a major issue at all. VBO for example, provides two modules with completely different names.

If your module is ready to be reviewed again, feel free to set its status to "Needs review". As always, Review Bonus can help speed things up.

vedpareek’s picture

Hello

Mannual review
1. Please fix pareview.sh issues http://pareview.sh/pareview/httpgitdrupalorgsandboxofflein2491739git
2. All functions should be prefixed with your module name.

Offlein’s picture

Status: Needs work » Needs review

Hello,

@Ayesh: Thank you so much for your assistance. You are right; that is valid. I used "data_manipulate_access" because, honestly, I thought there should be some sort of Access Control module in general for the Data module, and this could maybe be that. But then I couldn't easily imagine a situation where you'd need access control while not also needing the manipulate UI. I guess for changing the structure of the table, but that introduced other issues.

My module actually was first called "data_ui" I think, but uh... Well, for reasons that may be obvious that didn't make sense. ("data_ui" is already the name of the UI for the data module...) At that time the other was called "data_access". So I renamed it to "data_manipulate_ui" and "data_manipulate_access".

..Anyway, I've renamed it to data_manipulate_ui_access because that makes more sense and the pareview errors have gone away. I would love to get the review bonus in place, because I think it's such a great idea, but I am a little behind on my schedule so I can't at this time. :( I really appreciate all the help you've given in spite of this.

@vedpareek: Thank you for the manual review. I believe you may be mistaken about #1, however? That is, you should not use t() in hook_menu's page titles, as the default 'title callback' is t(). #2/#3 should be addressed!

Thank you so much, all.

zakir.gori’s picture

Please fix following issues:

js/data_manipulate_ui.js: line 6, col 2, Error - Use the function form of "use strict". (strict)
js/data_manipulate_ui.js: line 14, col 36, Error - Missing space before function parentheses. (space-before-function-paren)
js/data_manipulate_ui.js: line 17, col 36, Error - Missing space before function parentheses. (space-before-function-paren)
js/data_manipulate_ui.js: line 29, col 74, Error - Properties shouldn't be quoted as all quotes are redundant. (quote-props)
js/data_manipulate_ui.js: line 33, col 36, Error - Missing space before function parentheses. (space-before-function-paren)
js/data_manipulate_ui.js: line 36, col 34, Error - Missing space before function parentheses. (space-before-function-paren)
js/data_manipulate_ui.js: line 38, col 13, Error - "id" is not defined. (no-undef)
js/data_manipulate_ui.js: line 38, col 18, Error - "$jqxGrid" is not defined. (no-undef)
js/data_manipulate_ui.js: line 39, col 13, Error - "$jqxGrid" is not defined. (no-undef)
js/data_manipulate_ui.js: line 39, col 43, Error - "id" is not defined. (no-undef)
js/data_manipulate_ui.js: line 44, col 9, Error - "$jqxGrid" is not defined. (no-undef)
js/data_manipulate_ui.js: line 45, col 9, Error - "$jqxGrid" is not defined. (no-undef)
js/data_manipulate_ui.js: line 52, col 45, Error - Missing space before function parentheses. (space-before-function-paren)
js/data_manipulate_ui.js: line 58, col 9, Error - Move function declaration to function body root. (no-inner-declarations)
js/data_manipulate_ui.js: line 59, col 22, Error - Properties shouldn't be quoted as all quotes are redundant. (quote-props)
js/data_manipulate_ui.js: line 64, col 15, Error - data is defined but never used (no-unused-vars)
js/data_manipulate_ui.js: line 72, col 31, Error - Missing space before function parentheses. (space-before-function-paren)
js/data_manipulate_ui.js: line 73, col 17, Error - "$jqxGrid" is not defined. (no-undef)
js/data_manipulate_ui.js: line 75, col 31, Error - Missing space before function parentheses. (space-before-function-paren)
js/data_manipulate_ui.js: line 84, col 9, Error - Move function declaration to function body root. (no-inner-declarations)
js/data_manipulate_ui.js: line 87, col 15, Error - rowUniqueId is defined but never used (no-unused-vars)
js/data_manipulate_ui.js: line 90, col 21, Error - Expected '===' and instead saw '=='. (eqeqeq)
js/data_manipulate_ui.js: line 95, col 22, Error - Properties shouldn't be quoted as all quotes are redundant. (quote-props)
js/data_manipulate_ui.js: line 101, col 15, Error - data is defined but never used (no-unused-vars)
js/data_manipulate_ui.js: line 109, col 31, Error - Missing space before function parentheses. (space-before-function-paren)
js/data_manipulate_ui.js: line 110, col 17, Error - "$jqxGrid" is not defined. (no-undef)
js/data_manipulate_ui.js: line 112, col 31, Error - Missing space before function parentheses. (space-before-function-paren)

joachim’s picture

Status: Needs review » Needs work

Looks interesting, and I need to look at this in more depth.

I'll say now though that I think that having access control in a separate and optional module is not a good idea.

klausi’s picture

Status: Needs work » Needs review

That sounds like a design decision at the discretion of the module author and should not be an application blocker unless it results in a security vulnerability.

joachim’s picture

> That sounds like a design decision at the discretion of the module author and should not be an application blocker unless it results in a security vulnerability.

True, I was a bit too hasty there in assuming that without the submodule, there was no access control at all.

However, that submodule does have design flaws. It appears to store a table of user UIDs and table names, as a record of who can edit which table. That seems to me to just be reinventing the role system. It would be equivalent to define a permission for each table, and then let admins assign roles with those permissions to users.

  else {
    return t('Unable to load jQWidgets library!');
  }

If the jQWidgets library is a requirement, use hook_requirements() rather than checking for it here.

data_manipulate_ui_get_data() loads all the data in a table in an AJAX response. That's not going to scale.

> function data_manipulate_ui_access($table_name, $account = NULL) {

Docs are missing a parameter here.

Offlein’s picture

Status: Needs review » Closed (won't fix)

Hi. I'm sorry, I'm going to have to rescind my request for this. I would probably have been OK maintaining this, but I am employed elsewhere now and it's unfortunately not a priority to see this released. Happy for anyone to take it, but I can't make the corrections needed.