The Secured Yii Initiative

Hi!

I’ve been trying out Yii recently and found it very neat. One thing that concerns me though is the security. While there are already some pretty good security mechanisms built-in, there is lots of room for improvement and more security features.

Why recreate the wheel?

What I have in mind is basically to improve the framework security-wise to be more secure and offer more security features “out-of-the-box” so that everyone doesn’t have to recreate the wheel when trying to make their applications as secure as possible. This will ultimately result in audited code that is well tried and tested by many developers.

Since I’m not an expert in neither Yii or Web app security in general, I call upon the experts on this forum to join in and share their knowledge in this joint effort. I know there are many experienced and knowledgeable Yii programmers out there. Don’t be shy! =)

The goal

  • To security-wise improve all aspects of Yii, step by step, closely following the OWASP guidelines (see their "cheat sheets") and other "industry standard" methods to mitigate and remedy common web app vulnerabilities, while still keeping the Yii framework as "untainted" as possible.

Again, I call upon experienced developers to share their suggestions on how to best achieve this. Depending on the requirements the final result will be available as one or more Extensions and/or code patches.

  • To provide Example Code and Documentation of the added functions/features.

  • To raise general awareness and knowledge of Web App security.

  • To make Yii the most secure choice among web frameworks.

  • To have the final results implemented in future releases of the Yii framework.

How to get there

  • By having open discussions and commitments in this thread, evaluating methods, code and best practices. Perhaps creating a "live" Wiki page further down the road. If anyone have suggestions on how to organize this, please share. Expect things to get a bit chaotic at first!

  • To try keeping things focused, I suggest closely following the OWASP Master Sheet step by step.

Does this sound appealing to you?

Basics first

But before digging in to the Master Sheet, I’d like to start with some fundamentals: Input and Output sanitizing. Yii currently provides the HTML Purifier through the class CHtmlPurifier, which is a powerful tool, together with a bunch of Validator classes (see system.validators) but how do we best use them? I think we can agree that it depends on the context. Some times we want to filter SQL characters from the input, some times we need to filter HTML and script tags. Sometimes both! Sometimes none.

[list=1]

[*]Can we use CHtmlPurifier in all cases or are there need for other solutions/options?

[*]How about PHP’s filter_var for example?

[*]Can we use the built-in Validators and rules to decide when and how to filter input fields in a easy way?

[/list]

I will stop here for now. Fire away!

Agree, Yii needs some security revisions (I didn’t like some things I’ve seen :)). Proposed method: listing all known weaknesses in all layers and plugging them :).

I’ll start:

Sessions

  • fixation

  • hijacking

  • shared hosts

  • ?

all readily fixed.

Maybe implement some 2 way identification like a get var with hash(ip+useragent+…+randomval) in combination with the auth cookie.

Also default config should be security optimised and I think like, if using cookies only use cookies, default enable csrf/cookie validations etc.

While it’s a tempting approach, I think it will be hard to find all issues (there might be unknown issues) this way. Using the OWASP as reference will certainly be more tedious, but we can be sure to cover most topics and pitfalls.

Session management is perhaps one of the most critical aspects of web applications and having a good protection against session related attacks is crucial. I suppose the core problem lies in the difficulty to create a truly unique Session ID that can not be predicted (or brute forced). Instead one has to rely on other methods making the probability of succeeding an attack as little as possible. Yii is by default using PHP session management at large, and I’ve briefly noted some default weaknesses, such as:

  • Session ID reuse

  • Cookie persistance

  • Default parameter name (PHPSESSID) for Session ID

  • HttpOnly flag not set

  • Secure flag not set

Also, we need to detect and provide early counter measures of an attack. Perhaps the PHPIDS project and extension can be useful. I have not looked into it yet. Perhaps someone already got experience from using it?

The thing is not just that Yii doesn’t offer enough protection, the thing is that many developers don’t abuse the security layers Yii offers and the extensions created for this, here is the huge problem.

Maybe they think at performance penalties, dunno, but having a broken/exploitable app is better than having a slower app ?

Because Yii is so huge, it takes time to learn how to use its components properly, then the security is placed at the end of the to do list, hence the problems in applications.

Some key features in having a decent secured app:

*) Use all the security features Yii provides, and i mean everything, cookie encryption/csrf validation etc etc

*) The place of the sessions is in database, ALWAYS. (see my extended session class for more security)

*) Filter the user input, everytime, doesn’t matter where it came from GET/POST etc(see my input extension for a good start).

*) Validate the input, everytime, if you require an integer, make sure you receive one (Yii validators will be used here for validating models and common sense validation for other input type)

*) Always bind params when quering the database, don’t just throw the $variable there and expect to be fine. Filtering the input doesn’t mean that your queries are going to be safe, you need to watch out for both cases.

*) Make extensively use of the CHtml class when generating output.

*) Don’t echo without CHtml::encode(), just don’t(only if you need to echo html content).

*) When uploading files, make sure you check the mime type using finfo extension or exec(‘file -ib’) if you have shell access and finfo is not installed, never trust the extension.

If you only allow images, getimagesize() is a good php function to check the file.

*) If for some reasons you need to pass system paths via get/post(you better don’t) then make sure that when using those variables they still point to the place where you need them to point.

*) Use https if you can.

Hi

I tried to put most of what I knew on security and Yii in a single web page. This is in Yii’s wiki: How to write secure Yii applications.

This is still “work in progress”, and there’s an ominious FIXME-TODO on the last section of “SQL injections”.

I’d be glad if you could have a look at this. I’m not a native English speaker, so there will probably be quite a few language mistakes. And of course, if you see how the content could be improved, feel free to enhance it (this is a wiki!). If it is a major change, I’d prefer if you discussed it with me before (at least while the page is in this unfinished state). I’m also open to suggestions and criticism.

I tried to follow a few principles that donfuego wrote here. For example, I think like him that examples are very important, so I tried to put as more examples than general text. But I followed my own plan instead of OWASP’s, starting with generalities and simple things. I tried to put only what had a large consensus. For instance, I know some will disagree, but “sessions must be in the DB, final” are not a unanimous idea, and you won’t find it in Chris Shiflett or Illa Ashanetsy’s books.

I like to elaborate on why I prefer the ‘attacker’ point of view on securing applications: first of all, it’s the way most attacks will take place, also it will provide a better ‘to-do list’ (yes this will be a lot of work putting together attack vector matrices) of security issues to check off, making it more robust, complete etc.

That’s why I suggest security (relevant to Yii) be subdivided in all sorts of potential issues (cookies (stealing, maybe via XSS,encryption,fingerprinting…),XSS,CSRF,sessions (see my prev post),general design patterns,…), their weaknesses and countermeasures.

It would be nice to have a complete exhaustive list of all possible (webrelated) attacks and countermeasures, maybe ask santa?

edit:

The wiki article from above is great start but I have some remarks (not critics :)): general principles contains things specific to Yii, I would move all these Yii-related stuff under issue/weakness/countermeasure.

The stuff about configuring options (.htaccess, Yii options,…) should probably be structured like config/webserver/apache, config/yii. So my proposed TOC is something like:

*intro

*issues

**issue1 (xss)

***countermeasure1 (CHtmlPurifier)

***countermeasure2

**issue1a

***see countermeasure1+…

** …

*config

**yii

**webserver

***apache

Ok, I’ve read through the article as well as this thread and would like to make some remarks:

The section about logging needs to be extended. Especially since it is so important. It should also be noted that PHP’s E_WARN is quite different from Yii’s “warn” loglevel. (Btw: I’m pretty sure Yii’s error reporting will raise an exception if it encounters an E_NOTICE in debug-mode).

It would also be an idea to mention that the protected directory can be moved outside of the webroot entirely (there’s another wiki article that covers this in detail but I cannot seem to find it atm). It just takes a modification to the config and the bootstrap’s index.php. Also: application.data does not always need to be writable by the webserver. This is really only the case if the default CPhpAuthManager is being used which relies on protected/data/auth.php being writable. You can either modify CPhpAuthManager.authFile or use the CDbAuthManager instead (which is recommended for larger applications since it tends to scale better).

Regarding password encryption: I wrote this article a while back which is covering the usage of phpass from within Yii in a little more detail. It’d be nice if you could at least point to it ;)

In general it might be a good idea to split that article up: Leave the current one to safe coding practices and sane application layouts and write a second one for safe deployments. Later one could include system, webserver and database security and focus on the usage of advanced security measures like system security frameworks (SELinux, AppArmor) and application-level firewalls (mod_security, suhosin, php-ids).

In any case it should be pointed out more clearly, that:

[list=1]

[*]Yii itself provides the means (in most cases) to create secure applications but it remains the programmer’s responsibility to establish/maintain application security

[*]a “Let’s do it all at once”-approach concerning security can be rather harmful. Security needs need to be identified and evaluated carefully.

[/list]

Especially the "everything via https"-approach is rather questionable: While it is entirely out of question that sensitive data (login credentials, payment informations) must be encrypted, delivering all the content via https means a lot of stress for the webserver. So check if you really need this.

Then: The default session driver in Yii does not protect against session surfing/hijacking. There’s this extension improving the situation a bit. To take the heat off the Yii devs: The default handler is that “insecure” for design decissions. Too strict session checks will lock proud owners of dynamic IPs or people behind NATs out of your app.

Oh, and if you’ve got a solution to cookie-theft, please let me know. The “best” one I came up with so far has been to take a very long seed, append the /16-part of a user’s IP and take this as a key to encrypt the cookie’s content via twofish. Obviously this concept will work better after the glorious mass-deployment of IPv6. But until then … ::) I don’t have an implementation for Yii handy. But it shouldn’t be too hard by extending CCookieCollection and CHttpRequest. (Btw. A great point is: If a part of Yii is too insecure for you, just inject your own!)

Well, that’s all for now B)

Maybe we could use OWASP’s Top 10 list as a starting point. Troy Hunt did a nice guideline for .net developers based on the OWASP Top 10. It’s written like a tutorial. The top 10 changes slightly every few year but still not much, so just picking the current year and spelling out how to remedy each of the top 10 would probably solve most issues and still be good for years. They only update the list every few years anyway.

I just wanted to clarify that I really like the wiki article: How to write secure Yii applications.

The suggestion about OWASP was because the OWASP site is a common resource for web site security. I can just imagine someone reading through the Top 10 and thinking: “Now how do I apply that to my Yii Framework site?” I think it would be great to have something to help along those lines. I’m actually working on my own list but I’m not sure I’m really the man for the job… I don’t really have the experience with the Yii Framework.