У среднестатистического пользователя Web-приложения есть только браузер в качестве клиента, который вы не можете контроллировать. Как вы будете доставлять все это (Java, Thrift etc.) к нему в браузер? Особенно если он не хочет ваших плагинов.
Вот автор и "предлагает" сделать новый Web (NewWeb) с улучшенным дизайном для улучшения безопасности и производительности. Чтобы клиенты (e.g. браузеры) "из коробки" поддерживали новые протоколы.
А что в этом такого? :-)
Разве автор статьи призвает отказаться от этого?
Он предлагает уменьшить количество потенциальных дыр, считая избавление от них на 100% невозможным.
JSON — тоже текстовый. Вставка во время транспорта делается также легко, как и в URL простого HTTP GET.
Да, вы можете использовать JSON валидацию — так же как программисты, допустившие SQL injection, могли бы использовать SQL с параметрами. А можете и не использовать, что является дырой.
Автор предлагает NewWeb, в котором накоторые дыры будут закрыты "by design", независимо от того, что вы используете (или не используете) на своем backend'е.
А вот что насчёт подмены строки как в моём примере?
Использовать параметризированный SQL :-)
Еще раз повторю: проблема — в возможности очень легко подменить данные в HTTP запросе с текстовым протоколом. Это будет источником новых уязвимостей.
Да, вы можете валидировать текстовые данные, добавиви в ваш стек еще одно место потенциальных ошибок и дыр. Именно так и делается в современном Web, и именно это критикует автор.
А можно перейти на другой протокол, который в ряде случаев вообще не допускает SQL injection "by design".
Вы неправильно понимаете суть SQL Injection. Она не в проблеме передачи данных.
Сам хак SQL Injection происходит только на этапе передачи данных, и никак иначе (если мы о Web говорим). Если вы этого не понимаете, то… это вы не понимаете суть SQL Injection ;-)
Например, если вы передаете числовые данные в бинарном виде (т.е. с фиксированной длинной и в строго определенном формате), то SQL Injection невозможен в принципе. Как видите, проблема решена полностью именно выбором способа передачи данных.
сериализация/десериализация всё равно будут нужны.
Конечно. Это должна быть стандартная часть протокола, и будет делаться через стандартный API.
Сам-то запрос бинарный, но внутри него хакнутая SQL-инструкция.
Неверно. Хакнут был HTTP запрос, а не SQL. В таком случае замена протокола общения сервера с базой на бинарный, либо введение обёртки поверх SQL (как вы предлагали) вообще ничего не даст.
Наивно полагать...
А я и не полагаю наивно ;-)
Автор предлагает не просто бинарный протокол, а еще и типизированный, что автоматически делает невозможным в принципе любые вставки в нетекстовые данные, потому что они фиксированной динны (а в HTTP можно сделать вставки в любые данные, не только текстовые, но и числа, даты и т.д.)
С текстом посложнее, но тоже решаемо. Например, в ряде случаев от текста можно вообще отказаться -> проблема решена полностьб — см. выше. Можно работать с текстом фиксированной длинны. И т.д.
К тому же, основная цель NewWeb (как автор это называет) не в устранении всех возможных уязвимостей на 100% (сам автор считает это невозможным), а в минимизации возможных ошибок, что приведет к уменьшению числа дыр.
Всё это должно делаться стандартными средствами протокола, чтобы не плодить ошибок от кастомных решений.
Бинарность протокола делает ненужным всякие ухищрения с экранированием/эскейпингом, а также существенно облегчает парсинг (особенно если данные типизированы). Это ведет к уменьшению числа потенциальных ошибок и новых дыр.
а вот текстовый протокол вполне себе может что-нибудь заэкранировать. Но на стороне сервера значение будет деэкранировано. И на этом этапе уязвимости не будет.
Вот как раз на это автор указывает как на еще один недостаток современного Web: разные экранирования/эскейпинги и постоянные парсинги текста, причем с обеих сторон. Во-первых, никаким экранированием и эскейпингом вы не сделаете текстовый запрос из Web приложения безопасными с точки зрения injection (разве что вы будете его подписывать, но там уже свои проблемы). Во-вторых, все эти манипуляции являются потенциальным источником ошибок и новых дыр.
Да, это следствие текстовой природы SQL. Но это сейчас общепринятый стандарт работы с реляционными СУБД и другого у нас нет.
Как я уже говорил, SQL injection — просто частный случай. Проблема в самом текстовом протоколе без всяких средств контроля данных.
Протокол общения backend'а с базой данных здесь вообще ни при чем. Ни с какого боку (подозреваю, они и так бинарные в большинстве DB).
Уязвимость возникла из-за комбинации пагубной практики программистов строить свои SQL запросы конкатенацией с сырыми данными, полученными из браузера, и возможности очень легко подменить данные в HTTP запросе с текстовым протоколом. И если первое можно победить, заставив программистов использовать параметры в SQL, то второе никуда не делось, и еще будет источником новых уязвимостей.
Так SQL и не является частью Web (deprecated WebSQL не в счет).
Автор говорит именно о Web и его протоколах, которые до недавних пор были исключительно тесктовыми, да и сейчас ключевые протоколы остаются таковыми.
Так что он предлагает (во второй чати статьи) заменить текстовые протоколы на бинарные.
Тем не менее, проблема SQL injection "успешно" возникла в Web, как и buffer overflow в C/C++ за 20 лет до этого. Вот автор и говорит о том, что Web повторяет путь десктопного софта, включая схожие грабли.
Так что хотя SQL injection и победили параметризацией, тесктовый протокол с текстовыми же маркерами начала и конца данных далек от того, чтобы считаться полность безопасным.
Если уж есть желание работать с сервлетами на Java, то советую изучить аннотации из последних спецификаций. Конфигурация и деплоймент значительно упростятся (например, не нужно вручную мапить сервлеты в web.xml).
У меня остаётся надежда, что удобный алиас uint128_t попадёт в стандарт — тогда я смогу выкинуть свой тип UInt128, пока его не увидел кто-то ещё. =)
А что вам мешает использовать предложенный к стандартизации шаблон прямо сейчас — вместо класса UInt128? Заодно обкатаете свое предложение в реальном проекте? ;-)
(strlen(str) + 1) — такое себе решение. Перед нами встают 2 проблемы:
А если нам надо выделить память под формируемую с помощью, например, s(n)printf(..) строку?
А если нам это не надо? Зачем решать несуществующую "проблему"? Вот когда нам в каком-либо конкретном случае это действительно потребуется, тогда и сделаем по-другому.
Внешний вид.
Нормальный внешний вид. А если не нравится — сделайте макрос (особенно для программы "где регулярно требуется обрабатывать строки").
работа со строками в C — это очень сложная тема
Ничего сложного. Это вы всё слишком усложняете. Вместо того, чтобы сразу написать "под катом" (или даже перед ним) вот это:
Весь «прикол» в том, что функция strlen не учитывает символ конца строки
вы зачем-то затеяли целое "исследование" с дампами из valgrind, а в конце привели решение, избыточное для простого копирования.
И чем больше тонкостей языка вы знаете, тем лучше ваш код.
Одна из "тонкостей" заключается в том, что вот это:
является нормальным и безопасным рабочим решенем, если вам нужно скопировать одну строку в другую (динамически выделенную).
для написания «безопасного» кода при динамическом выделении памяти рекомендуется все же использовать функцию calloc() вместо malloc() — calloc забивает выделяемую память нулями. Ну или после выделения памяти использовать функцию memset(). Иначе мусор, который изначально лежал на выделяемом участке памяти, может вызвать вопросы при дебаге, а иногда и при работе со строкой.
Зачем такие "сложности"? Вы же используете strcpy(), а она копирует всю строку, включая терминальный 0.
А-а, сорри, это же рядом было :-) https://habr.com/ru/post/532726/
[offtopic] А что это за ребята?
Вот это вряд ли. Скорее, парное программирование само является дополнительным источником стресса.
У среднестатистического пользователя Web-приложения есть только браузер в качестве клиента, который вы не можете контроллировать. Как вы будете доставлять все это (Java, Thrift etc.) к нему в браузер? Особенно если он не хочет ваших плагинов.
Вот автор и "предлагает" сделать новый Web (NewWeb) с улучшенным дизайном для улучшения безопасности и производительности. Чтобы клиенты (e.g. браузеры) "из коробки" поддерживали новые протоколы.
Даже в текущем стеке Web постоянно появляются новые технологии, и никто особо не переживает по поводу небыстрого избавления от багов :-)
Или и то, и другое :-)
Но ведь можно попробовать хотя бы уменьшить количество потенциальных дыр. В этом и состоит предложение автора статьи.
Используя SQL с параметрами.
А что в этом такого? :-)
Разве автор статьи призвает отказаться от этого?
Он предлагает уменьшить количество потенциальных дыр, считая избавление от них на 100% невозможным.
JSON — тоже текстовый. Вставка во время транспорта делается также легко, как и в URL простого HTTP GET.
Да, вы можете использовать JSON валидацию — так же как программисты, допустившие SQL injection, могли бы использовать SQL с параметрами. А можете и не использовать, что является дырой.
Автор предлагает NewWeb, в котором накоторые дыры будут закрыты "by design", независимо от того, что вы используете (или не используете) на своем backend'е.
Использовать параметризированный SQL :-)
Еще раз повторю: проблема — в возможности очень легко подменить данные в HTTP запросе с текстовым протоколом. Это будет источником новых уязвимостей.
Да, вы можете валидировать текстовые данные, добавиви в ваш стек еще одно место потенциальных ошибок и дыр. Именно так и делается в современном Web, и именно это критикует автор.
А можно перейти на другой протокол, который в ряде случаев вообще не допускает SQL injection "by design".
Сам хак SQL Injection происходит только на этапе передачи данных, и никак иначе (если мы о Web говорим). Если вы этого не понимаете, то… это вы не понимаете суть SQL Injection ;-)
Например, если вы передаете числовые данные в бинарном виде (т.е. с фиксированной длинной и в строго определенном формате), то SQL Injection невозможен в принципе. Как видите, проблема решена полностью именно выбором способа передачи данных.
Конечно. Это должна быть стандартная часть протокола, и будет делаться через стандартный API.
Неверно. Хакнут был HTTP запрос, а не SQL. В таком случае замена протокола общения сервера с базой на бинарный, либо введение обёртки поверх SQL (как вы предлагали) вообще ничего не даст.
А я и не полагаю наивно ;-)
Автор предлагает не просто бинарный протокол, а еще и типизированный, что автоматически делает невозможным в принципе любые вставки в нетекстовые данные, потому что они фиксированной динны (а в HTTP можно сделать вставки в любые данные, не только текстовые, но и числа, даты и т.д.)
С текстом посложнее, но тоже решаемо. Например, в ряде случаев от текста можно вообще отказаться -> проблема решена полностьб — см. выше. Можно работать с текстом фиксированной длинны. И т.д.
К тому же, основная цель NewWeb (как автор это называет) не в устранении всех возможных уязвимостей на 100% (сам автор считает это невозможным), а в минимизации возможных ошибок, что приведет к уменьшению числа дыр.
Всё это должно делаться стандартными средствами протокола, чтобы не плодить ошибок от кастомных решений.
Бинарность протокола делает ненужным всякие ухищрения с экранированием/эскейпингом, а также существенно облегчает парсинг (особенно если данные типизированы). Это ведет к уменьшению числа потенциальных ошибок и новых дыр.
Вот как раз на это автор указывает как на еще один недостаток современного Web: разные экранирования/эскейпинги и постоянные парсинги текста, причем с обеих сторон. Во-первых, никаким экранированием и эскейпингом вы не сделаете текстовый запрос из Web приложения безопасными с точки зрения injection (разве что вы будете его подписывать, но там уже свои проблемы). Во-вторых, все эти манипуляции являются потенциальным источником ошибок и новых дыр.
Как я уже говорил, SQL injection — просто частный случай. Проблема в самом текстовом протоколе без всяких средств контроля данных.
Протокол общения backend'а с базой данных здесь вообще ни при чем. Ни с какого боку (подозреваю, они и так бинарные в большинстве DB).
Уязвимость возникла из-за комбинации пагубной практики программистов строить свои SQL запросы конкатенацией с сырыми данными, полученными из браузера, и возможности очень легко подменить данные в HTTP запросе с текстовым протоколом. И если первое можно победить, заставив программистов использовать параметры в SQL, то второе никуда не делось, и еще будет источником новых уязвимостей.
Так SQL и не является частью Web (deprecated WebSQL не в счет).
Автор говорит именно о Web и его протоколах, которые до недавних пор были исключительно тесктовыми, да и сейчас ключевые протоколы остаются таковыми.
Так что он предлагает (во второй чати статьи) заменить текстовые протоколы на бинарные.
Тем не менее, проблема SQL injection "успешно" возникла в Web, как и buffer overflow в C/C++ за 20 лет до этого. Вот автор и говорит о том, что Web повторяет путь десктопного софта, включая схожие грабли.
Так что хотя SQL injection и победили параметризацией, тесктовый протокол с текстовыми же маркерами начала и конца данных далек от того, чтобы считаться полность безопасным.
Имелось в вид, что если вы контроллируете длинну "буферов" (длинну данных, или длинну запроса), никто не может добавить к запросу посторонний код.
Если уж есть желание работать с сервлетами на Java, то советую изучить аннотации из последних спецификаций. Конфигурация и деплоймент значительно упростятся (например, не нужно вручную мапить сервлеты в web.xml).
Скорее всего, это вы не осознаете, что это условие неоднозначно, и не обязательно требует задержки 50ms между каждым принтом.
А что вам мешает использовать предложенный к стандартизации шаблон прямо сейчас — вместо класса UInt128? Заодно обкатаете свое предложение в реальном проекте? ;-)
А если нам это не надо? Зачем решать несуществующую "проблему"? Вот когда нам в каком-либо конкретном случае это действительно потребуется, тогда и сделаем по-другому.
Нормальный внешний вид. А если не нравится — сделайте макрос (особенно для программы "где регулярно требуется обрабатывать строки").
Ничего сложного. Это вы всё слишком усложняете. Вместо того, чтобы сразу написать "под катом" (или даже перед ним) вот это:
вы зачем-то затеяли целое "исследование" с дампами из valgrind, а в конце привели решение, избыточное для простого копирования.
Одна из "тонкостей" заключается в том, что вот это:
является нормальным и безопасным рабочим решенем, если вам нужно скопировать одну строку в другую (динамически выделенную).
Зачем такие "сложности"? Вы же используете strcpy(), а она копирует всю строку, включая терминальный 0.