«Безопасно by Design» не похожа на другие книги по безопасности. В ней нет дискуссий на такие классические темы, как переполнение буфера или слабые места в криптографических хэш-функциях. Вместо собственно безопасности она концентрируется на подходах к разработке ПО. Поначалу это может показаться немного странным, но вы поймете, что недостатки безопасности часто вызваны плохим дизайном. Значительного количества уязвимостей можно избежать, используя передовые методы проектирования. Изучение того, как дизайн программного обеспечения соотносится с безопасностью, является целью этой книги. Вы узнаете, почему дизайн важен для безопасности и как его использовать для создания безопасного программного обеспечения.
Использование при проектировании изменяемых объектов, которые не должны быть таковыми, может показаться очевидной ошибкой, но ее допускают даже самые умные проектировщики API. Первая версия стандартной библиотеки Java содержала класс Date с серьезным архитектурным изъяном74. Он представлял конкретную дату, такую как 28 января 1972 года, 08:24 UTC. К сожалению, он был изменяемым: если у вас была ссылка на такой объект, вы могли его модифицировать с помощью таких сеттеров, как setHour, setYear и т.д. Это создавало большие проблемы для любых сущностей, которые использовали дату в качестве одного из своих атрибутов. Было допущено много ошибок, в ходе которых объект Date возвращался из сущности и затем модифицировался снаружи. Некоторые из них привели к появлению уязвимостей.
Это очевидный архитектурный изъян в классе java.util.Date. Дата должна быть объектом-значением, а объекты-значения не должны изменяться, иначе в них нет никакого смысла. Мы ведь не говорим: «Это сегодняшняя дата, только измененная на завтрашнюю». Сегодня — один день, завтра — другой75. К сожалению, класс java.util.Date был спроектирован изменяемым, и, несмотря на то что многие его методы уже выведены из использования, сеттер setTime остается актуальным.
Если коротко, то мы не рекомендуем использовать java.util.Date. Вместо него лучше применять такую современную библиотеку, как пакет java.time76.
Если при написании кода вы по какой-то причине вынуждены работать с изменяемым объектом, можете воспользоваться одним приемом: перед тем как вернуть из метода ссылку на инкапсулированный объект, клонируйте его. Таким образом ваш изменяемый объект не будет модифицирован кем-то другим. Если внешний код воспользуется ссылкой, которую вы вернули, он изменит только копию объекта, но не оригинал. В листинге 6.11 показано, как этот прием можно применить к java.util.Date.
Отличная книга! По сути, это хороший учебник DDD с понятными и запоминающимися примерами (чего только стоит покупка минус одной книги в интернет-магазине). А при чем тут безопасность? Авторы считают, что для создания безопасного ПО нужно грамотно подходить к проектированию системы. А именно, использовать DDD. Немного необычный заход, но очень классный.