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 with security vulnerabilities are an important part of the illicit global infrastructure of malware, spam and phishing. Bot herders crawl the web looking for websites with security vulnerabilities, and then 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 and security risks. Each MediaWiki developer should be familiar with these issues and have at least a passing understanding of them.

Cross-site scripting (XSS) vulnerabilities allow an attacker to inject malicious code into a website. XSS vulnerabilities are caused by a web application not properly escaping data from external sources (such as GET data, POST data, RSS feeds or URLs). The range of attacks that can be made via XSS are very diverse, ranging from harmless pranks to the hijacking of an authenticated user's account.

Cross-site request forgery (CSRF or XSRF) 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 extremely dangerous, often allowing an attacker to overwrite variables in a script simply by adding parameters to requests. Register globals may be enabled on servers where MediaWiki is installed and MediaWiki developers must write their code to defend against register globals-based variable injection.

SQL injection relies on poorly validated input being used in a database query, possibly allowing an attacker to run arbitrary SQL queries on your server. The attacker may then be able to fetch private data, destroy data or cause other unintended responses. In the worst case, the injected code could 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
Every developer should be familiar with the MediaWiki coding conventions and the How to become a MediaWiki hacker article.

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



Cookies

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



Extensions

 * put all global variables declared by the extension into the extension's setup file?
 * put all global variables declared 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 (API, CSS, JavaScript, HTML, XML, etc.)
Any content that MediaWiki generates can be a vector for XSS attacks.
 * 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?


 * }