Защита путей JSON-PATCH в Spring Приложению загрузки данных загрузки

Я использую симпатичную настройку vanilla spring-boot-starter-data-rest и включил метод PATCH. Все работает, но у меня есть проблема с безопасностью и задаюсь вопросом, какой рекомендуемый способ ее смягчить.

Проблема заключается в том, что PATCH path позволяет обновлять объекты, доступные для доступа, с другой конечной точки. Итак, предположим, что у меня есть конечная точка comments и конечная точка article. У каждого комментария есть одна ассоциация со своей статьей. Пользователь, имеющий разрешение на редактирование комментария, может тогда сделать что-то вроде этого:

PATCH http://some.domain.foo/api/comments/1234
Content-Type: application/json-patch+json

[
    { "op": "replace", "path": "/article/title", "value": "foobar2" }
]

и тем самым изменить заголовок статьи.

Ясно, что это не хорошо.

В этом случае для других частей API связь с "статьей" должна быть обходимой. Но он должен быть доступен только для чтения.

Итак... как это сделать в Spring?

Перехватить запрос? Внедрить метод обработчика? Создать собственный контроллер с нуля?

Спасибо!

Ответ 1

Кажется, что текущая реализация в spring -data-rest преобразует пути в SpEL для применения значений непосредственно на beans. См. PatchOperation (v2.5.x).

Рассмотрим следующие параметры:

  • Вместо json-patch используйте запрос json-merge PATCH для отправки частичных обновлений (с типом контента "application/json" или "application/merge-patch + json" ). Это будет уважать @JsonIgnore и другие аннотации Джексона, а также рассматривать ассоциации по-разному.
  • Вы можете полностью отключить json-patch + json, например, добавив фильтр безопасности
  • Вы всегда можете создать свою собственную реализацию json-patch, если она вам еще нужна
  • Использовать соединение на уровне приложения, не полагаясь на JPA, т.е. выставляя только идентификаторы связанных объектов и предоставляя настраиваемые ссылки в ResourceProcessor.

Кроме того, если вы используете JPA, а Comment.article аннотируется с помощью @ManyToOne, убедитесь, что при ассоциации нет каскадирования. Даже если объект статьи изменен с помощью патча, он не будет сохранен вместе с комментарием.