Security for developers

Programming web applications in PHP brings with it a number of security issues which all MediaWiki developers should be aware of. Some of these are specific to PHP or to web development and will be surprising to developers who are not experienced in this field.

This document gives a brief introduction to the most common security vulnerabilities along with a list of best practices to help avoid security vulnerabilities.

The developer's responsibility
Websites vulnerable to issues like the ones discussed below are an important part of the illicit global infrastructure of malware, spam and phishing. Bot herders crawl the web for websites with security vulnerabilities, and use the vulnerabilities to hijack them. The hijacked website will distribute malware (viruses) to visitors, either via browser vulnerabilities or overtly by social engineering. The downloaded malware turns the client's computer into a "zombie", part of a global network of organised crime aimed at stealing bank account details, sending spam, and extorting money from websites with denial-of-service threats.

MediaWiki developers have a responsibility to avoid being a link in this criminal chain by ensuring that their coding style is secure.

Demonstrable security
It's not enough to assure yourself that you are perfect and that your code has no security vulnerabilities. Everyone makes mistakes. All core code, and a good deal of extension code, is reviewed by experienced developers to verify its security. This is good practice and should be encouraged.

So, write code in such a way that it is demonstrably secure, such that a reviewer can easily tell that it's secure. Don't write code that looks suspicious but is, on careful examination, secure. Such code causes unnecessary reviewer anxiety.

Overview of security vulnerabilities and attacks
This document has a strong focus on the following attacks or security risks. Each MediaWiki developer should be familiar with these issues and have at least a passing understanding of them.


 * Cross-site scripting (or XSS) relies on poor URL escaping to inject arbitrary JavaScript into an web application. For an XSS attack to be attempted, a user must be tricked into visiting a URL that the attacker has constructed. When successful, XSS attacks allow an attacker to run any JavaScript they wish with the same rights as the user.
 * Cross-site request forgery (or CSRF) uses web browser caching behavior to exploit vulnerabilities in a web application's security. CSRF attacks use authentication credentials cached in a victim's browser (such as a cookie or cached username and password) to authorize a malicious HTTP request. The malicious HTTP request can be sent in many ways. As long as the requests are processed by a web browser that has cached authentication credentials, a CSRF attack can be attempted.
 * Register globals is a deprecated feature of PHP. The feature causes data passed to a PHP script via cookies or GET and POST requests to be made available as global variables in the script. Register globals is convenient but extremely dangerous, often allowing an attacker to overwrite variables in a script simply by adding parameters to requests.
 * SQL injection uses vulnerabilities in an application's input validation or data typing for SQL queries. When successful, the attack allows the attacker to inject data into an existing SQL query. The attacker may then be able to fetch private data, cause a denial of service or cause other unintended responses. In the worst case, the injected code would allow the attacker to gain full control of the system by exploiting multiple vulnerabilities in the database server, system utilities and operating system.

Best practices
{| class="wikitable" | ! If you are working with ... ! have you ...



Any Part of MediaWiki

 * read the MediaWiki coding conventions?
 * read How to become a MediaWiki hacker?
 * examined this list carefully?
 * written your code to defend against register globals-based variable injection?
 * written your code to defend against register globals-based variable injection?



Cookies

 * used $wgRequest instead of ?
 * used $wgRequest instead of ?



Extensions

 * read the MediaWiki coding conventions?
 * put all global variables used by the extension into the extension's setup file?
 * put all global variables used by the extension into the extension's setup file?



Forms

 * used $wgUser->editToken to  implement anti-CSRF measures?
 * used or extended MediaWiki's existing form functionality?
 * used or extended MediaWiki's existing form functionality?



GET data

 * used $wgRequest instead of ?
 * used $wgRequest instead of ?



Global variables

 * written your code to defend against register globals-based variable injection?
 * written your code to defend against register globals-based variable injection?



Output (HTML/XML)

 * possible source of XSS
 * used the Html:: and Xml:: helper functions?
 * used the Html:: and Xml:: helper functions?



POST data

 * used $wgRequest instead of ?
 * used $wgRequest instead of ?



Query strings

 * See above



Sessions




SQL queries

 * escaped variables or used database wrappers?
 * escaped variables or used database wrappers?


 * }