Access denied - Are you sure?
Heine Fri, 2008/03/21 - 05:23
It is surely not my intend to discuss each and every security announcement, but the recent Live announcement (SA-2008-021) deserves to get some attention as this particular drupal_access_denied
& drupal_not_found
pitfall affects you too, especially when you are converting "arrow code" to use guard clauses.
// This drupal_access_denied / drupal_not_found pattern is common in Drupal modules.
function page_callback() {
if (condition) {
if (another_condition) {
if (yet_another_condition) {
return do_something();
}
}
}
drupal_access_denied();
}
function page_callback() {
if (!condition) {
drupal_access_denied();
}
if (!another_condition) {
drupal_access_denied();
}
if (!yet_another_condition) {
drupal_access_denied();
}
return do_something();
}
The pitfall: drupal_access_denied emits the access denied page, but does not end the request. This means do_something() is still executed, with potential security vulnerabilities as a result. When you actually test an access denied scenario and do_something returns a string, you'll notice you get a double page rendered; one part contains the access denied page, the other the output of do_something.
The remedy is easy, use return drupal_access_denied();
instead of drupal_access_denied();
function page_callback() {
if (!condition) {
return drupal_access_denied();
}
if (!another_condition) {
return drupal_access_denied();
}
if (!yet_another_condition) {
return drupal_access_denied();
}
return do_something();
}
Comments
Hi, I just did a search in a
Submitted by peach - all dru... (not verified) on Fri, 2008/03/21 - 10:26Hi, I just did a search in a folder with a bunch of drupal modules;
*.module; "return drupal_access_denied" : found 4 files
* .module; " drupal_access_denied" (note 2 spaces before function) : found 21 files
Does that mean all the modules in the second group are insecure? or possibly insecure?
maybe
Submitted by greggles (not verified) on Fri, 2008/03/21 - 14:09It depends what comes on the following lines.
if it just does
drupal_access_denied();
something_else_important();
return;
}
other_stuff();
Then the other_stuff is protected by the return on the following line.
I want to know how Heine has
Submitted by xamox (not verified) on Sun, 2008/03/23 - 03:06I want to know how Heine has become such a security ninja. He seems to be the master at finding these security bugs. Props to you man.
excellent
Submitted by Pedro Pablo (not verified) on Thu, 2008/07/17 - 01:00it is so comfortable to know people like you are watching out to protect us from the bad guys... :-)
Very good discovery as it will enhance many modules' security
In a lot of cases you won't
Submitted by Xano on Sat, 2008/09/20 - 01:27In a lot of cases you won't be able to end the request by returning drupal_access_denied() or drupal_not_found(), because the function these calls are made in are no direct menu callback. The solution is to simply exit; right after calling one of the aforementioned functions.
drupal_exit()
Submitted by scor (not verified) on Fri, 2011/04/01 - 19:35Drupal has its own wrapper for exit(): http://api.drupal.org/api/drupal/includes--common.inc/function/drupal_exit/7