В опубликованном 26 января корректирующем обновлении WordPress 4.7.2 (https://wordpress.org/news/2017/01/wordpress-4-7-2-security-.../) без лишней огласки была устранена критическая уязвимость (https://blog.sucuri.net/2017/02/content-injection-vulnerabil...), позволяющая удалённому атакующему без аутентификации изменить содержимое любой страницы через манипуляцию с REST API. Разработчики WordPress пояснили (https://make.wordpress.org/core/2017/02/01/disclosure-of-add.../) отсутствие упоминания об исправлении уязвимости в анонсе тем, что они лишь придержали публикацию уведомления, желая дождаться пока будет установлено обновление у как можно большего числа пользователей, чтобы предотвратить волну атак и вандализма.
Проблема проявляется только в выпусках WordPress 4.7 и 4.7.1, более ранние версии не подвержены проблеме, даже при включении плагина REST API. REST API по умолчанию включён начиная с ветки 4.7 и предоставлет альтернативный способ манипуляции с настойками, комментариями и публикациями. Уязвимость была обнаружена 20 января исследователями из компании Sucuri в процессе реализации инициативы по аудиту открытых проектов. Разработчики WordPress оперативно выпустили обновление и при участии сетей доставки контента
Incapsula, Cloudflare и SiteLock убедились, что в трафике не встречаются попытки эксплуатации данной уязвимости, после чего решили на несколько дней придержать сообщение о проблеме.Уязвимость вызвана особенностью обработки передаваемых через REST API значений, в частности, передаваемые через $_GET и $_POST параметры имели более высокий приоритет в обработке, чем параметры, закодированные внутри пути. Воспользовавшись данной особенностью атакующий мог передать запрос с идентификатором, включающим не только цифры, но и буквы, и обойти таким образом проверки на наличие полномочий для выполнения операции.
Например, вместо штатного запроса "/wp-json/wp/v2/posts/1234" можно отправить "/wp-json/wp/v2/posts/1234?id=5678helloworld", для которого значение парамера "?id=" будет иметь более высокий приоритет, чем идентификатор в пути "/1234". При проверке прав доступа проверяется наличие идентификатора "5678helloworld" и так как он не найден и не привязан к владельцу, передаётся управление в вызов get_post, который должен завершить запрос не найдя страницу. Но перед вызовом функции get_post осуществляется приведение переменной к целому типу и вместо "5678helloworld" передаётся значение "5678", указывающее на существующую страницу, что приводит не к выходу, а к вызову метода update_item. Отмечается, что в зависимости от используемых плагинов уязвимость может привести не только к подстановке своего содержимого на страницу, но и к выполнению произвольного PHP-кода на сервере.
URL: https://blog.sucuri.net/2017/02/content-injection-vulnerabil...
Новость: http://www.opennet.ru/opennews/art.shtml?num=45974
Сейчас эксперты придут и скажут, что дело вовсе не в кривом дизайне похвпэ и что никто уже не использует $_GET и $_POST и вообще Word Press г о в н о к о д.
Это плата за слишком вольное неявное приведение типов.
По каким-то причинам современные программисты очень боятся выделять/освобождать память и приводить типы самостоятельно.
Потому что это "сложо, неэффективно, небезопасно, пока я буду этим заниматься, можно написать еще сотню строк кода".
>>небезопаснонебезопасная только потомучто сишная malloc такая ?
Аналогия некорректная. "PHP" - не язык программирования, а всего лишь шаблонизатор, соответственно и планка для него должна быть как для шаблонизатора. Уродливый дизайн, нет внятных исключений и т. д.? Так это потому, что он и не создавался как язык программирования.
какая аналогия ? о чём речь?>>Так это потому, что он и не создавался как язык программирования.
таки да - об этом говорю не я а сам автор, пхп не ЯП, а апликейшен сервер написанный на С.
> нет внятных исключенийО да, как же нубам без исключений, их же другому и не учили
PHP:json_decode("null"); // => NULL
json_decode("хах, я тоже null"); // => NULLJavaScript:
JSON.parse("null"); // => null
JSON.parse("а вот и не null"); // => SyntaxError: Unexpected token а in JSON at position 0-------
Задача: распарсить два числа из поля number двух объектов из двух строк с JSON, сложить их и вывести результат. Если что-то пошло не так, вывести сообщение об ошибке.
PHP:
$object1 = json_decode($string1);
if (json_last_error() !== JSON_ERROR_NONE) {
echo "Error: " . json_last_error_msg();
} else {
$object2 = json_decode($string2);
if (json_last_error() !== JSON_ERROR_NONE) {
echo "Error: " . json_last_error_msg();
} else {
echo "Result: " . $object1->number + $object2->number;
}
}JavaScript:
try {
console.log(`Result: ${JSON.parse(string1).number + JSON.parse(string2).number}`);
} catch (err) {
console.log(`Error: ${err.message}`);
}
>> кривом дизайне похвпэв данном случае вообще не при чем.
>> "/wp-json/wp/v2/posts/1234?id=5678helloworld", для которого значение парамера "?id=" будет иметь более высокий приоритет, чем идентификатор в пути "/1234"это недоработка чисто вордпресовская, легко можно представить подобное в любом другом веб проекте (имею ввиду неверную расстановку приоритетов для получения значения переменной).
>это недоработка чисто вордпресовская, легко можно представить подобное в любом другом веб проекте (имею ввиду неверную расстановку приоритетов для получения значения переменной).
> легко можно представить подобное в любом другом веб проектеЭто напрямую и означает, что глобальные (!) супермассивы вроде $_POST и $_GET можно напрямую использовать неправильно, и более того, делать это достаточно легко! Что в свою очередь ведет к кривому дизайну самого ПХП и громадному количеству легаси-кода, который написан с подобными допущениями.
> Это напрямую и означает, что глобальные (!) супермассивы вроде $_POST и $_GET
> можно напрямую использовать неправильно, и более того, делать это достаточно легко!
> Что в свою очередь ведет к кривому дизайну самого ПХП и
> громадному количеству легаси-кода, который написан с подобными допущениями.А при чём тут пост и гет? Тут речь о том, что вообще произвольные строки в качестве чисел использовать нежелательно.
Блин, сколько ж лет учат криворучек валидировать весь юзеринпут. Да хоть РЕГЕКСПАМИ, да. А воз и ныне там.
смешно в этом то, что вы не посмотрели код, доверившись только пересказу новости.
а между тем, именно так там и сделали.. валидировали регекспом :)
Причем тут приоритеты?
Когда в одном месте при анализе параметра _5678helloworld_ это 5678helloworld, а в другом 5678. Не удивлюсь, что id=0x162E мог себя вести аналогичным образом.
js:
parseInt('5678helloworld'); //5678
---
это проблема всех динамических языков, или даже приведения типов. а не конкретно php.
Я эту ошибку отношу исключительно на счет вордпресса, поскольку гуляние параметра по разным фильтрам "авось в какойнить подойдет" - это проблема не языка программирования, а конкретного программиста наваявшего подобное...
> js:
> parseInt('5678helloworld'); //5678
> ---
> это проблема всех динамических языков,Ну-ну.
-- lua
> print(tonumber("5678"))5678
> print(tonumber("5678helloworld"))nil
% введение
1 ?- atom_number('5678helloworld',X).
false.2 ?- atom_number('5678',X).
X = 5678.2 ?- number_chars(Num, "1234").
Num = 1234.3 ?- number_chars(Num, "1234HelloWorld").
ERROR: number_chars/2: Syntax error: Illegal number#tcl
% expr "123"
123
% expr "123Hello"
invalid bareword "123Hello"
in expression "123Hello";
should be "$123Hello" or "{123Hello}" or "123Hello(...)" or ...# любимейший язык анонимов с убунтой
>>> int('5678helloworld')Traceback (most recent call last):
File "<input>", line 1, in <module>
int('5678helloworld')
ValueError: invalid literal for int() with base 10: '5678helloworld'
>>> int('5678')5678
Кстати про любимый язык анонимов с убунтой:
print 6 + "123";
> unsupported operand type(s) for +: 'int' and 'str'
> Кстати про любимый язык анонимов с убунтой:
> print 6 + "123";
>> unsupported operand type(s) for +: 'int' and 'str'Типа, строгая типизация === зло?
>>> print str(6) + "123"6123
>>> print 6 + int("123")129
>>> myint=type('myint', (int,), dict(zip(('__add__','__radd__'), [lambda x,y: int.__add__(x,y) if all(map(isinstance,[x,y],[int,int])) else str(x) + str(y)]*2)))
>>> '3' + myint(4)'43'
>>> 3 + myint(4)7
>>> 3 + myint(4) + myint(7)14
>>> "3" + myint(4) + myint(7)'743'
>>> (x,y) if all(map(isinstance,[x,y],[int,int])) else str(x) + str(y)]*2)))Вот здесь вырвало.
>>>> (x,y) if all(map(isinstance,[x,y],[int,int])) else str(x) + str(y)]*2)))
> Вот здесь вырвало.Держите нас и далее в курсе ваших "достижений" и мы, возможно, когда-нибудь перепишем этот однострочник, идущий как PoC с типами, на что-то, соответсвующее "низкому порогу вхождения" и понятное любому школьнику.
Нубы всегда такие нубы. Лет через 5 предложите новому коллеге прочитать ваш код. Почитайте с ним вместе. Посмейтесь над тем, что ни хрена быстро не прочли. После чего задумайтесь.
> Нубы всегда такие нубы. Лет через 5 предложите новому коллеге прочитать ваш
> код. Почитайте с ним вместе. Посмейтесь над тем, что ни хрена
> быстро не прочли. После чего задумайтесь.А еще здесь тестов нет, да и документация отсутсвует!
В общем, ламы такие ламы. Они не знают, что такое PoC, зато готовы спустя 5 лет читать свой код на форумах.
Продолжаем эстафету. :)
Схема. Racket v6.1.
1 > (string->number "11")
2 11
3 > (string->number "11zxc")
4 #fCommon Lisp (SBCL v1.2.4)
1 * (parse-integer "11")
2 11
3 * (parse-integer "11zxc")
4 debugger invoked on a SB-INT:SIMPLE-PARSE-ERROR in threadPerl (v5.20.2)
1 $ print "11zxc" + 0
2* Argument "11zxc" isn't numeric in addition (+) at - line 1.
3 11
4 $ print "zxc11" + 0
5* Argument "zxc11" isn't numeric in addition (+) at - line 1.
6 0
[*] Для этих строк надо включить use warnings.
Однако даже с use strict, скрипт с ошибкой не сваливается.
Похоже, это камень в огород Perl.Zsh (v5.0.7)
1 % x=11zxc
2 % let x+=0
3 zsh: bad math expression: operator expected at `zxc'Bash (v4.3.30)
1 $ x=11zxc
2 $ let x+=0
3 bash: let: 11zxc: value too great for base (error token is "11zxc")
> js:
> parseInt('5678helloworld'); //5678
> ---
> это проблема всех динамических языков, или даже приведения типов. а не конкретно
> php.пхп не ЯП сам создатель об этом говорил, забудьте про него и весь холивар про теорию типов.
можно пруфы где создатель такое говорил.
любителям читать пруфыhttps://habrahabr.ru/company/idcee/blog/202890/
https://habrahabr.ru/company/edison/blog/315680/
Это вполне себе обычное дело для языков с нестрогой типизацией. Если человек не знает этого и садится кодить на пхп или жс, то для него есть особое название - быдлoкодер. Но никоим образом это не может быть претензией к языку, который изначально создавался с нестрогой типизацией, и в котором реализация оной выполнена как надо.
> Это вполне себе обычное дело для языков с нестрогой типизацией. Если человек
> не знает этого и садится кодить на пхп или жс, то
> для него есть особое название - быдлoкодер. Но никоим образом это
> не может быть претензией к языку, который изначально создавался с нестрогой
> типизацией, и в котором реализация оной выполнена как надо.
>>с нестрогой типизациейнет такого понятия, ни пхперы ни джиэсники даже понятия не имеют о теории типов, более менее с этим функциональщики знакомы. Даже сишники не в курсах, потомучто ни в одной книге даже у Ричи и кернигана о типах ничего не сказано.
тем не менее сишники в типах как-то не путаются. Динамика - это вообще заботливо разложенные грабли.
> тем не менее сишники в типах как-то не путаются. Динамика - это
> вообще заботливо разложенные грабли.не путаются эт по какой причине ? по той, что компилятор на столько тугодум не знает в скольких ячейках памяти сохранить результат ? а динамические чем отличаются тогда ? умом, что знают об этом ? Асм-му ваще по** на ваши инты, чары, флоаты он для этого юзает "корзинки" (регистры) конкретного размера для результатов вычислений.
Не путайте динамическую типизацию с нестрогой типизацией - это разные вещи. В Python динамическая типизация, но строгая.
В математике все сводится к строгости
> Если человек садится кодить на пхп или жс, то для него есть особое название - быдлoкодер.//fixed
Дело именно в гуанокоде.
> Дело именно в гуанокоде.Кидаться гуанокодом - это нормальное поведение вэб-макак.
>Сейчас эксперты придут и скажутТы уже пришел
> никто уже не использует $_GET и $_POSTДа? А чем там теперь пользуются?
Новости про баги вордпресса (да какие там баги, зияющие дыры) выходят так регуляно, что уже стали чем-то обычным
Использование wordpress, почти равносильно..
> Использование wordpress, почти равносильно..Жумлы ещё. С друпальчиком.
> молча устранена уязвимость..., кроме того молча добавлен новый вид бекдора...
автор, который вносил это, проиграл своему коллеге 5000 рупий - ибо таки спалили
>манипуляции с настойками))
2017года а у ВП ничего нового.
С ошибками приведения типов бороться сложно, неявное приведение могло произойти и в MySQL. А вот то что один модуль решает, что запись с заданным id не найдена, а потом другой спокойно с ним что-то делает - это, имхо, полный бардак в архитектуре.
Я одни делаю проверки regEx перед тем как использую значения?
И как люди пользуются WP?
Да и вообще, я видел бизнеса которые клипаю магазины и всякие веб сервисы на WP. Вот как так? Руки нужно отрубать таким девелоперам по самую шею
Ты гордишься тем, что как обезьянка повторяешь технику без попытки осмысления?
Если мне надо проверить существует ли переданный объект, то я просто сделаю if exists $pages{$page}. Что к этому добавит проверка регексом? Если какой-то параметр должен быть числом, то зачем его пропускать через проверку регексом, если все-равно после этого он пройдет через конвертацию в число? В данном случае причина фейла не в том, что не воспользовались регексом, а в том, что одни и те же по сути проверки существуют в разных местах, разными способами и вызываются более одного раза в процессе обработки запроса.
В вёбе ВЕСЬ юзеринпут должен быть завалидирован без допущений. Независимо от языка.
А не в вебе уже можно не заниматься валидацией? А в вебинтерфейсе "для себя" недоступном миру валидировать точно нужно? Ну и самое главное, регекс это единственный способ валидации?
> А не в вебе уже можно не заниматься валидацией? А в вебинтерфейсе
> "для себя" недоступном миру валидировать точно нужно? Ну и самое главное,
> регекс это единственный способ валидации?Нет, можете валидировать хоть чем, разрешаю. Главное - валидировать корректно.
> Ты гордишься тем, что как обезьянка повторяешь технику без попытки осмысления?очень даже осмысленно
>Если мне надо проверить существует ли переданный объект, то я просто сделаю if exists $pages{$page}. Что к этому добавит проверка регексом?
>>В вёбе ВЕСЬ юзеринпут должен быть завалидирован без допущений. Независимо от языка. - мудрый аноним"if exists $pages{$page}" - очень глупо, в зависимости от реализации Hash, это может привести к коллизиям.
>Если какой-то параметр должен быть числом, то зачем его пропускать через проверку регексом, если все-равно после этого он пройдет через конвертацию в число?
B том что нужно было слать лесом запрос /wp-json/wp/v2/posts/1234?id=5678helloworld в самой ранней стадии (это конечно если id всегда Number). да и RegEx не только, что я использую - я еще все фильтрую параметры, то есть там где я не жду id, я верну тебе HTTP 400.
> "if exists $pages{$page}" - очень глупо, в зависимости от реализации Hash, это может привести к коллизиям.Коллизия это конечно очень страшное слово, можно пугать им джуниоров, но что если тебе попадется кто-то более опытный и попросит тебя рассказать о последствиях такой коллизии? Только во взрослом ЯП, а не в какой-нибудь студенческой наивной реализации hash/map. Вдруг окажется, что единственное последствие это небольшой провал производительности.
> B том что нужно было слать лесом запрос /wp-json/wp/v2/posts/1234?id=5678helloworld в
> самой ранней стадии (это конечно если id всегда Number).А с этим кто-то спорил? Попробуй все-таки прочитать внимательно, что именно произошло.
if exists $pages{$page} - не глупо, а очень глупо, поскольку скорее всего pages не существует, и page передаётся куда-то в запрос. Я не про вордпресс конкретно, я про вообще.
> Я один делаю проверки regEx перед тем как использую значения?Ты не одинок, нет. Про остальное согласен.
Что вы думаете о MODX?
> Что вы думаете о MODX?Позитивчик.
Лучше о нём не думать...
Тоже похапе -> сорта одного и того же.
> осуществляется приведение переменной к целому типу и вместо "5678helloworld" передаётся значение "5678"Ну Семен Семеныч!
И не надо мол PHP опять виноват. С таким подходом ребят никакой инструмент не спасет.
Как можно больше обновятся, если будут знать о проблеме!!!
> Разработчики WordPress пояснили отсутствие упоминания об исправлении
> уязвимости в анонсе тем, что они лишь придержали публикацию
> уведомления, желая дождаться пока будет установлено обновление у как
> можно большего числа пользователей, чтобы предотвратить волну атак и
> вандализма.Какая прелесть. Совершенно обычная реакция... для нашкодившего подростка, который боится, что его засмеют или накажут.
Анонсы исправлений уязвимостей должны быть побуждающим фактором для обновления, а не наоборот. Публиковать такие вещи надо сразу же.
>приведение переменной к целому типу и вместо "5678helloworld" передаётся значение "5678"занимательная php-математика :)
Должен быть единое место получения параметров. И должна быть однозначнисть, где прячется ид , в пути или в параметрах
Если пэхэпэ такой прогнивший, то что юзать?
> Если пэхэпэ такой прогнивший, то что юзать?Статические HTML-сайты.
Предлагаю вообще не пользоваться интернетом и компом. И жить в лесу.
Слез кстати с докувики на такой в своём бложеке. Доволен. Брат жив.
> Если пэхэпэ такой прогнивший, то что юзать?Православный питончик же. Или рабьку. Или растик. Ну с рантаймом год по***ться придётся на каждый проект, и при апдейтах ещё. Проблем-то. Рынок же на месте стоит, конкуренции нет, можно и академично подойти.
> Православный питончик же. Или рабьку.Угу, вот только PHP 7 по производительности всухую уделывает рабьку с питончиком. Intel, к слову, сотрудничает с командой PHP, оптимизируя их процессоры конкретно под этот ЯП. Пока ребята пишут высокопроизводительные сайты, пишите свои тормозные жигули на рабьке с питончиком))
gantry + grav
Молодцы разработчики,всегда обновляют и держат руку на пульсе,вордпресс рулит !