These are the slides from the security presentation. Visit the s5 version to see them as a presentation.
Greg Knaddison and James Walker
Drupaloop, baby
- Why?
- Config?
- Coding?
- Process
- Q (hopefully A)
Why bother
- Who has had a site cracked?
- Who has had a server cracked?
- More popularity brings more eyes reviewing code - brings more desire to crack and build worms
Authentication
- Verifying digital identity of user
- Brute Force - guessing passwords
- Insufficient Authentication - only ask for email instead of email plus password
Authorization
- Checking permissions of an authenticated user
- Insufficient Authorization - permission is too lose
Client-side attacks
- Cross site scripting - XSS
- Cross site request forgery - CSRF
Command Execution
- SQL Injection
Information Disclosure
- Information Leakage
- Directory Indexing
- Predictable Resource Location
if (typeof jQuery == 'function') {
jQuery.get('/user/1/edit',
function (data, status) {
if (status == 'success') {
var matches = data.match(/id="edit-user-edit-form-token" value="([a-z0-9]*)"/);
var token = matches[1];
var payload = {
"form_id": 'user_edit',
"form_token": token,
"pass[pass1]": 'hacked',
"pass[pass2]": 'hacked'
};
jQuery.post('/user/1/edit', payload);
}
}
);
}
Secure Configurations
Drupal permissions - “be careful - test”
Input formats - http://drupal.org/node/224921
File permissions - http://drupal.org/node/117054
PHP Filter - don’t use it
Be a Secure User
- Use a good, unique password
- Beware unencrypted WiFi
- Use ssh/keys instead of FTP
- Be careful with UID 1
Security related modules
http://drupal.org/project/phpass
http://drupal.org/project/single_login
http://drupal.org/project/httpbl
http://drupal.org/project/paranoia
http://drupal.org/project/password_policy or http://drupal.org/project/password_strength
http://drupal.org/project/persistent_login
http://drupal.org/project/phpids
Writing Secure Code
Use the APIs luke.
FAPI
Ensures form selections were provided to user
Protects against CSRF
- NO: <FORM ACTION=”“>
- YES: drupal_get_form($form_array);
- Forms API Introduction
- Forms API Reference
- Forms API Diagram
t()
Protects against XSS
- SAFE: t(‘I escape %user_data’, array(‘%user_data’ => $data));
- I escape user_data (safe)
- SAFE: t(‘I escape @user_data’, array(‘@user_data’ => $data));
- I escape user_data
- XSS vulnerability: t(‘I do not escape !user_data’, array(‘!user_data’ => $data));
- I do not escape user_data
checkplain(), filterxss()
- NO: print $user_data;
-
YES: print check_plain($user_data);
-
check_plain - to be used when inserting plain text in HTML
- check_markup - to be used when inserting rich text in HTML
- filter_xss - to remove all but whitelisted tags from text inserted in HTML
- filter_xss_admin - shortcut to filter_xss with a permissive tag list, used to output admin defined texts.
drupal_render()
- NO:
$node = node_load($nid);
print $node->body; - YES:
$node = node_load($nid);
print node_view($node);
content_format()
- NO:
print $node->field_content_something[0][‘value’]; - YES:
print content_format(‘field_content_something’, $node->field_content_something, $formatter = ‘default’, $node = NULL);
db_query()
- NO:
db_query(“SELECT * FROM {table} WHERE someval = ‘$user_input’”); - YES:
db_query(“SELECT * FROM {table} WHERE someval = ‘%s’”, $user_input);
dbrewritesql()
- NO:
db_query(“SELECT * FROM {node}”); - YES:
db_query(db_rewrite_sql((“SELECT * FROM {node}”));
Proper use of these functions will solve the most common issues.
See http://drupal.org/writing-secure-code for more information.
When in doubt, ask.
Goals and Processes
- Protect Drupal sites secure from Zero Day exploits
- Be really quiet, then really loud
- Promote security practices in core and contrib
- Make defaults and “proper” use of APIs secure
- Provide docs and examples
- Facilitate fixes for contrib (not scanning, necessarily)
- Intake of reports, pass information along, provide guidance, make announcements
Report a Problem
- Contact form or security@d.o
- Report a security issue guide
- Report a cracked site guide
Contrib Module Workflow
- Issue gets reported (keep it quiet)
- Security team works with maintainer to get a fix
- Fix is released in next bundle of fixes (be loud)
Policies:
Cover core and contrib under basically the same process
Only create SAs if:
- Module has a stable release
- Or, it has a developer release but is very popular
Only current and last version are supported. This could be changed if enough volunteers stepped forward, but that has proven unlikely so far.
Q?
A (hopefully)





In the example: print
In the example: print content_format(‘field_content_something’, $node->field_content_something,…
There is no “content_format” function at api.drupal.org. Was this an example function or something from a module? In this situation wouldn’t you use check_markup?
content_format is a cck
content_format is a cck function, not a Drupal core function.
I was confused by that at first myself.
Thanks for reminding me to highlight this situation.