что такое безопасный код
Как писать безопасный Python-код. Отвечает Кушал Дас
В этом году компания спикеров Moscow Python Conf++ подобралась что надо (то есть как, подобралась — Программный комитет подобрал). Но кому интересно изучать достижения, куда интереснее, что спикер думает по поводу волнующих нас самих вопросов. Чтобы это узнать, получить инсайдерскую информацию или совет более опытного разработчика, и нужно общаться на конференциях. Но я воспользовался положением и взял небольшое интервью у нашего докладчика Кашала Даса (Kushal Das).
Отличительная черта выступлений Кушала в том, что он регулярно обнародует «секретные» способы сломать Python-код и в противовес показывает, как написать код так, чтобы АНБ не смогло его взломать. На нашей конференции Кушал расскажет, как безопасно разрабатывать и деплоить Python-код, поэтому о безопасности я его и расспрашивал.
— Кушал, расскажите, пожалуйста, немного о себе и о своей работе с Python и тому подобными вещами.
Кушал Дас: Я живу в Индии, сейчас работаю технологом по общественным интересам в американской некоммерческой организации Freedom of the Press Foundation, где помогаю поддерживать проект SecureDrop. SecureDrop — это информационная платформа с открытым исходным кодом. Основной язык здесь Python.
Помимо этого, я занимаюсь другими open source проектами, в том числе самим языком Python. Я один из Core-разработчиков CPython, а также член Совета директоров Python Software Foundation.
Я работаю с Python с 2005 года, и почти вся моя карьера связана с этим языком, а также с Linux. Это два основных направления мои интересов. Еще я вхожу в группу Core-разработчиков проекта Tor Project. Как многие уже знают, Tor помогает сохранять конфиденциальность в интернете.
— Tor — потрясающий проект, им пользуются разработчики по всему миру, чтобы получить доступ к API и документации, заблокированным, к примеру, из-за местных законов. Ваше выступление будет построено вокруг безопасности, поэтому у меня есть несколько вопросов.
Прежде всего, есть мнение, что для обычного разработчика без специальной подготовки безопасность сама по себе слишком сложна. Считается, что мы, как отрасль, должны обеспечить инструменты и экосистему, чтобы создаваемое нами ПО было безопасным по умолчанию.
Как вы думаете, что все-таки лучше: обучать людей безопасности или предоставлять им какие-то инструменты?
Кушал Дас: Думаю, и то, и другое. Действительно, безопасность — сложный вопрос. Однако, если начинающий программист проходит базовые тренинги или работает в команде, то учится избегать большинство распространенных проблем.
Чаще всего реальные ошибки в системе безопасности, такие как взлом, утечка или кража данных, возникают из-за неправильной конфигурации, отсутствия обновлений или некорректного, порой хулиганского кода.
Думаю, большинства основных ошибок можно избежать, если обучать как новичков, так и «старожилов» отрасли. Кроме того, некоторые вещи, недоступные человеческому глазу, можно выявлять с помощью новых инструментов, новой автоматизации, новых процессов.
Очень простой пример — проверки зависимостей, которые теперь есть в GitHub. Если Python-приложение содержит ошибки или использует какую-то старую версию независимого модуля, и есть определенная уязвимость, описанная в CVE, GitHub может сказать вам как разработчику: «Эй! Здесь требуется обновление!» — и бот автоматически попытается сделать PR, чтобы обновить модуль.
Таким образом, обучение и инструменты лучше сочетать, но лично я все равно предпочел бы как можно больше обучения. Именно люди вводят данные и допускают ошибки. Технологии все такие ошибки исправить не смогут.
— Да, к сожалению, это так. Современная разработка программного обеспечения в значительной степени полагается на открытые репозитории, такие как Python Package Index, node.js, npm и т.п. При современном уровне развития это обычно происходит как pip install или poetry add.
С вашей точки зрения, насколько высоки риски безопасности для обычного Python backend-разработчика в компании среднего размера, если он пользуется только этими инструментами? Приемлемы ли такие риски, или разработчикам надо учитывать даже тривиальные уязвимости?
Кушал Дас: Это по настоящему важный вопрос, потому что во всех репозиториях, которые мы поддерживаем, где можно скачать модули для разных языков, мы стараемся сделать этот процесс простым и доступным для разработчиков.
Для Python, например, существует Python security mailing list, который оповещает о проблемах с новейшими загруженными модулями для Python. Известны случаи так называемого тайпсквоттинга, когда название пакета похоже на очень известный пакет, и разработчики используют неправильный по неосторожности. Со стороны Python о подобных вещах заботится PyPI.
Кроме того, при установке любого пакета с помощью pip, можно действительно проверить его и убедиться, что это то что нужно, а также проверить безопасность загрузки. Например, есть PEP 458, который советует защищать загрузки с PyPI подписыванием пакетов.
Работы по развитию инструментов безопасности все еще продолжаются. Я бы рекомендовал разработчикам, начинающим работу с любым новым неподписанным модулем, выяснять, кто автор, сколько людей участвует в разработке, где хостится, в каких крупных проектах используется, что в исходном коде, есть ли жалобы на проблемы или ошибки и т. д.
Это всего 15-30 минут поиска, но они дают массу преимуществ. Если ни один человек в мире, кроме автора, не использует этот пакет, возможно, и вам не стоит его использовать. Если этот конкретный модуль применяется в других пакетах или ПО, то он, скорее всего, будет более безопасным для вашего кода.
— Да, современному разработчику необходимо задумываться, прежде чем использовать какие-либо пакеты и зависимости, с точки зрения безопасности, поддержки, популярности и многих других вещей.
Если говорить о публичных пакетах, зависимостях и репозиториях, недавно я обнаружил встроенный мониторинг безопасности в экосистеме node.js и npm, с проверкой данных при npm install something.
NPM проверяет безопасность данных и показывает результаты. Например, выводит сообщение: «Среди пакетов, которые вы только что установили, есть два с высоким риском безопасности и десять со средним риском. Вы можете выполнить следующие команды, чтобы исправить или обновить их, или отказаться от установки». Это похоже на встроенные инструменты. Что вы думаете о таких решениях, и можно ли ожидать чего-то подобного для PyPI?
Кушал Дас: Я никогда не пользовался NPM, за исключением, может быть, одного или двух раз в жизни, когда нужно было протестировать что-то. Поэтому не могу напрямую прокомментировать, насколько это хорошо, но, похоже, речь идет о том, чтобы дать разработчику более наглядный пользовательский интерфейс.
В целом, все это часть истории про взаимодействие с пользователем, когда задача разработчиков и дизайнеров — выявить, как лучше всего представить данные с учетом того, что их реально просматривает конечный разработчик, третье лицо, которое будет устанавливать все эти инструменты и модули. Потому что, когда информации слишком много, мы обычно ее прощелкиваем или пропускаем, не читая. Истина где-то посередине.
Насчет будущих планов Python- и pip-разработки — я не могу их комментировать, они мне неизвестны. Однако я думаю, или скорее надеюсь, что кто-то уже подал запрос на подобную функцию, чтобы авторы pip могли учесть его в своих планах. Сейчас команда поддержки немного больше, чем было раньше, — около семи человек с правом принимать коммиты.
— Спасибо, я надеюсь, что со временем люди будут больше думать о безопасности и встраивать больше проверок в нашу экосистему. Давайте немного поговорим о вашем предстоящем выступлении на Moscow Python Conf++. Оно построено вокруг встроенной проверки безопасности зависимостей и пакетирования.
Мы не будем здесь спойлерить, но с точки зрения эксперта по безопасности, с вашей точки зрения, что еще разработчики должны учитывать при проверке безопасности приложения?
Мы уже обсудили, как обезопасить работу с зависимостями и пакеты. Что еще нужно проверять обычному разработчику? На что следует обращать внимание?
Кушал Дас: Думаю, одним из главных пунктов должны быть обновления. Убедитесь, что хотя бы с этим у вас порядок, и все, от чего вы зависите, обновляется, включая ОС, будь то Linux, Mac, Windows или даже iOS. Как вариант, убедитесь, что вы, по крайней мере, смоделировали процессы, чтобы понять, что еще может пойти не так.
Проблема новичков (и со мной такое случалось) в большинстве случаев заключается в том, что мы слепо доверяем пользовательскому вводу. Нужно меньше полагаться на то, что ввод действительно корректен, и что это не вызовет никаких других проблем. Всё нужно перепроверять.
Кроме того, если что-то открыл — убедись, что не забыл закрыть. Представьте себе обычную дверь: когда мы входим в офис, мы проверяем, не забыли ли закрыть за собой дверь. Так же и в программировании, когда мы открываем файлы, сокеты или еще что-то, или доступ к чему-то, необходимо убедиться после завершения работы, что все чисто и закрыто.
С точки зрения программирования, я думаю, это два основных момента, о которых многие забывают.
— Да, есть много вещей, о которых люди забывают, и теперь, я думаю, последний вопрос. Исходя из вашего личного опыта, какие ошибки, связанные с безопасностью, чаще всего допускают Python backend-разработчики среднего уровня подготовки? Пользовательский ввод? Зависимости? Безопасное пакетирование приложения? Что встречается чаще?
Кушал Дас: Проблемы, которые я видел, были в основном связаны с неправильным вводом.
В 2011 году я разрабатывал инструмент для проекта Fedora и забыл вычистить свои временные файлы. В данном конкретном случае это были дампы, и их отсутствие в новой среде вызвало непредвиденные проблемы для инфраструктуры, — она упала из-за моего, мягко выражаясь, нехорошего кода.
Это продолжение все той же темы, когда необходимо убедиться, что код «вычищен», если вы что-то создаете или открываете. Так что это был серьезный урок для меня. Когда ты думаешь: «Ага, я сделал это! Все работает на моем ноутбуке!», то не факт, что это будет работать в реальном релизе или продакшне.
Мы почему-то часто думаем, что среда будет идентична нашей локальной, но она таковой никогда не бывает. Даже крупным компаниям часто трудно определить реальную среду на стороне клиента. Важно просто помнить об этом.
И еще — делайте больше комментариев к своему коду, пишите документацию. Это совет не только для новичков, но и для опытных разработчиков. Если вы не заглядывали в код в течение нескольких месяцев или нескольких лет, потом бывает очень трудно понять, почему вы что-то когда-то написали.
Кушал Дас выступит на Moscow Python Conf++. Большую оффлайн-конференцию мы были вынуждены перенести на осень, но 27 марта провели мини-онлайн-конференцию, материалами которой скоро поделимся, оставайтесь на связи.
Безопасный код: Работа с пользовательским вводом
(ч2. Подделка межсайтовых запросов; ч2. Работа с базой данных)
Наверняка, XSS атаки остаются самыми популярными наравне с SQL инъекциями. Их принцип прост до безобразия, а последствия разнятся от невинного коверканья вывода страниц до получения злоумышленником полного контроля над сайтом.
Некоторые сценарии XSS атак
Устойчивая атака
Неустойчивая атака
Как обезопасить код от XSS?
Ответ прост — фильтровать вывод на страницу.
Методы фильтрации в Друпале
Золотое правило работы с данными — хранить пользовательский ввод в базе именно в том виде, в котором он был отправлен. Поэтому, всю фильтрацию следует производить на этапе вывода пользовательских данных на страницу.
Весь пользовательский ввод можно разделить на два типа:
Текст без разметки (plain text)
Любой пользовательский ввод, который должен быть подан в виде чистого текста, должен проходить через функцию check_plain(), которая превратит кавычки, амперсанды и угловые скобки в их HTML представление. Затем, такой текст может быть уже вставлен в конечную HTML разметку страницы.
$form[‘good’] = array(
‘#type’ => ‘checkboxes’,
‘#options’ => array(check_plain($u_supplied0), check_plain($u_supplied1)),
);
Текст с разметкой
Размеченный текст нужно фильтровать с помощью check_markup(). Эта функция принимает на вход, кроме самого текста, формат ввода, который содержит правила фильтрации. Поэтому, при формировании форм для текста с разметкой, имеет смысл вводить рядом с многострочными полями виджет для выбора формата ввода(filter_form()).
-=Бонус=-
Видео-доклад «Introduction Security» с прошедшего друпалкона:
Рекомендации по безопасному написанию кода
В этом обзоре описываются различные способы разработки кода, взаимодействующего с системой безопасности.
Защита доступа к ресурсам
При разработке и написания кода необходимо защитить и ограничить доступ данного кода к ресурсам, особенно при использовании или вызове кода неизвестного происхождения. Убедиться, что ваш код является безопасным, можно с помощью следующих методов.
Не используйте управление доступом для кода (CAS).
Не используйте частично доверенный код.
Не используйте модель DCOM.
Не используйте двоичные модули форматирования.
Безопасность доступа к коду и код Security-Transparent не поддерживаются в качестве границы безопасности с частично доверенным кодом. Мы не рекомендуем загружать и выполнять код из неизвестных источников, не предприняв дополнительные меры безопасности. Ниже приведены дополнительные меры безопасности.
Пользователи операционной системы (ОС) и разрешения
Код, нейтральный к безопасности
Библиотека нейтрального кода имеет особенности, которые следует понимать. Предположим, что библиотека предоставляет элементы API, которые используют файлы или вызывают неуправляемый код. Если код не имеет соответствующего разрешения, он не будет выполняться, как описано. Однако даже если код имеет разрешения, вызывающий его код приложения должен иметь те же разрешения, чтобы он мог работать. Если вызывающий код не имеет нужного разрешения, в SecurityException результате анализа стека управления доступом для кода отображается.
Код приложения, который не является повторно используемым компонентом
Если код является частью приложения, которое не будет вызываться другим кодом, обеспечение безопасности является простым, а специальное кодирование может не требоваться. Однако помните, что вредоносный код может вызвать ваш код. Хотя управление доступом для кода может предотвратить доступ вредоносного кода к ресурсам, такой код все еще может считывать значения полей или свойств, которые могут содержать конфиденциальные сведения.
Кроме того, если код принимает ввод пользователя из Интернета или других ненадежных источников, будьте осторожны, чтобы не были введены вредоносные данные.
Реализация управляемой оболочки в машинный код
Обычно в этом сценарии некоторые полезные функции реализуются в машинном коде, который требуется сделать доступным для управляемого кода. Управляемые оболочки легко создаются с помощью вызова неуправляемого кода или COM-взаимодействия. Однако если это сделать, для успешного выполнения вызывающим ваши оболочки объектам необходимо предоставить права на неуправляемый код. В разделе Политика по умолчанию это означает, что код, скачанный из интрасети или Интернета, не будет работать с оболочками.
Вместо предоставления прав на неуправляемый код для всех приложений, использующих эти оболочки, лучше предоставить эти права только коду оболочки. Если эта базовая функциональность не предоставляет никакие ресурсы и реализация также безопасна, оболочке достаточно просто объявить свои права, что позволяет любому коду вызывать ее. При использовании ресурсов написание безопасного кода должно быть таким же, как в случае кода библиотеки, описанного в следующем разделе. Поскольку оболочка потенциально предоставляет вызывающим объектам доступ к этим ресурсам, необходима тщательная проверка безопасности машинного кода, за которую отвечает оболочка.
Код библиотеки, предоставляющий защищенные ресурсы
Чистый и безопасный код — миф или реальность?
«Программирование — это искусство сообщать другому человеку, что он хочет от компьютера»
Каждый язык программирования разработан с учетом разных операционных систем, платформ, стилей кодирования и предполагаемого использования. Обычно мы слышим о языках Python, PHP, Ruby, JavaScript, Java, C, C++ и C#, а также более современных их разновидностях, такие как Rust, Swift, Hack и многих других.
Одна из составляющих бесперебойной работы любых приложений (помимо стабильно работающих серверов, сбалансированной нагрузки и прочего) — чистый код. Однако возможен ли чистый код в реальной жизни или же это лишь мечты программистов? Откуда берутся уязвимости и как избежать багов?
Когда речь заходит о чистом коде, мы представляем идеально продуманные строки. Это код, который был спланирован до того, как был написан. Настолько хорошо спланирован, что при первом запуске он работает без ошибок и без изъянов.
Тем не менее реальное программирования намного сложнее: что бы вы ни делали, ошибок избежать сложно. Сомнение в собственной профпригодности продолжает расти, и ошибка, исправление которой, как вы думали, займет пять минут, в конечном итоге занимает часы. К тому же функция, которую вы собирались реализовать, превратилась в серьезную проблему для проекта.
В таком случае важно иметь в виду, что сходу написать идеальный код невозможно. Для этого нужно потратить множество часов на обдумывание и детальное планирование. Здесь каждый для себя выбирает сам, что приоритетнее: написание чистого кода или скорость работы.
Чистый код — это объективно хороший код. Он написан максимально лаконично и элегантно, без дублирования. Он структурирован таким образом, чтобы его было легко читать как людям, так и компьютерам. Каждый может написать код, понятный компьютеру, но только хороший программист может написать код, понятный человеку.
Небрежно написанный код стоит дорого, а на его обслуживание уходит много времени и усилий. Кроме того, код более подвержен ошибкам, которые могут привести к сбою программы.
Следует понимать, что чистый код — это продукт совместной работы, когда каждому в команде необходимо понимать код. Это оптимизирует работу в случае изменения состава команды и значительно упрощает рефакторинг и отладку.
Рефакторинг — это процесс оптимизации программного кода без изменения его внешнего поведения с целью улучшения производительности, читабельности, тестируемости или ремонтопригодности. По сути, при рефакторинге вы улучшаете дизайн кода после того, как он был написан.
Отладка — это исправление ошибок в коде.
Тем не менее даже чистый код имеет срок годности. Программное обеспечение и вычисления существуют в быстро меняющемся ландшафте. Код, который раньше был чистым, устаревает.
Устаревший код — это код, который не поддерживается и не обновляется, но используется. Он работает или нет, при этом никто не понимает почему. Чем старше код в вашей кодовой базе, тем труднее его понимать, независимо от того, насколько хорошо он был написан.
В результате, несмотря на то, что кодовая база может быть изначально чистой, необходимость масштабирования, внесения изменений и появление новых требований может привести к ее загрязнению.
Код должен соответствовать правилу DRY (Don’t repeat yourself с англ. — «не повторяйтесь»). Это означает, что любое изменение в одном участке не должно требовать изменений в других.
Если в коде существует множество зависимостей, его сложнее поддерживать или изменять в будущем.
В коде должно быть минимальное количество как классов (шаблонов для создания объектов, обеспечивающих начальные значения состояний), так и методов (функций или процедур, принадлежащих определенному классу или объекту.
Код должен быть прост, удобен и понятен, чтобы любой разработчик мог его быстро прочитать. Для этого многие разработчики используют правила KISS (keep it simple and straightforward с англ. — «сохраняйте простоту») и YAGNI (You aren’t gonna need it с англ. — «вам это не понадобится»).
Используйте языковые инструменты статического анализа для проверки вашего кода.
Само по себе высокое качество программного обеспечения не подразумевает то, что это ПО безопасно. Отсутствие уязвимостей в коде до сих пор не является обязательным требованием для большинства компаний-разработчиков.
Согласно отчету Veracode, более трех четвертей (75,8%) приложений имеют хотя бы один недостаток безопасности, а 23,7% содержат недостатки высокой степени серьезности, и исправление этих недостатков обычно занимает месяцы.
Стоит иметь в виду, что уязвимый код создает угрозу не только для пользователя, но и для разработчика.
Современные операционные системы и приложения подключаются через интернет и регулярно обновляются. Эти обновления в большинстве случаев делаются не только для добавления дополнительных функций, но и для исправления ошибок. Обновления делают систему более устойчивой к новым вредоносным программам. Подробнее о необходимости обновлений мы писали в аналитическом обзоре.
Из-за уязвимостей в коде хакеры и совершают атаки на устройства. Так, они могут украсть информацию, вмешаться в работу устройства или удалить всю важную для вас информацию.
Список существующих уязвимостей довольно длинный, поэтому мы рассмотрим лишь некоторые из часто встречающихся, а также те, которые причиняют наибольший ущерб. Согласно исследованию одними из наиболее популярных уязвимостей являются: Information leakage (утечка информации) — 65,9%; Cross-Site Scripting (XSS, межсайтовый скриптинг) — 47,1%; SQL Injection (внедрение SQL-кода) — 27,8%.
Обеспечение безопасности приложения — это в первую очередь задача разработчика, который с первых строк написания кода продукта должен заботиться о безопасности продукта и пользователей. Специалисты по информационной безопасности могут помочь улучшить код путем поиска уязвимостей, которые необходимо закрыть.
В идеальном мире разработчик (самостоятельно или с привлечением специалистов) тестирует продукт на проникновение, применяя наиболее популярные и новые методы взлома, а после анализирует полученный результат и делает выводы.
Качество кода и безопасность кода — это не одно и то же, но они тесно связаны. И в нынешней среде киберугроз разработчики должны заботиться об обоих. Писать сразу хороший код проще, чем исправлять ошибки, влияющие на безопасность, которые нужно сначала найти, опередив злоумышленников.
Идеальный код, к сожалению, не всегда возможен, но важно стараться писать код как можно более чисто. Необходимо постоянно совершенствовать свои навыки и обучаться.
Ниже мы собрали полезные ресурсы, которые помогут вам освоить мастерство безопасного и чистого кодинга.
В этой книге, состоящей из трех частей, вы узнаете о том, как отличать плохой код от хорошего и как его исправлять. В первой части автор описывает основные принципы и приемы создания чистого кода и приводит примеры «правильного» кода. Во второй книге он демонстрирует сценарии, представляющие собой упражнения по чистке кода или по преобразованию некачественного кода в код с меньшим числом ошибок. В последняя части автор описывает путь мышления человека в процессе чтения, написания и чистки кода.
Книга написана простым языком, поэтому освоить ее сможет даже начинающий программист. Рекомендуется прочесть книгу людям, которые только начинают осваивать профессию, поскольку важно усвоить принципы написания правильного кода в самом начале работы.
Эта книга стала учебником для многих разработчиков по всему миру. В ней подробно изложена идеология рефакторинга. Основу книги составляет подробный перечень более 70 методов рефакторинга, для каждого из которых описываются мотивация и техника испытанного на практике преобразования кода с примерами на Java. Рассмотренные в книге методы позволяют поэтапно модифицировать код, внося каждый раз небольшие изменения, благодаря чему снижается риск, связанный с развитием проекта.
Книга предназначена как для относительно новых разработчиков. Старшим разработчикам она покажет, как научить рефакторингу других.
Это высоко ценимая книга в индустрии разработки ПО. Основной посыл — «ошибки в программном обеспечении возникают из-за сложности кода». Книга была написана почти 30 лет назад, с тех пор идеи прочно вошли в сообщество разработчиков программного обеспечения.
Эта книга будет полезна разработчикам с опытом 3-5 лет. Стоит учитывать, что в некоторых местах она откровенно устарела и не всегда может быть применима к возможностям разработки небольших компаний.
Одним из недостатков является большой объем книги и то, что она, похоже, в основном ориентирована на объектно-ориентированные языки (C ++, Java) и даже более старые императивные (C, Ada и т. Д.)
Hack The Box — это онлайн-платформа для обучения кибербезопасности, позволяющая проверить свои навыки тестирования на проникновение. Платформа предоставляет множество задач. Некоторые из них моделируют сценарии реального мира, а некоторые больше похожи на задачи CTF. Hack The Box постоянно предлагает свежие хакерские задачи в полностью игровой и интуитивно понятной среде.
Платформа от Академии Digital Security — бесплатная платформа по обучению кибербезопасности, которое построено на игровых механиках и нацелено на отработку практических навыков на реальных кейсах, развернутых на виртуальных машинах. Курсы разработаны действующими пентестерами и исследователями в области информационной безопасности.
Курс «Веб-безопасность» содержит обзор самых распространенных атак, ключевых мер защиты веб-приложений (корпоративных порталов, ДБО, систем электронной коммерции и т.д.) и методов аудита кода. С курсом «Безопасное программирование на Java» вы сможете развить навыки защиты, выполняя задания на эксплуатацию и исправление кода в приложениях, написанных на Java. При этом результаты будут видны сразу на живом приложении.
На платформе Pentestit есть программы практического обучения в области информационной безопасности: Zero Security: A и Corporate Laboratories. Учебный процесс включает теоретические и практические занятия, на которых опытные инструкторы Pentestit рассказывают о характере и способах обнаружения уязвимостей.
«Zero Security: A» — это программа начального обучения тестированию на проникновение Pentestit, в рамках которой стажеры осваивают различные инструменты тестирования на проникновение и изучают основы этического взлома: от разведки и сбора информации до обеспечения безопасности в системе.
Хороший (и бесплатный) ресурс, хотя сосредоточенный на веб-приложениях, а не на тестировании на проникновение в целом. Он включает в себя материалы собственной исследовательской группы PortSwigger и лабораторные работы, где вы можете проверить полученные знания.
Одна из самых известных и популярных образовательных платформ. На сегодняшний день у них есть учебники по HTML, CSS, Sass, JavaScript, Rails, AngularJS, ReactJS, Ruby, Command Line, Git, SQL и Java.
Программирование — это ремесло, которое необходимо практиковать, оттачивать и совершенствовать. Написание чистого и безопасного кода — трудоемкая задача, решение которой имеет большое значение для продвижения карьеры и эффективности тайм-менеджмента.
Миф. Следующий вопрос.
В определенный момент осваиваешь каждый раз всё новое и необходимое для развития. Это утечки, загрузка, многопоточность, умение написать полет снаряда с учетом законов физики (когда движок ничего не дает, разве что синус рассчитать может).
Потом была пауза. Армия. Вернулся, думал я сис админ.
В итоге, в свободное время стал писать игры в браузере для себя.
Позже занялся рекламой, так как всё так же сис-админил.
И только в 2017 году обнаружил, что все эти навыки ценны. Но я всё это делал для себя) Так что, кто то занимается для себя, а кто то ради другой цели, поэтому и есть всегда эта проблема «а почему код грязный?».