Fix Business Logic Errors in Yii
Business logic vulnerabilities in Yii applications typically manifest when developers assume that the client-side state or user-provided identifiers are immutable and authorized. These flaws—ranging from Insecure Direct Object References (IDOR) to state machine bypasses—allow attackers to manipulate data they don't own or trigger transitions that should be restricted. In Yii, the battle is won by moving authorization from the UI layer directly into the Active Record query and implementing strict state validation.
The Vulnerable Pattern
public function actionUpdate($id) { // VULNERABILITY: This trusts the $id parameter without verifying ownership. // An attacker can change the 'id' in the URL to modify any user's profile. $model = Profile::findOne($id);if ($model->load(Yii::$app->request->post()) && $model->save()) { return $this->redirect(['view', 'id' => $model->id]); } return $this->render('update', ['model' => $model]);
}
The Secure Implementation
The vulnerable code relies on 'Security by Obscurity' or assumes the user will only interact with the UI provided. By using Profile::findOne($id), the controller fetches any record matching that primary key. The secure implementation enforces 'Ownership Scoping' by chaining the query with 'user_id' => Yii::$app->user->id. If the ID belongs to another user, the query returns null, and we throw a 403 Forbidden. For complex logic like price changes or status updates, always use Yii's 'scenarios' to whitelist attributes and 'BeforeSave' hooks to validate business rules (e.g., ensuring a 'Paid' order cannot be downgraded to 'Pending' by a POST request).
public function actionUpdate($id) { // FIX: Use a scoped query that includes the current user's ID. // This ensures the model is only found if it belongs to the authenticated user. $model = Profile::find() ->where(['id' => $id, 'user_id' => Yii::$app->user->id]) ->one();if (!$model) { throw new \yii\web\ForbiddenHttpException('You are not allowed to edit this profile.'); } // Additionally, use scenarios to prevent mass assignment of sensitive fields $model->scenario = Profile::SCENARIO_USER_UPDATE; if ($model->load(Yii::$app->request->post()) && $model->save()) { return $this->redirect(['view', 'id' => $model->id]); } return $this->render('update', ['model' => $model]);
}
Your Yii API
might be exposed to Business Logic Errors
74% of Yii apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.
Free Tier • No Credit Card • Instant Report
Verified by Ghost Labs Security Team
This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.