Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Apress.Pro.Drupal.7.Development.3rd.Edition.Dec.2010.pdf
Скачиваний:
74
Добавлен:
14.03.2016
Размер:
13 Мб
Скачать
☆

CHAPTER 21 ■ WRITING SECURE CODE

nodes will show up. Plus, node titles are user-submitted data, so they need to be sanitized before output. But as the code currently stands, it just gets the titles from the database and displays them. Let’s fix these problems.

function insecure_code($type = 'article') { $types = node_type_get_types();

if (!isset($types[$type])) {

watchdog('security', 'Possible SQL injection attempt!', array(), WATCHDOG_ALERT);

return t('Unable to process request.');

}

$output = "Searching for nodes of type: $type <br/>";

$query = db_select('node', 'n'); $query->fields('n', array('title')); $query->condition("n.type", $type); $query->condition("n.status", 1); $result = $query->execute();

$items = array();

foreach($result as $row) {

$items[] = check_plain($row->title);

}

if (sizeof($items) > 0) {

$output .= theme('item_list', array('items' => $items)); } else {

$output .= "No nodes were found of type $type";

}

return $output;

}

Now only unpublished nodes will show up, and all the titles are run through check_plain() before being displayed. We’ve also removed the debugging code. This module has come a long way! But there’s still a security flaw. Can you see it? If not, read on.

Keeping Private Data Private with hook_query_alter()

The preceding example of listing nodes is a common task for contributed modules (though less so now that the views module makes it so easy to define node listings through the Web). Question: If a node access control module is enabled on the site, where is the code in the preceding example that makes sure our user sees only the subset of nodes that is allowed? You’re right . . . it’s completely absent. The preceding code will show all nodes of a given type, even those protected by node access modules. It’s arrogant code that doesn’t care what other modules think! Let’s change that.

476

CHAPTER 21 ■ WRITING SECURE CODE

Before:

$query = db_select('node', 'n'); $query->fields('n', array('title')); $query->condition("n.type", $type); $query->condition("n.status", 1); $result = $query->execute();

After:

$query = db_select('node', 'n'); $query->fields('n', array('title')); $query->condition("n.type", $type); $query->condition("n.status", 1); $query->addTag('node_access'); $result = $query->execute();

We’ve added a “->addTag(‘node_access’)” to the $query parameter for our query that calls the hook_query_alter() function to modify the SQL so it obeys the access restrictions set by permissions.

Dynamic Queries

If you have a varying number of values in your SQL that cannot be determined until runtime, you should use the $query->condition(field, array of values, ‘IN’) statement to restrict your query to a dynamic list of values as defined in the second parameter. An example of using this technique is as follows:

//$node_types is an array containing one or more node type names

//such as article, page, blog, etc.

$node_types = array('article', 'page', 'blog');

// Prepare and execute the query using the list of node types $query = db_select('node', 'n');

$query->fields('n', array('title')); $query->condition("n.type", $node_types, 'IN'); $query->condition("n.status", 1); $query->addTag('node_access');

$result = $query->execute();

Permissions and Page Callbacks

Another aspect to keep in mind when writing your own modules is the access arguments key of each menu item you define in the menu hook. In the earlier example demonstrating insecure code, we used the following access arguments:

/*

* Implements hook_menu(). */

function insecure_menu() {

477

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]