Факультет Ruby on Rails
Освоите язык программирования Ruby, быструю разработку сайтов на Ruby on Rails и научитесь развивать сложные веб-приложения.
— Читать дальше «Факультет Ruby on Rails»
…
Освоите язык программирования Ruby, быструю разработку сайтов на Ruby on Rails и научитесь развивать сложные веб-приложения.
— Читать дальше «Факультет Ruby on Rails»
…
И для каждого из них указан ожидаемый рост популярности.
— Читать дальше «Опубликован топ-9 самых популярных языков программирования с высокими зарплатами»
…
Продолжая большую тему ошибок в коде, разберем, как с этим обстоят дела в Ruby. На этот раз речь пойдет о самых страшных багах, приводящих к проблемам с информационной безопасностью.
Перевод публикуется с сокращениями, автор оригинальной статьи Dhruv.
Ruby – универсальный
язык, сочетающий в себе простоту синтаксиса и мощные функции. Благодаря
популярности фреймворка Rails, Ruby входит в десятку лучших современных языков. Однако с таким комьюнити разработчиков существует множество распространенных
ошибок, ведущих к серьезным последствиям.
С момента создания Ruby обрел репутацию языка программирования, который обладает ориентированными на счастье разработчиков функциями. Тем не менее он имеет особенность в виде «острых ножей»
в своем ящике функций, и только вопрос времени, когда от них кто-то серьезно
пострадает.
«Острые ножи» – это все
доступное в Ruby метапрограммирование, и тот нюанс, что все открыто для
изменения/переопределения в любой момент. Дальше станет понятнее. Рассмотрим
ошибки и их решения.
Выполнять все, что
пользователь собирался отправлять – плохая мысль. А вот сериализация/десериализация
пользовательского ввода не кажется такой уж плохой идеей, т. к. никакой код при этом не
выполняется.
Основанная на Psych встроенная библиотека YAML Ruby поддерживает сериализацию пользовательских типов данных в YAML и обратно:
# serialize.rb
require 'yaml'
require 'set'
s = Set.new([1, 2, 3])
File.open('set.yml', 'w') do |file|
YAML.dump(s, file)
end
--- !ruby/object:Set
hash:
1: true
2: true
3: true
Десериализация этого
YAML возвращает исходный тип данных:
# deserialize.rb
require 'yaml'
require 'set'
file = File.read('set.yml')
s = YAML.load(file)
p s
$ ruby deserialize.rb
#<Set: {1, 2, 3}>
Как вы можете видеть,
строка -- !ruby/object:
описывает, как повторно создавать экземпляры объектов из их текстовых
Set
представлений. Это открывает множество векторов атаки, которые могут перерасти
в RCE.
Решение
Решение заключается в
использовании безопасной загрузки. Используйте функцию YAML::safe_load
вместо
YAML::load
. Она полностью блокирует загрузку пользовательских классов:
# deserialize.rb
require 'yaml'
require 'set'
file = File.read('set.yml')
s = YAML.safe_load(file)
p s
$ ruby deserialize.rb
/usr/ruby/2.7.0/psych/class_loader.rb:97:in `find':
Tried to load unspecified class: Set (Psych::DisallowedClass)
Стандартные типы вроде хэшей и массивов все еще могут быть сериализованы в документы YAML и
десериализованы из них, как и раньше.
---
hash:
1: true
2: true
3: true
$ ruby deserialize.rb
{"hash"=>{1=>true, 2=>true, 3=>true}}
Если вашему приложению
необходимо читать или записывать пользовательские файлы с диска или делать
запросы через API к пользовательским URL-адресам, вы можете написать следующий код:
# test.rb
puts 'Enter file path:'
path = gets.chomp
puts 'File contents:'
open(path, 'r') do |file|
until file.eof? do
puts file.gets
end
end
У пользователя запрашивается
имя файла, а потом его содержимое выводится построчно. Здесь есть ошибка.
Функция Kernel::open
из приведенного выше фрагмента кода имеет еще одну
дополнительную функцию, которая используется для порождения процессов. Посмотрите,
что происходит, когда вы передаете начинающиеся с символа конвейера ( | ) входные данные:
$ ruby test.rb
Enter file path:
|date
File contents:
Sun Nov 15 22:03:33 IST 2020
Она выполняет команду
date и передает выходные данные обратно Ruby. Злоумышленник будет выполнять
команды гораздо более разрушительные, чем в этом коде. В нашем примере базовое
RCE – удаленный пользователь, выполняющий код на сервере с полными
привилегиями, доступными вашему веб-приложению.
Никогда не запускайте
код от ненадежного источника, такого как пользователь, но если все-таки придется
– ограничьте доступ к выбранным ресурсам.
Решение
Никогда не используйте
Kernel::open
! Альтернативой является File::open
, URL::open
или
IO::open
, в зависимости от контекста. Попробуем еще раз, на этот раз с
File::open
вместо Kernel::open
. Такой вариант гораздо более безопасен, поскольку он не дает доступа к shell:
# test.rb
puts 'Enter file path:'
path = gets.chomp
puts 'File contents:'
File.open(path, 'r') do |file|
until file.eof? do
puts file.gets
end
end
$ ruby test.rb
Enter file path:
|date
File contents:
Traceback (most recent call last):
2: from test.rb:4:in `<main>'
1: from test.rb:4:in `open'
test.rb:4:in `initialize': No such file or directory @ rb_sysopen - |date (Errno::ENOENT)
Инъекция происходит,
когда пользовательский ввод из фронтенда без проверок и очистки применяется непосредственно
в SQL-запросе на бекенде.
Допустим, у вас есть
столбец users, в котором выполняется
поиск по введенному в форму имени. Вот, как бы это выглядело в Ruby:
User.where("name = '#{name}'")
Это небезопасно.
Рассмотрим следующий ввод от злоумышленника:
name = " ' OR '1' = '1" # Ввод от злоумышленника
Запрос ложный, как видно
в первой строке и крашится из-за вредоносного кода, как показано во второй
строке. WHERE всегда true и возвращает
каждого пользователя из таблицы:
SELECT * FROM users WHERE name = '<name>' -- <name> ложный запрос
SELECT * FROM users WHERE name = ' ' OR '1' = '1' -- все сломалось
Решение
Используйте один из следующих
двух способов:
User.where(["name = ?", name])
User.where({ name: name })
Оба подхода
предназначены для очистки значения перед генерацией запроса и поэтому невосприимчивы
для этой атаки.
Когда вы создаете
модель Rails, автоматически создается id – автоинкрементное целочисленное
поле. По большей части этого достаточно. Целочисленные идентификаторы
имеют преимущество: поскольку они постоянно увеличиваются, нет никаких шансов
на коллизию. Что произойдет, если пострадает безопасность:
Решение
Используйте UUID. С Rails
сделать это будет очень просто. После несложного изменения все ваши модели будут использовать UUID в качестве первичных ключей:
# config/application.rb
config.generators do |g|
g.orm :active_record, primary_key_type: :uuid
end
Если вы все-таки хотите
использовать целые числа, берите большие, выбранные случайным образом. Посмотрим
на структуру URL-адресов ролика из YouTube. Так выглядит его URL-адрес:
https://www.youtube.com/watch?v=dQw4w9WgXcQ
Идентификатор видео – это
случайное число между $0$ и $64^{11}$
(более 73 квинтиллионов чисел), закодированное
в Base64. Не совсем UUID, но и не целочисленное поле с автоинкрементом.
Ключевой вывод из описанных выше примеров – никогда не доверять юзеру. Данные пользователя не
должны быть напрямую сериализованы/десериализованы, оценены или обработаны. В
качестве дополнительных мер предосторожности подойдет специальный софт.
Инструменты анализа
кода, такие как линтеры и сканеры уязвимостей, могут найти множество просчетов
до того, как те начнут эксплуатироваться. RuboCop уведомит вас о проблемах безопасности, вроде небезопасной десериализации или IO
hijacking, а также предложит варианты исправления.
Brakeman
– сканер уязвимостей, который может найти SQL-инъекцию среди других ошибок
безопасности. Оба инструмента являются бесплатными и поставляются с открытыми исходными текстами.
DeepSource – комплексное ПО, способное сканировать код, на каждом коммите, анализировать результаты работы линтеров/анализаторов
и автоматически устранять множество проблем.
Для большинства языков программирования это решение имеет собственные
пользовательские анализаторы, которые постоянно совершенствуются
и обновляются. А еще оно элементарно устанавливается – нужно всего лишь
добавить .deepsource.toml файл в корень репозитория и DeepSource готов:
version = 1
[[analyzers]]
name = "ruby"
enabled = true
[[transformers]]
name = "rubocop"
enabled = true
Проблемы с безопасностью
– самые опасные и дорогостоящие. Будьте предельно внимательны и учитывайте все
вышесказанное в своих проектах. Обязательно продолжайте изучать язык программирования, ошибки других разработчиков и нашу статью про ошибки новичков. Удачи!
По итогам вчерашнего раунда С++ буквально уничтожил Cobol, а Assembler оказался почти в два раза популярнее чем Pascal. Результаты смотрите здесь. Сегодня у нас новые соперники: SQL/TypeScript и Python/Ruby. Вы
— Читать дальше «Третий раунд битвы язык…
В то время как Java и язык Си меняются местами на вершине рейтинга TIOBE, мы решили выяснить, какие языки программирования, наши подписчики любят больше всего. Завтра начинается баттл языков программирования
— Читать дальше «Примите участие в баттле я…
Делаю интерактивную карту, есть база данных кабинетов с координатами и этажами, где кабинеты расположены, этажи переключаются посредством кнопок, для каждого этажа своя кнопка. Как передавать переменную зависящую от кнопки в контроллер, чт…
Как можно скомпилировать\выполнить код из nodejs в ruby. Знаю что есть execjs, но что то не получается)
вот код nodejs
const os = require(‘os’);
function operatingTime() {
let sec = os.uptime;
timeMessage();
function timeMessag…
есть какая то пременная id = 5 в js, этот id надо передать в ruby.
Может я что то не так пишу в поисковике , или слишком не терпеливый но найти не могу решение.
…
Олимпиада пройдёт в весёлой атмосфере и предназначена для всех энтузиастов программирования: учеников, студентов, тестировщиков и других.
— Читать дальше «Международная олимпиада по программированию Proggy-Buggy Contest 2020»
…
У меня есть AJAX запрос, который взаимодействует с сервером написанным на ruby. Когда я делаю запрос с браузера сервер кидает ошибку.
127.0.0.1 – – [13/Sep/2020:14:59:38 -0400] "OPTIONS / HTTP/1.1" 404 462 0.0021
Когда я делал з…
Я делаю ajax запрос на свой сервер на сервер. Получить запрос я могу, ответ с сервера также идет. Но я не могу получить данные, которые я передаю по запросу. Как мне реализовать читание данных?
Мой запрос
$.ajax({
url: ‘http://127.0.0.1:56…
Ежегодная конференция, посвящённая Ruby, Rails и сопутствующим технологиям, впервые пройдёт в онлайн-формате и разделена на два дня.
— Читать дальше «Конференция RubyConfBY 2020 Online»
…
Поговорят про проблемы с производительностью Ruby-приложений, как писать простой и поддерживаемый код, CQRS-паттерне и использовании PostgreSQL в проектах.
— Читать дальше «Online Ruby Meetup №12»
…
Как возможно обратиться к python функциям exec() или eval() из Ruby c помощью RubyPython?
Есть бд с разными фрагментами кода, из них динамически с помощью ruby генерируется python код, в итоге мы получаем строку с python кодом, который нужно исполнить. Как можно это сделать, не создавая файл?
…
Онлайн-платформа Progate открыла доступ к 15 коротким онлайн-курсам для новичков. Можно изучить Python, Java, PHP, SQL, HTML, jQuery, Ruby и Ruby on Rails.
— Читать дальше «Онлайн-курсы ProGate»
…
Первый в 2020-м году митап из серии meta/conf. Встреча посвящена бэкенду и языкам Ruby, Golang, Rust, Node.js, Python и Elixir.
— Читать дальше «Backend Meetup meta/conf»
Уже давно и успешно использую miniperl в своей работе. Совсем недавно после сборки ruby обнаружил miniruby, – тоже удобная вещь, способная заменить собой с десяток-другой утилит. А есть ли аналоги у python, lua, node или какого другого инт…
Международная олимпиада для тех, кто владеет любым из следующих языков программирования: C++, Free Pascal, Java, C#, Python, Ruby, PHP, JavaScript.
— Читать дальше «Олимпиада по программированию Proggy-Buggy»
…
Будет полезно любым веб-разработчикам — в программе доклады об open source, командной работе и лучших практиках проектирования систем.
— Читать дальше «Ruby Meetup meta/conf»
…
Рубисты из разных стран обсудят последние новости, обменяются опытом и поделятся необычными техниками. Среди участников в этом году — создатель Nokogiri.
— Читать дальше «Конференция RubyConfBY 2019»
…
16 февраля в Санкт-Петербурге пройдёт митап локального сообщества Ruby-программистов. Кого ждут? Всех, кому не безразличен Ruby и интересна разработка на этом языке. О чём пойдёт разговор? На встрече выступят профессионалы сферы с докладами на серьёзны…
22 сентября в Минске состоится SEC — Software Engineering Conference от компании EPAM. Мероприятие впервые открыто для внешних участников. Что это? Это более 3 000 участников, 90 спикеров и 500 представителей экспертных сообществ. Последним отведены 2 …
Свежие комментарии