Предотвращение случайной сериализации моделей ActiveRecord

Мы внедрили патч, предотвращающий случайную сериализацию моделей ActiveRecord без указания полей для сериализации. Это изменение позволяет контролировать, какие поля включаются в результат, избегая потенциальных проблем с раскрытием неполных или избыточных данных.

По умолчанию при рендеринге модели ActiveRecord в JSON включаются все атрибуты, что во многих случаях нежелательно. Чтобы обеспечить более правильные практики, необходимо явно указывать, какие поля следует сериализовать.

Примеры использования

Неверное использование:

def show
  @user = User.first
  render json: @user
end

В среде разработки и при тестировании это приведёт к следующему:

ActiveRecordSerializationSafety::BlockedSerializationError:
Сериализация моделей ActiveRecord (User) без указания полей не разрешена.
Используйте Serializer или передайте опцию :only в #serializable_hash. Подробнее: https://meta.discourse.org/t/-/314495
./lib/freedom_patches/active_record_disable_serialization.rb:15:in `serializable_hash'

Правильное использование:

  1. Использование Serializer
class UserSerializer < ApplicationSerializer
  attributes :id, :email
end

def show
  @user = User.first
  render json: @user, serializer: UserSerializer
end
  1. Использование опции :only
def show
  @user = User.first
  render json: @user.as_json(only: [:id, :email])
end

Этот документ находится под контролем версий — предложите изменения на github.

6 лайков

Для уточнения тем, кто может столкнуться с этим на практике: это означает, что любое использование методов сериализации в ActiveModel::Serialization, например as_json, независимо от контекста (включая тесты), приведёт к ошибке, если не передан параметр only. Подробнее:

Пример:

5 лайков

Пост был разделён на новую тему: Помощь с новыми защитами сериализации

Что ж, прошло 21 день, но я наконец разобрался в том, что вы написали здесь в связанном коде, по крайней мере в одном контексте, и надеюсь, что и в другом, упомянутом в разделе выше. Этот второй кажется сложнее (по крайней мере, по моей памяти), так как я не совсем понимаю, где именно проблема.

Спасибо, что спасли день (или хотя бы этот день). :beers:

Другая проблема заключалась в том, что моя модель server включала модель user, и мне нужно было вызывать сериализатор пользователя (или ограничивать поля) модели пользователя в сериализаторе сервера.

Оказалось, что мне вообще не нужна была модель пользователя в модели сервера (user_id уже был там, и есть вполне вероятная возможность, что даже это мне не нужно).

1 лайк