- Ну, у него нет носа… но он точно может вонять!` (SourceMaking.com, 2007–2020).

Если ваш код пахнет, хакеры придут за вами. Эта формула должна быть первой в вашем списке для изучения программирования. Если какая-либо часть кода протекает или гниет, день выплаты жалованья не исчезнет. Это лакмусовая бумажка для кибер мошенников. Они имеют одинаковое происхождение программирования. Они знают, что код может пахнуть, что он пахнет, и запах отклоняется. Не было бы большим сюрпризом, если бы у хакеров в черной шляпе была шкала для оценки уровня запаха.

Ясно как божий день, что чистый код гораздо легче обнаружить на наличие ошибок. Интересно отметить, что в мире программирования гораздо сложнее писать простые и общие функции, чем со сложной логикой. Чем хуже дизайн, тем чище и сложнее писать. «Чистый код — тупой, но очень понятный код. И чем тупее, тем понятнее». В конце концов, это делает программу более умной. Парадокс. Это связано с тем, что разработчики пишут часть приложения не только для себя, но и для командной работы. Если код, написанный по какому-то образцу, не был согласован внутри команды, то плохая архитектура создаст трудности для понимания другими разработчиками и плохо повлияет на эффективность. Поэтому им нужно много убирать за собой. Им с детства внушали родители, что те, кто плохо учился, закончат уборкой. Теперь это имеет большой смысл, верно? В 3 часа ночи, пытаясь не попасться на удочку атакующих с консоли жуков. Так что, если бы вы только начали рефакторить его параллельно, вы бы сейчас, наверное, сладко спали. Но никто не слушает родителей.

~Зачем?

Изменение — единственное, что является постоянным. Каждый сталкивается с изменениями через день. Изменение погоды или изменение, запрошенное КЛИЕНТОМ. Если это последнее, и вы должны перестроить все приложение, то это звоночек, чтобы переписать весь код. Невозможность плавно изменить и адаптировать вашу часть разработки снизит способность приложения быть улучшенным с помощью механизма защиты, поскольку они находятся в режиме мгновенного обновления.

Ваш код работает, и вы понятия не имеете, почему. Ваш код не работает, и вы понятия не имеете, почему. И это огромный запах. Он шепчет вам, что отладчик будет отчаянно пытаться обработать вашу часть кода. Неправильное определение и интерпретация проблемы приведет к нестабильной сборке, нежелательной производительности вашей программы и подвергнет ваши конфиденциальные данные риску взлома, что является худшим.

Спорить о шаблонах чистого кода — все равно, что обсуждать политику. И только какой-нибудь лысый мужик покажет свой дерьмовый исходник кода, чтобы встретить критику и прыгнуть на уровень выше. Вы можете думать об этом так же, как блогеры в Instagram, хвастающиеся своей жизнью. Это действительно публичный обзор кода! И только хейтерские комментарии делают их сильнее. Но любой разработчик начинает с написания спагетти-кода на PHP. Дядя Боб написал миллионы грязных строк кода, чтобы понять искусство четкого шаблона. Пожалуйста, примите, что писать шиткод — это нормально. Нехорошо, чтобы это пахло.

После проведения вопросов и ответов с разработчиками из разных языков программирования была выявлена ​​важная веха: чистый код не имеет запаха. Потому что его не существует в реальной жизни. Конец истории. Он ведет себя как экспонат в музее. Смотреть можно, но не трогать. Чистый код — это идеальный, другими словами, недостижимый код. Но опять же, это зависит от того, что разработчик вкладывает в свое определение. Для кого-то это элегантность в простоте, для кого-то универсальность функциональности. Лично он реализует концепцию безопасности и отказоустойчивости приложения. Суть здесь в том, чтобы писать так четко, чтобы ваши коллеги могли заметить слабо пахнущие места. Вполне логично, что для того, чтобы получить чистый код, вы начинаете с написания грязного. Так что пора иметь в виду, пока вы в отчаянии обсуждаете, чего стоят чистые паттерны, другие разбирают замечания из очередного Code Review и становятся на шаг ближе к идеальной модели, разработанной именно в вашей команде.

Безопасность приложений неразрывно связана с определением чистого кода. Каждый даст свой ответ на вопрос, что на самом деле означает для него безопасность. С клиентами хуже. Они просто не заботятся об этом. Для них не существует этого термина. То же самое с безопасностью, не имеющей запаха, что затрудняет вынюхивание.

Что ж, давайте разберемся, как написать код, чтобы быть мегачувствительным и, как производители парфюмерии, уметь распознавать предпосылки проблемы, которая вот-вот начнёт вонять. По разнообразию запахов, от сильных до едва уловимых, мы должны понимать, что за обонятельным кодом, скорее всего, скрывается едва узнаваемый запах. И это самое опасное.

Важно знать:

  1. "Хорошие запахи" легко и ясно ведут к сути проблемы. А «дурные запахи» лгут и прячутся от вас.
  2. Для разработчиков среднего и младшего звена написать чистый код вполне возможно, но настоятельно рекомендуется писать код с "приятным запахом".
  3. Чем больше раз вы сталкиваетесь с грязью и боретесь с ней, тем больше оттенков грязи вы узнаете в будущем.

~Мы рассмотрим некоторые запахи:

  1. Жестко закодированные URL-адреса
  2. Очистка URL-адресов в React
  3. JSON.Parse
  4. Неуместная близость
  5. Компонент Бога
  6. реквизит слабых типов
  7. Не аннотированные параметры
  8. Отсутствие комментариев
  9. Переоптимизированный код
  10. Утечка памяти

Согласно статье Филиппа, наиболее популярными атаками являются XSS и внедрение SQL (De Ryck, 2020).

Запах:жестко запрограммированные URL

Проблема:

Наличие любых жестко закодированных значений потенциально может быть местом, где может быть внедрен вредоносный код. В частности, такие символы, как ‹и›, являются чрезвычайно уязвимым местом и первым шагом, чтобы дать злоумышленнику возможность вставить свои вредоносные данные, которые будут интерпретированы как действительный код вашего веб-приложения.

Решение:

Закодируйте свой код. Я знаю, это звучит странно, но суть в том, чтобы замаскировать потенциально опасные символы под безобидные символы, воспринимаемые браузером как данные. Примените шаблон кодирования вывода контекстно-зависимого шаблона, который преобразует символы в данные, не спутанные с кодом.

  • Никогда не вводите учетные данные приложения жестко.
  • Не используйте оповещения с жестко запрограммированными сообщениями.
  • Никогда не присваивайте значение innerHTML вручную! Вместо этого используйте опасноSetInnerHTML
  • Избегайте жесткого кодирования URL-адресов, так как они содержат символы `/` и ведут к завершающему содержимому с комментариями злоумышленников.

Запах: очистка URL-адресов в React

Проблема:

React довольно умен, чтобы использовать выражения регулярных выражений для поиска неподходящих шаблонов. Однако он способен различать только конечные точки, начинающиеся с «javascript», а те, которые начинаются с «data», обречены.

Решение:

Не используйте URL-адреса, начинающиеся с данных. Что ж, довольно весело, но пока нет советов, связанных с безопасностью. Или используйте другой фреймворк, который обрабатывает такие случаи по умолчанию.

Запах:JSON.Parse

Проблема:

опасноSetInnerHTML может не сработать в нашу пользу в случае более сложного сценария. Если объект JSON анализируется, любой черный хакер мечтает использовать это опасное свойство SetInnerHTML. Они с удовольствием встроят в ваш JSON конфигурацию зараженного скрипта.

Решение:

Дезинфицируйте объект перед его использованием! Помните, что React выдаст ошибку, если вызов API createElement содержит более двух аргументов, поэтому атака будет предотвращена. Но это не удастся, если у элемента есть дочерние элементы.

Запах: неуместная близость

Проблема:

Компонент, имеющий много обязанностей и более 100 строк, вопит, что скоро сгниет и превратится в монстра. Как только вы захотите реализовать новую функцию, связанную, например, с Auth, вам нужно будет добавить обработчик исключений, который может создать больше беспорядка, и никто не сможет распознать, где скрывается недостаток из-за длины реализации логики. Однажды у вас возникнет соблазн добавить комментарий, поясняющий какой-то блок кода. Внимание! Это пахнет!

Решение:

Возьмите карандаш и начните рисовать. Я не шучу. Пришло время отделить представление от бизнес-логики или реорганизовать некоторые части в более мелкие компоненты. А затраты времени на эскиз сэкономят ваше время и деньги клиента в будущем. Думайте о React как о башне из кирпичей. Компоненты — это ваши кирпичи, имеющие тенденцию иметь одинаковый размер. И только самодисциплина, помноженная на терпение, построит надежную защиту вашей башни.

Запах: компонент Бога

Проблема:

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

Решение:

Компонент должен быть разделен на «детские» компоненты со своей бизнес-логикой и просматривать и выполнять контекстно-зависимый набор вещей. Перейдите к SRP: один компонент = одна ответственность = одна часть функциональности, предоставляемая приложением.

Запах: реквизит слабого типа.

Проблема:

Хотя мощный React позаботится о защите объекта, вы, как разработчик, можете указать ему недопустимое значение и создать сильный запах, привлекающий злоумышленников.

Решение:

Используйте машинопись. Поощряйте вашу команду думать и использовать ее, чтобы избежать ситуации, когда злоумышленник может получить контроль над вашим объектом. Если злоумышленник попытается присвоить вашей опоре вредоносное значение, React отклонит рендеринг, но если вы сделаете то же самое, директивы привяжут недопустимое значение. Следовательно, это даст злоумышленнику возможность воспользоваться этим.

Запах: параметры без аннотаций.

Проблема:

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

Решение:

Параметры должны быть правильно аннотированы, в частности, при определении моделей данных. Наряду с вводом текста важно отметить, можно ли обнулить переменную, и указать начальное значение, если оно переопределено. Простой способ — сериализация ответа JSON API. Нет никаких шансов, что вы можете рассчитывать на данные с другого сервера. Если какое-либо свойство отсутствует, нулевые значения или значения по умолчанию должны быть обработаны и обработаны должным образом внешней стороной, чтобы избежать непредвиденных результатов или даже сбоя.

Запах: Отсутствие комментариев

Проблема:

Да, это не шутка. Существует тонкая грань между отсутствием комментариев и ненужными комментариями. В самом коде нет блоков документирования, нет возможного просмотра использования функций, нет объяснений, где это нужно ИЛИ он полон разных комментариев даже в глупом контексте, что делает код некрасивым.

Решение:

Хороший код самодокументируется. Ну и не важно, что разработчики вообще никогда не должны комментировать. Программа считается хорошо разработанной, если нет необходимости в комментариях, так как код рассказывает подлинный сюжет, но может быть такая необходимость в комментариях, чтобы другие поняли, почему фрагмент кода существует, а не то, что он делает.

Существует два типа комментариев:

  • Комментарии к документации: для тех, кто собирается использовать ваш код, но никогда его не читал. Если вы разрабатываете какую-либо платформу или библиотеку, вам потребуется создать документацию для вашего API. Если вам не нужно обновлять код, вы можете оставить документацию нетронутой. Но из-за того, что требуется очень трудоемкая работа, фактическим решением является встраивание документации в код и с помощью внешних инструментов, таких как JavaDoc, для ее извлечения.
  • Комментарии для объяснения:для тех, кто собирается читать ваш код. И тут начинает вонять. Не переусердствуйте с объяснениями — плохой паттерн.

Здесь самое время упомянуть о компрометации. Любому опытному разработчику знакома ситуация, когда их берут кучей. Поддержка приложений и скорость являются наиболее распространенными и важными. В результате многие проекты не могут быть оценены по ценности кода или полному эффективному использованию какой-либо функциональности. А к чему приводит средний проект?

Обзоры кода приносят все больше и больше компромиссов. Усилия по тому, чтобы сделать код красивее и приятнее, предпринимаются, если у разработчиков не хватает энтузиазма, чтобы повысить качество, углубляясь в код коллег. Однако компромиссы превращаются в «отдел кодирования», а недавно разработанные части приложения переходят в стадию производства без соответствующей станции рефакторинга — «не трогайте, если работает». И все это реализовано в тысячах TODO в приложении. По этой причине вы вряд ли сможете найти крупный производственный проект в открытом исходном коде. Есть места, где использовались поясняющие комментарии, иначе вы и ваша команда не догадались бы, почему этот код здесь делает. Однако такие ситуации должны возникать крайне редко.

Запах: переоптимизированный код

Проблема. Оптимизация стоит больше, чем ее отсутствие. Или пользовательские хуки оборачивают useCallback и useMemo каждый раз, в то время как на самом деле производительность снижается.

Решение.Оптимизация вашего кода нежелательно увеличит сложность вашего приложения, повлияет на соблюдение сроков и снизит качество обслуживания. Если ваш код достаточно гибкий, вы можете продолжить его оптимизацию в будущем, если возникнут такие потребности. Например, вас просят представить проект для компании, которым пользуются 100 пользователей, не позднее, чем через месяц. И вы, помешанные на оптимизации, начинаете строить каркас проекта, который позволит им пользоваться одному миллиону человек. Конечно, через месяц ваш проект едва ли сможет обслуживать 50 пользователей, и теперь вам потребуется еще больше времени, чтобы избавиться от старого кода и запустить новый. Это просто пустая трата времени, ресурсов и денег.

Запах: утечка памяти

Проблема: ресурсы утечки данных происходят, когда программа не выделяет память должным образом. Он не очищает бесполезную память. Циклические зависимости являются основной причиной этого запаха. Есть и другие, такие как использование локального состояния React в качестве хранилища данных проекта и вызов асинхронных задач без их очистки.

Решение.Используйте Redux, чтобы избежать хранения данных в локальном состоянии, этого крайне недостаточно. Следите за реализацией хуков React, методы с подпиской setTimeout должны быть очищены правильно. Лучшее место для него — хук useEffect, который отражает функциональность componentDidMount и componentWillUnmount. И для всех запросов XHR у вас есть причудливый AbortController, чтобы отменить их все. И даже если AbortController бесполезен, useStateIfMounted должен разобраться с этим, чтобы ваш компонент отображал состояние после монтирования.

~Заключительные предостережения:

Каждый разработчик время от времени сталкивался со следующим (3 часа ночи, приложение наполовину сломано, консоль красная, крайний срок подачи/представления рабочего функционала — утро). В отчаянии… Тут-то и вступает в игру безопасность. Пожалуйста, ответьте на вопрос: сколько раз вы возвращались к приложению, которое заработало после нескольких бессонных ночей, и пытались изменить код ради безопасности? Будьте честны хотя бы перед собой.

  1. В то время как React довольно безопасен по своей конструкции с возвратом JSX, куда нельзя внедрить вредоносный код, вы можете свести это влияние к нулю, написав код, который скрывает запах. В React есть некоторая защита от XSS, но большая ее часть все еще находится в руках разработчиков.
  2. Безопасность: смешивает как минимум два уровня абстракции.
  3. если вы не можете его контролировать, вы не можете ему доверять. Очевидно, что существует сильная корреляция между чистым кодом и безопасностью. Но вопрос в том, где этот предел ловушки при применении логики валидации к другому уровню сложности добавляется, и это приводит к созданию горячих желанных мест для прихода хакеров? Сложность скрывает ошибки не только от вас, но и от членов команды, проверяющих ваш код.
  4. Все кричат ​​о безопасности, но когда дело доходит до того, чтобы что-то работало, она уходит за кулисы, и ее понятия становятся расплывчатыми… И это понятно, поскольку работоспособность программы вполне очевидна для определения, то же самое, к сожалению, не идет вместе с безопасность. Только взлом будет подходящей оценкой, оценивающей, насколько ваш сайт безопасен/был безопасен.
  5. Точно так же все кричат ​​о чистоте кода, но когда дело доходит до конца спринта, пахнет `TODO: Улучшить это позже`
  6. Чистый код — это не код, представленный всего одной строкой, и вы чрезвычайно гордитесь своими изящными разработанными методами. По сути, это означает, что код предполагается дублировать, а некоторые его части следует оставить на уровне абстракции. Теоретически упрощение вашей программы должно привести к уменьшению количества дефектов.
  7. Мартин, Р., нд. Чистый код. Разжечь.
  8. Хабр.com. 2020. Вероятно, Хватит Рекомендовать “Чистый Код”. [онлайн] Режим доступа: ‹https://habr.com/ru/post/508876/› [Проверено 19 октября 2020 г.].
  9. Рефакторинг.гуру. 2020. Запахи кода. [онлайн] Доступно по адресу: ‹https://refactoring.guru/refactoring/smells› [По состоянию на 19 октября 2020 г.].
  10. Де Рик П., 2020 г. Предотвращение XSS в React (часть 1): привязка данных и URL-адреса. [онлайн] Pragmaticwebsecurity.com. Доступно по адресу: ‹https://pragmaticwebsecurity.com/articles/spasecurity/react-xss-part1.html› [По состоянию на 19 октября 2020 г.].
  11. Хакернун.com. 2020. Извлеченные уроки: общие запахи кода React и как их избежать | Хакерский полдень. [онлайн] Доступно по адресу: ‹https://hackernoon.com/lessons-learned-common-react-code-smells-and-how-to-avoid-them-f253eb9696a4› [По состоянию на 19 октября 2020 г.].
  12. Блэкхэт.com. 2020. [онлайн] Доступно по адресу: ‹https://www.blackhat.com/docs/us-14/materials/us-14-Johns-Call-To-Arms-A-Tale-Of-The-Weaknesses-Of. -Current-Client-Side-XSS-Filtering-WP.pdf› [По состоянию на 19 октября 2020 г.].

Первоначально опубликовано на https://kristinavolk.medium.com 13 декабря 2020 г.