Skip to content

Instantly share code, notes, and snippets.

@bencroker
Last active November 7, 2021 10:22
Show Gist options
  • Save bencroker/87a4b9337543f9c2b232225936e3920b to your computer and use it in GitHub Desktop.
Save bencroker/87a4b9337543f9c2b232225936e3920b to your computer and use it in GitHub Desktop.
Securing Front-End User Profile and Entry Forms in Craft (https://putyourlightson.com/articles/securing-front-end-user-profile-and-entry-forms-in-craft).
<?php
use craft\helpers\App;
return [
'id' => App::env('APP_ID') ?: 'CraftCMS',
'modules' => [
'field-permissions' => \modules\FieldPermissions::class,
],
'bootstrap' => [
'field-permissions',
],
];
<?php
namespace modules;
use Craft;
use craft\controllers\EntriesController;
use craft\controllers\UsersController;
use yii\base\ActionEvent;
use yii\base\Event;
use yii\base\Module;
use yii\web\ForbiddenHttpException;
/**
* Prevents disallowed custom fields from being saved in front-end user profile and entry forms.
*/
class FieldPermissions extends Module
{
const DISALLOWED_CUSTOM_FIELDS = ['subscriptionStatus', 'subscriptionExpiry'];
public function init()
{
/**
* Protects the `users/save-user` controller action.
*/
Event::on(UsersController::class, UsersController::EVENT_BEFORE_ACTION,
function(ActionEvent $event) {
if ($event->action->id == 'save-user' && Craft::$app->request->isSiteRequest) {
// The UsersController looks for custom fields in a param called `fields`, unless one is provided in a param called `fieldsLocation`.
$fieldsLocation = Craft::$app->request->getBodyParam('fieldsLocation', 'fields');
// Craft versions below 3.6.13 only allowed fields to be submitted via the `fields` param, so we force set this to avoid our checks from being bypassed.
if (version_compare(Craft::$app->version, '3.6.13', '<')) {
$fieldsLocation = 'fields';
}
$fields = Craft::$app->request->getBodyParam($fieldsLocation, []);
foreach ($fields as $key => $value) {
// Throw an exception if the field is disallowed.
if (in_array($key, self::DISALLOWED_CUSTOM_FIELDS)) {
throw new ForbiddenHttpException('One or more disallowed fields were submitted.');
}
}
}
}
);
/**
* Protects the `entries/save-entry` controller action.
*/
Event::on(EntriesController::class, EntriesController::EVENT_BEFORE_ACTION,
function(ActionEvent $event) {
if ($event->action->id == 'save-entry' && Craft::$app->request->isSiteRequest) {
// The EntriesController looks for custom fields in a param called `fields`, unless one is provided in a param called `fieldsLocation`.
$fieldsLocation = Craft::$app->request->getBodyParam('fieldsLocation', 'fields');
$fields = Craft::$app->request->getBodyParam($fieldsLocation, []);
foreach ($fields as $key => $value) {
// Throw an exception if the field is disallowed.
if (in_array($key, self::DISALLOWED_CUSTOM_FIELDS)) {
throw new ForbiddenHttpException('One or more disallowed fields were submitted.');
}
}
}
}
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment