Yii 1.1: Yii Security-extended guide


This article is called extended guide is because there is already a security guide in the Yii tutorial security section. but that guide is not complete in the sense that it does not rise the developers' attention to some other commonly happening attacks: SQL injection and magic URL, which can be major vulnerabilities in your application without much caring.

Warning: please do not consider this page as reference material. Its content is subject to caution. See comments at the bottom of the page.

SQL Injection

Sql injection is the most common attacks in the web application and has been ranked as the number 1 security issues by the OWASP. these attacks happen when you take input from users client side, and use it as a string in your raw SQL query. This attack can modify, delete data, and even exposes and manipulate all the sensitive data from the database.

One simple example could be:

"Select * from User where username=".$username;

This query is sinful because the attacker can easily inject query expression in the input $username which you take from client side. So imagin if user is capable of guessing your query and that user's input is "'john' or 1=1", then the whole query becomes:

"Select * from User where username='john' or 1=1";

and this query will return all the user data in your table, so attacker can do whatever they want with the data. This is a simple example, but it demonstrates very well of how the attack happens.

So the followings are some approachs to raise security guide:

  1. Input validation, do not trust any data from client side, always validate.
  2. Avoid write raw SQL statement in controller, if you have to, pay great attention to the input.
  3. Use prepared statment,in Yii, use methods in activeRecord or CDbCommand to pass $params.

Magic Urls

Another attack that you should pay attention to is the so called Magic Url. this attack happens when developers use parameters in the url as input and execute some operation on the server side. In particular, the architecture of Yii framework has opens the door to this attack. Without proper authentication guides and other countermeasures, attackers may be able to delete all the data you have in your database. so let's look at a concrete example:

Imagin you have a ImageController which contains common methods:

Class ImageController extends Controller{
    public function accessRules(){
         array('allow', 'actions'=>array('delete'),'users'=>array('*'),
    public function actionCreate(){
    public function actionDelete($id){

If you look at the structure, you can see that this controller allows authenticated user to perform the action delete. So one scenario would be that users click on the delete button under a image on the interface then the image record will be removed from database table. But wait, is this that simple? If you have knowledge about the http url, then a url for this delete action would probably be


or similar. It becomes clear now if your database design is just simply numerically increase the id for image records, then the obvious attack could happen just by simply changing the id value in the URL and remove the image record owned by another user, therefore this is a sinful code.

the followings are better some approachs to raise security guide:

  1. Authorized the operation by checking the role of the user, consider using Role-Based Access Control (RBAC).
  2. Avoid using get method when the result has side effect on the server side,use post instead and always check if it is a post request by checking: Yii::app()->request->isPostRequest
  3. Input validation if the parameter can be validate against the potential thread, do reluctance to trust user input.
  4. Raise the level of access rule, leave the least privilege to users.


Total 11 comments

#6194 report it
Sammaye at 2011/12/19 05:13am
I agree with the negative points

There is a lot of mis information here, for example magic URLs is not really a problem if you use bizrules (which you should) and so what if the user is able to manipulate a url to affect a row that they own? Other sites such as facebook etc actually allow this if you know what your doing, it is only when the user is allowed to effect rows not belonging to them you gotta start worrying. What you should of explained is how to prevent the problem of users effecting rows not related to themselves. I understand what you mean by this but you do not give a valid example really, nor do you explain the true problem which leads people to believe it only requires CSRF validation when in reality it is nothing to do with CSRF.

Not only that but GET is no more secure than POST (other than to hide plain text input from the user), the key is validation of the values and failure to instantly off the spot mass assign (like turning on the GLOBALS settings in PHP, it is never done now). POST does nothing more than change the method by which the data is transmitted so as to allow a much greater amount of data to be sent to the server since the browsers own address bar can only handle up to 4000 characters.

Also there is no difference to doing the SQL in the model than there is in the controller, that is a myth. The problem with injection comes from formation of the query string and the parameter sources you use, not where you place it. In fact I would consider putting all SQL into models bad practice because it does not really belong in the model, SQL really belongs on that page or to be more precise that controller action. That is where I would expect to find it.

Also find() and findby() are PDO accessible but they are also non-PDO accessible, you must use the $params param to actually get the PDO version of the command ( As I found out myself).

Also input validation should always be validated against a model, I am not sure what you mean by "the potential thread".

So your article is more badly explained than wrong but it is both at the same time.

#5883 report it
PrplHaz4 at 2011/11/22 02:27pm
Thanks for sparking the discussion....

I'd rather see the discussion play out...IMO, developing best practices is what leads to long-term adoption of a framework...

#5881 report it
bingjie2680 at 2011/11/22 11:39am
no more comments...

well, I think I do, but Cross-site Request Forgery attack happens cross site as the name reads. the Magic Url I am talking about here is only applying to the same domain attack and does not necessarily have anything to do with cookies.

anyway, thanks for your comment. this tutorial has too many negitive comments, I would like to remove this if it is possible.

#5878 report it
yangmls at 2011/11/22 06:38am
about Cross-site Request Forgery

Do you really know Cross-site Request Forgery? Do you really know csrf token?

#5877 report it
bingjie2680 at 2011/11/22 05:21am
people have problems with "Magic Urls"

if you have any doubt about the name "Magic Url", check out the book "24 deadly sins" chapter 4, this attack is diff from Cross-site Request Forgery, which is also presented in the book chapter 2

#5875 report it
yangmls at 2011/11/21 10:10pm
agree to Francois.Gannaz

Sql injection

the best solution is to use PDO methods (bindParams and bindValues), in Yii, You can use bindValue and bindParam

Magic Url

In fact, it is Cross-site Request Forgery...

You can read more about this CSRF Valition


#5846 report it
bingjie2680 at 2011/11/20 04:22am
reply to Francois

Hi Francois.Gannaz, Thank you for your comment.

Sql injection:

  1. Ok,
  2. I said avoid writing SQL in controller layer, not saying "do not write". do you not agree that placing SQL statement in Model layer is a better practice?
  3. Are find(),findAll() not like prepared statements? if not, then this is a security issue in Yii framework, don't you agree?
  4. I admit that this was wrongly explained.

Magic URl,

  1. does it matter what is called. I believe in 24 Sins book, it is called so.
  2. I only suggest that POST is more secure than GET in some way, I do not say in any way that it is secure.

If you have any other thoughts or ideas, you are very welcome to update and improve this article to share your knowledge.

#5845 report it
François Gannaz at 2011/11/19 07:45pm
Please do not believe what is written in this page (as of 2011-11-20)

Sorry, but I think this article's value is very low. For instance, the recommendations on the first part, SQL Injection, are mostly useless:

  1. OK
  2. Nonsense
  3. Wrong
  4. Wrong, $criteria->condition = "a=$userdata" is not secure, even if it's a string.

The most obvious solution is not even mentioned: when using SQL, use prepared queries whenever possible, like Post::Model()->findBySql($sql, $parameters) or $criteria->condition = "a > :first".

The second part isn't better. "Magic Url" are in fact called "backdoors" and the advice are plain wrong. For instance, POST is not a security improvment because post requests can be easily forged.

I'm really sorry, but I believe the whole page should be deleted and written by someone more experienced in security. It's safer to say nothing rather than wrong advice.

See this forum post for an answer to bingjie2680.

#5837 report it
bingjie2680 at 2011/11/18 04:23am
nothing guarantees 100% secure

it is still just "security through obfuscation", which is not secure at all.

@donfuego: Maybe I should use suggestion than countermeasure. but notice nothing posted here will guarantee your system secure, it is just a suggestion to be more secure.

#5836 report it
donfuego at 2011/11/18 04:15am
Be aware

Nice to see some efforts on security awareness. Also the first time i see OWASP being mentioned in conjunction with Yii.

However, there are some things that I'd like to point out (I'm not a security expert, I still consider myself a rookie on the subject), namely:

Under the 'Magic Url' paragraph above, you suggest using POST as a counter measure. While this certainly is better than using GET (since with GET, url parameters will easily be exposed in browser history, logs and referers), it is still just "security through obfuscation", which is not secure at all.

Using POST method, it is still possible for an attacker to send crafted HTTP requests to achieve the same result as with GET.

Using Yii's built in Authorization and accessControl is key here. Also, re-authorizing critical operations by forcing the user type the password again. I'd like to see built in support for this in the future.

#5833 report it
bonnie at 2011/11/17 06:00pm
Nice tips

Thanks for mentioning this. Am reality taking into account what you have mentioned here in my app am creating.

Leave a comment

Please to leave your comment.

Write new article
  • Written by: bingjie2680
  • Category: Tips
  • Yii Version: 1.1
  • Votes: +6 / -7
  • Viewed: 21,688 times
  • Created on: Nov 17, 2011
  • Last updated: Nov 22, 2011
  • Tags: security, tutorial, tips