Как мы ускорили написание кода на 20% с помощью обучения сотрудников работе с веб-уязвимостями

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Раньше, когда мы нанимали новых специалистов, работа над кодом строилась так: пишем, проверяем, исправляем ошибки, проверяем ещё раз, снова переписываем и т.д. В итоге даже после испытательного срока разработчик тратил на фрагмент кода до 60 часов, а ревьюер — до 10. Но плановый аудит помог понять, что подход нужно менять. 

Привет! Это SpaceWeb, на связи Виталий Киреев, я руковожу отделом исследований и разработок. В статье расскажу, как мы в компании внедрили стандарты работы с веб-уязвимостями и собственную методологию обучения сотрудников и каких результатов добились. 

Как работали до внедрения стандартов 

Мы нанимали сотрудников, у которых уже был опыт работы с веб-уязвимостями. Но рельеф знаний у всех был разный: например, разработчик мог хорошо разбираться в SQL-инъекциях, но ничего не понимать в XSS. В результате уровень безопасности их изначального кода был разным — первые три месяца приходилось тратить на код-ревью по 30–40 часов и разбирать каждую ошибку отдельно. 

На подключение новых сервисов к API, таких как DBaaS, разработчик тратил 20–40 часов. Еще 2–4 часа уходило на код-ревью. Код мог вернуться на доработку от одного до трех раз. В итоге на новую фичу для API мы тратили 30–60 часов разработчика и 3–6 часов ревьюера. И даже тогда в код могли просачиваться потенциальные веб-уязвимости, которые отлавливали на этапе внутренней проверки безопасности.

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

Осознали проблему — начались первые изменения

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

В формате код-ревью новым сотрудникам было сложно учиться работать с веб-уязвимостями, потому что обратную связь они получали по каждой конкретной задаче. Так получалось хорошо отработать одни типы веб-уязвимостей, которые встречаются почти в каждой задаче по API, например RCE, и ни разу не столкнуться с более редкими — например, с инъекциями PHP-объектов через сериализацию. При этом разработчики всё равно должны учитывать разные типы уязвимостей и уметь отрабатывать их в коде. 

Еще мы пробовали давать новым сотрудникам материалы для самостоятельного изучения, но это тоже не сработало. Поначалу предлагали разработчикам самим погружаться в популярные документы по веб-безопасности — например, OWASP Web Security Testing Guide, ver 4.1 и OWASP Developer Guide, ver 2. И дополнительно проходить курсы образовательной платформы Otus и Бауманского учебного центра «Специалист» по PHP-разработке, в которых были кусочки, посвященные веб-безопасности. 

В итоге новым сотрудникам приходилось изучать огромное количество информации самим. Такой подход тоже не давал равномерных знаний по веб-безопасности для всех. 

Тогда мы решили взять подготовку кадров на себя и внедрить внутренний стандарт работы с веб-уязвимостями. 

Шаг 1. Разработка стандартов: что в них вошло

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

В стандарты вошло 9 типов веб-уязвимостей. Их мы разбили на две группы: Server Side — для бэкендеров и Client Side — для фронтендеров. 

Server Side | бэкенд

Client Side | фронтенд

RCE (Remote Code Execution)

XSS (Cross-Site Scripting)

LFI/RFI (File Include)

CSRF/XSRF (Cross-Site Request Forgery)

SSTI (Server Side Template Injection)

CFT/Open Redirect

XXE (XML External Entity)

SSRF (Server Side Request Forgery)

PHP Object Injection

Структура корпоративных стандартов веб-безопасности получилась такой: тип уязвимости — пример — шаги для решения проблемы

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

Шаг 2. Обучение сотрудников: основные этапы

Как закончили с разработкой стандартов, начали продумывать методологию обучения. Обучение разбили на три этапа: вебинар → практика → аттестация. По этой схеме мы работаем до сих пор. 

Вебинар

Для каждого нового сотрудника я сам провожу двухчасовую онлайн-встречу, на которой знакомлю его со стандартами. Почему не в записи? Опыт с курсами показал, что так информация плохо усваивается: лекцию либо смотрят вполглаза и пропускают важное, либо, досмотрев до конца, забывают, что было в начале. 

Еще знания у всех разработчиков разные, а запись не позволяет эффективно закрыть пробелы. Зато в режиме реального времени мы можем выяснить, каких знаний не хватает, и сделать на этом акцент.

Практика

После презентации разработчик идет применять теорию на практике. Уже на испытательном сроке мы даем новым сотрудникам реальные задачи, в которых нужно применять стандарты веб-безопасности. Например, вот такое решение ждем от разработчика при работе с XSS:

header("X-XSS-Protection: 1; mode=block");
header("X-Frame-Options: SAMEORIGIN"); 
header("Content-Security-Policy: frame-ancestors 'self' https://*.sweb.ru;");

У каждого есть наставник, которому можно задать вопросы, а код проходит скрупулезную проверку с разбором ошибок.

Аттестация

В конце испытательного срока проверяем, как новичок усвоил стандарты. Аттестация состоит из двух частей. Мы работаем по Agile и первым делом смотрим последние четыре спринта сотрудника и количество уязвимостей в коде, которые обнаружили на этапе QA. Нормальный показатель — 1–2 бага на 10 задач. 

Дальше сотрудник решает тест из 2–6 вопросов. У бэкендеров вопросов больше, чем у фронтендеров, поскольку и типов уязвимостей в серверной части больше. 

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

Пример кода, в котором есть проблема с безопасностью:

$domain = strval($_POST['domain']);
$email = strval($_POST['email']);

Решение этой проблемы: 

$domain = filter_var($_POST['domain'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);

Чтобы пройти аттестацию в конце испытательного, нужно правильно ответить на 75% вопросов. Если что-то идет не так, мы вынуждены расстаться с сотрудником.

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

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

Результаты: трудозатраты на код-ревью сократились до 70%, а безопасность кода выросла в 10 раз

После прохождения аттестации каждый разработчик обязан учитывать стандарты веб-безопасности в своем коде. 

К примеру, есть правила по очистке входящих данных: верификация email, строковых и числовых данных. Для этого есть конкретные фильтры, валидаторы, которые разработчик должен использовать, — это зафиксировано в стандарте. 

Пример использования встроенного валидатора:

if (filter_var($statusCode, FILTER_VALIDATE_INT) === false) {
throw new \InvalidArgumentException('Status code must be an integer value.');
}

В результате мы твердо знаем, что все данные, которые получаем на входе, проходят проверку. И так во всём. Эта работа упростила ревью кода и во время испытательного срока новых сотрудников, и после.

Чтобы оценить, как изменились времязатраты на типовые задачи, мы применили диаграмму Ганта, в которой фиксируем продуктовый план. Оказалось, что затраты компании на код-ревью в период адаптации снизились минимум в три раза — теперь в первые три месяца работы новичка мы тратим на проверку кода 10–15 часов. 

Еще у нас есть тайм-трекинг в Jira: напротив каждого слота сотрудники отмечают, на что ушло время. Например, три часа на код-ревью. Так выяснили, что после старатизации работы с веб-уязвимостями, время на код-ревью сократилось на 50–70%, а скорость написания кода выросла на 20%. Такой подход позволяет ревьюеру вместо рецензирования кода заниматься непосредственно своими задачами — разработкой или оптимизацией программной архитектуры. 

Так изменились трудозатраты разработчиков и ревьюеров на фичи для API: 

Трудозатраты

До

После

Разработчик

30–60 часов

25–50 часов

Ревьюер

3–10 часов

1–3 часа

Разработчики изначально предусматривают в своем коде стандарты веб-безопасности, и в результате на код-ревью и исправление ошибок тратится меньше времени

Качество кода тоже выросло. Для QA у нас есть отдельный баг-трекер в Jira, где отмечается количество багов и возвратов задач на доработку. Статистика показала, что уязвимостей на этапе QA стало в 10 раз меньше. Раньше потенциальные уязвимости находили в каждой задаче, сейчас — только в одной из десяти. Там, где есть ошибки, неизбежен процесс их исправления и повторной проверки — это увеличивает сроки и стоимость разработки, так что стандартизация экономит компании не только время, но и деньги.

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

Александр Литвинов, бэкенд-разработчик в SpaceWeb:

«Было полезно узнать ещё на старте работы, что часть возможных проблем с безопасностью уже решена настройками проекта или его архитектурой. Например, отключена поддержка xinclude для безопасной работы с XML, запрещены внешние allow_url_include в php.ini, чтобы нельзя было подключить внешние скрипты.

Помимо этого мы разбирали и неочевидные для меня моменты в веб-безопасности — например, я не знал о возможности инъекции в PHP при использовании функции unserialize».

Что получилось в итоге:

  • Новые сотрудники обучаются быстрее: вместо того, чтобы изучать многостраничные документы или проходить курсы, они получают краткую выжимку — только самое важное.  

  • Руководитель тратит меньше времени на координацию взаимодействия между разработчиками и QA и разбор проблем. Каждая задача проходит несколько этапов: новая, в разработке, готова к тестированию, протестирована. Если нашли баг, задача возвращается в разработку. Когда изменился подход, таких «возвратов» стало меньше. 

  • Компания тоже в плюсе: благодаря тому, что задачи закрываются быстрее, сотрудники могут сделать больше за то же время. При этом и качество кода после внедрения стандартов значительно выросло. 

А как работа с веб-безопасностью устроена в вашей компании? Делитесь опытом в комментариях.

Источник: https://habr.com/ru/companies/spaceweb/articles/796957/


Интересные статьи

Интересные статьи

Тестировать андроид — сложно. Автоматизированно тестировать андроид — очень сложно. А если автоматизированно тестировать 6 очень разных приложений на 10 разных версиях ОС Android с использованием 3 яз...
В 2021 году команда по управлению репутацией, в которой состою и я, решила помочь волонтерам закрыть приют для животных, где работали мошенники. Вот только мало мы знали, какой шум поднимется из-за эт...
Сегодня я хочу рассказать про один не очень популярный но очень классный паттерн в написании React приложений - Compound components.Что это вообще такоеCompound components это подход, в котором вы объ...
«Наши компьютеры создаются так же, как и наши города: долго, без планов и на руинах былого». Эллен Ульман (Ellen Ullman) написала это в 1998 году, но сегодня мы именно так и создаем современные прилож...
Двойственная природа материи — широко известное понятие среди физиков. Вещество на атомном уровне в некоторых случаях ведёт себя как частицы, а в некоторых — как волны. Ч...