Elevating from DRUPAL_BOOTSTRAP_DATABASE (which takes <100 ms) to DRUPAL_BOOTSTRAP_SESSION (which can take 1500-1700 ms on my local dev) in order to only get the user ID and potentially a role ID or something like that is probably avoidable. In my own use case, I'm showing the user a lot of different data, such as comments, via modals, and that data is privileged to the current user only if they're attached to the particular content in some way, such as a user reference field.
In looking through session.inc, which is actually not as hairy as I anticipated, I've come to realize that we don't need to do much more than grab the session ID from the user's $_COOKIE and query the sessions table. I was blindly under the impression that there would be more security caveats here and, if so, I'd love to hear about them. Here's an example of some code at the top of a JS callback that can get the current user's ID and check if they're the author of a node:
<?php
// Helper function that can be called at the top of JS callbacks to get the user's UID.
function _mymodule_js_session_uid() {
$session_name = session_name();
if (!empty($session_name)) {
if ($uid = db_query("SELECT uid FROM {sessions} WHERE sid = :sid", array(':sid' => $_COOKIE[$session_name]))->fetchColumn()) {
return $uid;
}
}
return FALSE;
}
function mymodule_js_callback_view_node($nid) {
$uid = _mymodule_js_session_uid();
if (!$uid) {
return 'access denied';
}
// Only view this node if the current user is the author.
if (db_query("SELECT nid FROM {node} WHERE nid = :nid AND uid = :uid", array(':nid' => $nid, ':uid' => $uid))->fetchColumn()) {
return 'You are the author of this node and you can do whatever you want with it.';
} else {
return 'access denied';
}
}
?>The above code is missing the HTTPS SID (the ssid) which I'll play with a bit on my own, but the real purpose of this issue is to answer the question – what security concerns lie in using this method? I am able to serve up modals that contain all of the comments on a particular node, or to perform ajax actions on a node (change a status field, change a boolean field, etc) in ~ 90 ms, which is amazing!
On a side note, sorry for opening so many issues in such a short amount of time. I've been delighted with this module in D7 and am trying to use it for a lot of different things. Hopefully I can close most of these issues myself and they don't take up too much time by the maintainers.
Comments
Comment #1
michielnugter commentedBootstrapping to session may take this long because along the way it also does a lot of other stuff as SESSION is a very late step in the bootstrap.
There might be something to this, maybe there is a way to initialize the session without the rest, minimizing the overhead. I really want to be able to use the default user_access method for access validation, anything else feels a bit too custom for the js module itself. The code above really focuses on node ownership but fails to respect the normal permissions (maybe the current user can view/edit all nodes). I really think it should focus on features which are at least similar to the normal Drupal process.
There is of course, nothing stopping you from adding this kind of access control in your own modules and validate permissions in the js callbacks themselves.
No problem at all on opening the issues, it's great to see the module being used, that's the whole reason for releasing it :)
Comment #2
charlie-s commentedI agree completely – the logic above was just to show a simple usage of this concept, but ultimately it should follow the existing access logic. I have node_access() / user_access() working locally:
Comment #3
coltraneIf you allow comments from anonymous or untrusted users you'll be vulnerable to an XSS attack via mymodule_view_comments().
You should not assume the comment body can be rendered in Full HTML and you should sanitize the comment name:
Comment #4
charlie-s commentedThanks coltrane! A couple of questions:
1. What's wrong with Full HTML if I need it? I do not allow javascript to be sent through the full HTML filter. I also only allow (in this instance) comments to come from trusters users, but that's completely beside the point as even a trusted user could do something evil.
2. Why should I filter the user name?
Comment #5
coltraneIf you've configured the Full HTML format to filter dangerous tags then that's OK. By default Full HTML is just that, all HTML tags including dangerous ones. You can't just filter script though, embed, object are also dangerous. Edit, here's a list of dangerous tags http://drupalcode.org/project/security_review.git/blob/refs/heads/7.x-1.... but know that whitelisting (Filtered HTML) is better than blacklisting.
If you allow anonymous commenting you should filter the user name. Comment module stores the name in the comment table so it doesn't always pass through validation that would revoke control characters.
Comment #6
charlie-s commentedGood points, again. Thanks Coltrane.
Comment #7
michielnugter commentedI'm closing this as I don't think I'll ever implement it for the module. There are too many possible complications and security issues here.
Thank you very much for your input and thoughts on the module, they are very much appreciated!
Comment #8
michielnugter commented