Cross-site scripting Cross-site scripting (XSS) refers to a large classification of vulnerabilities that focus on the ability

to present malicious code to an unsuspecting user. This usually takes the form of malicious JavaScript, which could do anything from annoying the user to capturing data from cookies. At the heart of the XSS vulnerability is an application that filters user data improperly once submitted. For example, suppose you're building an application with a forum and did no filtering against the user data. Anything submitted for a forum post could be displayed. As an evil user, suppose I submit the following text as a forum post: <script>alert("EXPLETIVES!!!")</script>. If the application permits this text, anyone who viewed my post would get a JavaScript alert box that shouted expletives at them. While not particularly harmful, it's certainly not something you want the boss to see. This is a very simple example of a harmless XSS exploitation. While this example is fairly harmless, XSS is anything but. XSS has been used to steal passwords, steal credit card numbers, forge news stories, and much more. Protecting yourself and your application from XSS is important. CakePHP can help you do so. Spamming Meaning: Overloading a system through excessive traffic can lead to denial of service for other users or system failure. This can happen if you allow a bot to post public accessible forms (registration etc). He could sign up millions of users in just a few hours filling your database tables to the outer limit. You can use timeouts or captchas to prevent this (careful: try not to use session based stuff because bots change their session all the time). Timeouts also prevent “brute force / dictionary attacks”. Another cake-related overloading attempt: “limit” on pagination. Anybody who knows that CakePHP is used, could simply append “/index/limit:1000000″. If there actually are that many entries it will most certainly cause excessive traffic. Currently you have to implement this yourself.

SQL injection A SQL injection vulnerability occurs when a user is able to pass SQL code directly to the application in such a way that the code will be executed in a query. For example, the user is presented with a login screen, in which the user name and password is entered. The password variable might be used in the query "select * from users where username = '" + $username + "' and password = '" + $password + "'" Consider what would happen if the user submitted the following password: ' or '1' = '1. The final SQL statement might look something like "select * from users where username = 'zaphod' and password = 'secret' or '1' = '1'" Not checking for SQL-specific characters can open your application up to a wide range of vulnerabilities. Properly used, Cake can make it easy to protect your application from this type of vulnerability. Session hijacking session hijacking is the exploitation of a valid computer session—sometimes also called a session key—to gain unauthorized access to information or services in a computer system. In particular, it is used to refer to the theft of a magic cookie used to authenticate a user to a remote server. It has particular relevance to web developers, as the HTTP cookies used to maintain a session on many web sites can be easily stolen by an attacker using an intermediary computer or with access to the saved cookies on the victim's computer (see HTTP cookie theft). A popular method is using source-routed IP packets. This allows a hacker at point A on the network to participate in a conversation between B and C by encouraging the IP packets to pass through its machine. If source-routing is turned off, the hacker can use "blind" hijacking, whereby it guesses the responses of the two machines. Thus, the hacker can send a command, but can never see the response. However, a common command would be to set a password allowing access from somewhere else on the net.

A hacker can also be "inline" between B and C using a sniffing program to watch the conversation. This is known as a "man-in-the-middle attack". A common component of such an attack is to execute a denial-of-service (DoS) attack against one end-point to stop it from responding. This attack can be either against the machine to force it to crash, or against the network connection to force heavy packet loss. There are four main methods used to perpetrate a session hijack. These are: 1. Session fixation, where the attacker sets a user's session id to one known to him, for example by sending the user an email with a link that contains a particular session id. The attacker now only has to wait until the user logs in. 2. Session sidejacking, where the attacker uses packet sniffing to read network traffic between two parties to steal the session cookie. Many web sites use SSL encryption for login pages to prevent attackers from seeing the password, but do not use encryption for the rest of the site once authenticated. This allows attackers that can read the network traffic to intercept all the data that is submitted to the server or web pages viewed by the client. Since this data includes the session cookie, it allows him to impersonate the victim, even if the password itself is not compromised. Unsecured Wi-Fi hotspots are particularly vulnerable, as anyone sharing the network will generally be able to read most of the web traffic between other nodes and the access point. 3. Alternatively, an attacker with physical access can simply attempt to steal the session key by, for example, obtaining the file or memory contents of the appropriate part of either the user's computer or the server. 4. Cross-site scripting, where the attacker tricks the user's computer into running code which is treated as trustworthy because it appears to belong to the server, allowing the attacker to obtain a copy of the cookie or perform other operations.

Methods to prevent session hijacking include: 1. Encryption of the data traffic passed between the parties; in particular the session key, though ideally all traffic for the entire session by using SSL/TLS. This technique is widely relied-upon by web-based banks and other e-commerce services, because it completely prevents sniffing-style attacks. However, it could still be possible to perform some other kind of session hijack. 2. Use of a long random number or string as the session key. This reduces the risk that an attacker could simply guess a valid session key through trial and error or brute force attacks. 3. Regenerating the session id after a successful login. This prevents session fixation because the attacker does not know the session id of the user after he has logged in. 4. Some services make secondary checks against the identity of the user. For example, a web server could check with each request made that the IP address of the user matched the one last used during that session. This does not prevent attacks by somebody who shares the same IP address, however, and could be frustrating for users whose IP address is liable to change during a browsing session. 5. Alternatively, some services will change the value of the cookie with each and every request. This dramatically reduces the window in which an attacker can operate and makes it easy to identify whether an attack has taken place, but can cause other technical problems (for example, two legitimate, closely timed requests from the same client can lead to a token check error on the server). 6. Users may also wish to log out of websites whenever they are finished using them. However this will not protect against attacks such as Firesheep. Security component Case: Let us consider the basic example of 2-tier architecture (employs only two types of hosts: clients and servers). Now whenever the data is transferred from the server to client, let us say a web form asking some information to process something, then that data can be easily modified by

saving that form locally and modifying some attributes of that form. This form can be easily submitted back to the server by inputting some unexpected values. And it is better not to think about what (weird thing) can happen later on, if input from (the malicious) user is not filtered properly. By this way, the web forms can be easily tampered or spoofed leaving your application unprotected. Solution: The ultimate solution over this problem is to keep track of the data before it gets sent to the client by calculating the hash of the form fields. If the form attributes get altered, then ultimately the hash will also gets changed resulting the mismatch of the hashes after the form submission. This is what the Security Component in CakePHP exactly does! The Security component will create a hash based on the form fields produced by our Form Helper. If someone tampers with the form fields (by adding or removing or changing any field), the hash is not going to match with the expected one and call to the form action will get fail. So far, so good. Let us see an example. In my basic Blog application, I need to provide security to my comments section as many users leave comments using this section and may pass some malicious data from right here. So, I’ll go ahead and add a Security component in my CommentsController as follows: class CommentsController extends AppController { var $name = 'Comments'; var $components = array('Security'); public function add() { if (!empty($this->data)) { $fieldList = array( 'name', 'email', 'comment', ); $this->Comment->save($this->data, $fieldList); } }//end add() }//end class

If $fieldList is not supplied, a malicious user can add additional fields to the form data (if you are not using Security component), and by this, change fields that were not originally intended to be changed. Hence it is a good practice to always pass an array of $fieldList while you save the data. And guess what.. Our form is secured by this step. How??? It is just because we’ve added a single line in the controller where we’ve added the Security component. Now, the next step is to create a simple view add.ctp to add a comment which will consist of the three fields ‘name’, ‘email’ and ‘comment’. echo $this->Form->create('Comment', array('url' => array('action' => 'add')); echo $this->Form->input('name'); echo $this->Form->input('email'); echo $this->Form->input('comment'); echo $this->Form->end(__('Submit', TRUE)); Lets us see what it actually does. The Security component works in conjunction with the FormHelper. It automatically inserts the hidden token fields into the form and checks it. In addition, it will not allow the form to be submitted after certain period of inactivity, depending upon the setting of Security.level in core.php file. If the form gets tampered then the application will return a blank screen in most cases unless and until we handle that error and display a custom message to the user. Basically, if the action is restricted by the security component, then it is black holed (black listed for that moment) and results into HTTP 404 error. And we can handle this thing by using the blackHoleCallback property of the Security component in the beforeFilter action. //This function gets called before any action in the controller gets called public function beforeFilter() { $this->Security->blackHoleCallback = 'error'; }

//This function is called by the blackHoleCallback property of security component public function error() { $this->cakeError('accessDenied'); }//end fail() In the error method, we are just calling the error method named accessDenied which will be responsible to display some nice error message. For that, you’ll need to define this action in the app_error.php file in your /app directory. This is the place where you can define your customized error handling functions. Create this file if you do not have one. class AppError extends ErrorHandler { public function accessDenied() { $name = array('name' => __('You are not authorized to perform this action', TRUE)) $this->controller->set($name); $this->_outputMessage('denied'); }//end accessDenied() }//end class And now the very last step is to create the denied.ctp file which is the view file for our error message. Path of this file will be app/views/errors/denied.ctp. <h2><?php echo $name; ?></h2> <div class="error"> <strong><?php __('Access Denied!'); ?></strong> </div> In this way, if the form gets tampered, the malicious user will get the error message as mentioned above. The Security component has some more nice properties and methods which provides developers some additional features like secure SSL authentication and many more things which are very simple and handy to use.

Input Saving Model Data and Security,covers some aspects of the saving process. You are even quicker if you include the Security Component in the app controller. This automatically takes care of form manipulation and other things like Cross-Site Request Forgery (CSRF). Cake already takes care of the usual risks by escaping all queries (except for the manually built ones). Some use Sanitize or other things prior to the save to ensure that the content is stripped of any harmful strings. I dont think this is a good approach. At least not in general. Usually the user wants to post something which intentionality consists of some special characters. He would be quite upset if all kinds of things are stripped out just because the developer felt like it. It’s overkill and unnecessary for text input. On the other hand, if you allow HTML (with a wysiwyg editor?), you cannot escape the output. Therefore it makes sense in this case to protect your site with something like “htmlpurifier”. My opinion is: ONLY validate, do not sanitize or strip things off the input. You have plenty of time to do that on output. The other part is the view and potential risks from xss attacks etc. It is actually simpler than you might think. All CakePHP helpers already escape by default ($this->Html->link() for instance). If you output database content directly in the view you need to escape those text strings manually, though. This is done with the h() function (conv. function of htmlspecialchars): echo h($model['Model']['comment']); No matter what the user posted, it is now harmless (javascript, xss stuff). Many forget that even image titles or alt attributes must be escaped. So if you don’t use the helper for it, escape manually. A good testing environment has always some of those “bad strings” in the database. Just insert some of the first examples on this XSS site. If you don’t get “alerts” in your views, you know that you did everything right. I once wrote a lib + shell script that extracted all those xss strings (xml is available) and automatically added them to the specified model. After calling the “index” overview I found out that nothing happened – which is always a good sign in this case.

Flash messages are often forgotten, as well. If you use user input in them, escape it: $name = $this->data['Model']['title']; $this->Session->setFlash(sprintf(__('record \'%s\' saved', true), h($name))); // prints "record {title} saved" POST/GET To protect yourself from a very unpleasant attack which can make you delete all kinds of content, you should always ensure that database modifications (INSERT, UPDATE, DELETE) can only be triggered by POST actions (ajax or not ajax). This is not for no reason the specification for HTTP. “GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval“. Currently – using the default bake templates – you would allow DELETE simply by calling “/controllers/delete/ID”. So you might want to customize your scripts. Use a form submit button to post to the url (or jquery) and blackhole the request if it is a GET request. What can happen if you don’t follow the specification? If you don’t allow any HTML probably nothing. But let’s assume you allow BBCode or HTML – both properly sanitizes/cleaned. I will give you one example with “comments” on a blog post. The result of the user comment might be: <b>Blablabla</b>, <img src="/admin/users/delete/3" /> FooBar. Normal users will just see a scrambled image (because they don’t have the admin role). The url can only delete a user if you are currently logged in as an admin. Note: An image tag ALWAYS assumes that the src is valid. It will call anything you put in there as url. Even urls that aren’t any image. So the url redirects inside the image tag (no access without admin role). Ok, but now the admin logs on and checks out the post. Well, he DOES have the right to delete users. And therefore the img tag automatically deletes the user (because GET requests are allowed). The admin doesn’t even notice. Combine some of those delete actions and you can really mess things up. Especially if cascading is on and all kinds of user related content (users hasMany posts, …) is removed as well. Miscellaneous

Be especially careful with user submitted data or $_GET params if they are about file names, urls or similar system related information. They can have ../../ in them which could lead to vulnerabilities. Webserver If you host the website on a managed server or even a root server, you need to make sure that the server is secure. That includes the following: 1. Keep the packages up to date (“apt-get update” + “apt-get upgrade”) 2. Register Globals OFF, Magic Quotes OFF (Cake handles this!) 3. Hide your exact server version with ServerSignature Off

Sign up to vote on this title
UsefulNot useful