Безопасность динамических языков
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 18.12.11 21:10
Оценка: 13 (7) +1 -1
Здравствуйте, 0K, Вы писали:

0K>Хотелось бы услышать конкретные причины.


Приведу голую статистику, выводы сделайте сами.

За последние три года я провел аудиты безопасности | пентесты | ревью кода 124 веб-приложений. На PHP были реализованы 78 из них (14 на готовых CMS, остальные либо с нуля, либо на CMF), из оставшихся 46: 42 на ASP.NET (C# во всех случаях) и 4 на python (1 на django-CMS, 2 на django, 1 на web.py). В каждом, я подчеркиваю, в каждом PHP-проекте была выявлена хотя бы одна уязвимость уровня реализации, получившая оценку по шкале CVSS >= 5.0 (это значит, что ее эксплуатация была обусловлена ошибками в коде и могла повлечь за собой серьезные проблемы с активами ИС).

В не-PHP проектах, такие уязвимости присутствовали, в среднем, в каждом 4-ом проекте, причем уязвимыми оказались 3 из 4 питонячих приложений

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

24.12.11 19:59: Ветка выделена из темы Чем конкретно чревата разработка сложных проектов на PHP
Автор: 0K
Дата: 06.12.11
— kochetkov.vladimir
24.12.11 19:59: Перенесено модератором из 'Компьютерные священные войны' — kochetkov.vladimir

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re: Чем конкретно чревата разработка сложных проектов на
От: __lambda__ Россия http://zen-hacker.blogspot.com/
Дата: 24.12.11 00:55
Оценка:
Здравствуйте, kochetkov.vladimir, Вы писали:

KV>Приведу голую статистику, выводы сделайте сами.


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

KV>Я не хочу гнать на динамические языки и сам до сих пор плотно использую питон в своей работе, но полученный мной опыт говорит о том, что существующие подходы к разработке веб-приложений на динамических языках, тупо не работают, по крайней мере, в отношении вопросов обеспечения безопасности. При этом, PHP является лидером среди динамики по числу доступных провокаций разработчиков к допущению ошибок в коде. Другого объяснения данным цифрам я не вижу, т.к. подавляющее большинство протестированных систем разрабатывалось весьма и весьма опытными разработчиками в составе толковых, а главное разных команд и явно не студентами с улицы.


Как вообще вы связали динамическую типизацию с безопасностью приложений написанных на них? В чем это проявляется? Типизация может быть статической, но не безопасной, такой как в Си например, все эти множественные проблемы с buffer overflow например. Типизация может быть динамической, но безопасной, такой как в Python/Ruby например.
Computer science is no more about computers than astronomy is about telescopes (c) Edsger Dijkstra
Re[2]: Чем конкретно чревата разработка сложных проектов на
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 24.12.11 04:46
Оценка:
Здравствуйте, __lambda__, Вы писали:
___>Здравствуйте, kochetkov.vladimir, Вы писали:

KV>>Приведу голую статистику, выводы сделайте сами.

___>Вывод для себя сделал такой. Выборка не репрезентативна. Тестовых данных нет, объективно верифицировать ваши результаты невозможно.

Буду рад обсудить любую другую, более репрезентативную на ваш взгляд.

___>А верить на слово в данном случае, это явно не в форум, где сидят инженера.


Скажем так, меня слабо волнуют вопросы доверия к моей персоне на интернет-форумах

___>Как вообще вы связали динамическую типизацию с безопасностью приложений написанных на них? В чем это проявляется? Типизация может быть статической, но не безопасной, такой как в Си например, все эти множественные проблемы с buffer overflow например. Типизация может быть динамической, но безопасной, такой как в Python/Ruby например.


То, о чем вы говорите, называется "сильная" и "слабая" типизация, а не "безопасная" и "не безопасная". Понятие же безопасности типов (type safety), к динамическим языкам не вполне применимо:

class A:
  def __init__(self, a, b):
    self.a = a
    self.b = b

a = A(1, 2)
a.WTF = 'There is no type safety here'
print(a.WTF)


И, в любом случае, я писал не о type safety, а об information security. Разницу надо пояснить?

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re[3]: Чем конкретно чревата разработка сложных проектов на
От: __lambda__ Россия http://zen-hacker.blogspot.com/
Дата: 24.12.11 05:23
Оценка:
Здравствуйте, kochetkov.vladimir, Вы писали:

KV>Скажем так, меня слабо волнуют вопросы доверия к моей персоне на интернет-форумах


И меня Ваша персона не волнует. Меня лично волнуют лишь тестовые данные и результаты.

KV>То, о чем вы говорите, называется "сильная" и "слабая" типизация, а не "безопасная" и "не безопасная". Понятие же безопасности типов (type safety), к динамическим языкам не вполне применимо:


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

KV>
KV>class A:
KV>  def __init__(self, a, b):
KV>    self.a = a
KV>    self.b = b

KV>a = A(1, 2)
KV>a.WTF = 'There is no type safety here'
KV>print(a.WTF)
KV>


И? Вы мне покажите, как это может привести к каким-либо уязвимостям. Я же Вам привел пример, как в статически типизированном C/C++ слабая (не безопасная) типизация может привести к многочисленным уязвимостям. Я про тот злосчастный buffer overflow.

KV>И, в любом случае, я писал не о type safety, а об information security. Разницу надо пояснить?


Так это именно Вы и связали динамическую типизацию с информационной безопасностью. Ссылку привести, чтобы напомнить?
Computer science is no more about computers than astronomy is about telescopes (c) Edsger Dijkstra
Re[4]: Чем конкретно чревата разработка сложных проектов на
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 24.12.11 15:56
Оценка: 22 (5)
Здравствуйте, __lambda__, Вы писали:

KV>>То, о чем вы говорите, называется "сильная" и "слабая" типизация, а не "безопасная" и "не безопасная". Понятие же безопасности типов (type safety), к динамическим языкам не вполне применимо:

___>Это синонимы. Учите матчасть.

Это не синонимы. Сильная типизация еще не подразумевает типобезопасность, как бы не считал человек, писавший эту и связанные с ней статьи в википедии. Рассуждать о безопасности типов в языках, допускающих модификацию контрактов в рантайме — по меньшей мере странно.

И на будущее: википедия не может являться сколь-нибудь значимым и достверным ресурсом, чтобы быть матчастью. Далеко не каждое утверждение в т.ч. и в приведенной вами статье, подкреплено цитатами из значимых внешних источников (собственно, эта статья отмечена, как требующая цитат, т.е. фактически содержащая ничем не подкрепленную на данный момент информацию). Поэтому вернемся к нашему вопросу: вы заявили, что в частности питон, обеспечивает типобезопасность. Я привел пример кода, фактически демонстрирующий, что это не так. С чем именно здесь вы не согласны? Что реальный и работающий код противоречит написанному в той статье? Это все или есть еще что-то?

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


<sarcasm> Да ну? Быть этого не может </sarcasm>

___>И? Вы мне покажите, как это может привести к каким-либо уязвимостям. Я же Вам привел пример, как в статически типизированном C/C++ слабая (не безопасная) типизация может привести к многочисленным уязвимостям. Я про тот злосчастный buffer overflow.


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

Допустим, мы храним в веб-приложении некоторое состояние, которое пробрасывается серверу от запроса к запросу посредством передачи на/с клиента некоторого куки-значения. У нас есть объект, описывающий это состояние на сервере и ленивый разработчик, который не хочет заморачиваться с двумя десятками его полей при передачи их в/из куки и хочет воспользоваться штатным модулем pickle, чтобы запихивать в куки целиком сериализованный объект и, соответственно, читать его оттуда при обработке очередного запроса. Разработчик знает, что использование этого модуля небезопасно, если десериализованные им объекты бездумно протаскивать в систему, т.к. в куках может прийти все, что угодно. Поэтому он решает предпринять шаги по исключению возможности появления в десериализованном объекте посторонних членов и обеспечению гарантии того, что он будет "крякать как утка" в любом случае, вне зависимости от данных, полученных из куки.

# -*- coding: UTF-8
import pickle, base64, pprint

class ViewState:
  # Аннотируем явным образом все возможные члены класса (лишь два, а не пара десятков указаны для простоты)
  __slots__ = ['VisitCount', 'SessionToken']

  def __init__(self, visitCount = 0, sessionToken = ''):
    self.VisitCount = visitCount
    self.SessionToken = sessionToken

  # Возвращает строку с сериализованным объектом
  def Serialize(self):
    return base64.b64encode(pickle.dumps(self))

  # Десериализует строку и возвращает соответствующий экземпляр ViewState
  @staticmethod
  def Deserialize(str):
    # Создадим пустой ViewState
    cleanObj = ViewState()
    # Десериализуем строку в "грязный" объект, в котором может быть все, что 
    # угодно...
    dirtyObj = pickle.loads(base64.b64decode(str))
    # ...и заполним значениями из "грязного" объекта только те поля ViewState,
    # которые были аннотированы в __slots__
    for (key,value) in dirtyObj.__dict__.iteritems():
      if key in cleanObj.__slots__:
        cleanObj.__dict__[key] = value
    # Значения полей от этого чистыми не стали, но сам объект - мы уже вполне
    # можем вернуть и быть уверенными в том, что оно крякает именно как ViewState и
    # что там нет ничего лишнего
    return cleanObj

# Протестируем...

initialState = ViewState(1, '5a55665d11da2ddc11b7b14d8dc4294b')
print(vars(initialState)) # {'VisitCount': 1, 'SessionToken': '5a55665d11da2ddc11b7b14d8dc4294b'} - OK

serializedState = initialState.Serialize()
print(serializedState) # KGlfX21haW5fXwpWaWV3U3RhdGUKcDAKKGRwMQpTJ1Zpc2l0Q291bnQnCnAyCkkxCnNTJ1Nlc3Npb25Ub2tlbicKcDMKUyc1YTU1NjY1ZDExZGEyZGRjMTFiN2IxNGQ4ZGM0Mjk0YicKcDQKc2Iu - OK

deserializedState = ViewState.Deserialize('KGlfX21haW5fXwpWaWV3U3RhdGUKcDAKKGRwMQpTJ1Zpc2l0Q291bnQnCnAyCkkxCnNTJ1Nlc3Npb25Ub2tlbicKcDMKUyc1YTU1NjY1ZDExZGEyZGRjMTFiN2IxNGQ4ZGM0Mjk0YicKcDQKc2Iu')
print(vars(deserializedState)) # {'VisitCount': 1, 'SessionToken': '5a55665d11da2ddc11b7b14d8dc4294b'} - OK

# И тут нам в куки приходит...
malformedState = ViewState.Deserialize('Y29zCnN5c3RlbQooUydjYWxjLmV4ZScKdFIu') # OMG, почему моя винда запустила калькулятор?!

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

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Еще один пример
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 24.12.11 17:01
Оценка:
Здравствуйте, __lambda__, Вы писали:

___>И? Вы мне покажите, как это может привести к каким-либо уязвимостям.


А вот это вообще, просто прелесть:

# -*- coding: UTF-8

userRights = [
  ('kochetkov.vladimir', 'read'),
  ('kochetkov.vladimir', 'write'),
  ('__lambda__', 'read')
]

def getUserRights(user, rights = []):
  for (k,v) in userRights:
    if user == k:
      rights.append(v)
  return rights

def doSomeWriteAction(login):
  if 'write' in getUserRights(login):
    print('Action allowed')
  else:
    print('Action disallowed')

doSomeWriteAction('__lambda__') # Action disallowed
doSomeWriteAction('kochetkov.vladimir') # Action allowed
doSomeWriteAction('__lambda__') # Action allowed <- WTF?!!!



[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re[5]: Чем конкретно чревата разработка сложных проектов на
От: Eugeny__ Украина  
Дата: 24.12.11 18:49
Оценка:
Здравствуйте, kochetkov.vladimir, Вы писали:


KV>


KV># И тут нам в куки приходит...
KV>malformedState = ViewState.Deserialize('Y29zCnN5c3RlbQooUydjYWxjLmV4ZScKdFIu') # OMG, почему моя винда запустила калькулятор?!
KV>

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

А можно для тех, кто про Питон слышал только очень отдаленно(ну и вообще толком не знаком с динамическими языками) разъяснить, в чем суть? А то у меня только мутные подозрения.
Новости очень смешные. Зря вы не смотрите. Как будто за наркоманами подсматриваешь. Только тетка с погодой в завязке.
There is no such thing as a winnable war.
Re: Безопасность динамических языков
От: мыщъх США http://nezumi-lab.org
Дата: 24.12.11 21:56
Оценка: +1
Здравствуйте, kochetkov.vladimir, Вы писали:

KV>Здравствуйте, 0K, Вы писали:


0K>>Хотелось бы услышать конкретные причины.


KV>Приведу голую статистику, выводы сделайте сами.


"спичек нет? значит, пидорас" (с) анекдот
давайте обратимся к логике: все вороны черные. следовательно, все, что черное, это ворона. ведь бред же.

а если вот так: некоторые из ворон черные. следовательно, все что черное, это ворона.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re[6]: Чем конкретно чревата разработка сложных проектов на
От: CiViLiS Россия  
Дата: 25.12.11 07:36
Оценка:
Здравствуйте, Eugeny__, Вы писали:

E__>А можно для тех, кто про Питон слышал только очень отдаленно(ну и вообще толком не знаком с динамическими языками) разъяснить, в чем суть? А то у меня только мутные подозрения.

Why Python Pickle is Insecure
... << RSDN@Home 1.2.0 alpha 5 rev. 1511>>
"Бог не терпит голой сингулярности" -- Роджер Пенроуз
Re[6]: Чем конкретно чревата разработка сложных проектов на
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 25.12.11 14:31
Оценка:
Здравствуйте, Eugeny__, Вы писали:

E__>А можно для тех, кто про Питон слышал только очень отдаленно(ну и вообще толком не знаком с динамическими языками) разъяснить, в чем суть? А то у меня только мутные подозрения.


В первом примере, проблема в

dirtyObj = pickle.loads(base64.b64decode(str))


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

Во втором случае, строчка

def getUserRights(user, rights = []):


читается не как "создать объект-функцию с аргументами user и rights, где последний будет иметь значение по умолчанию: 'пустой список'", а как "создать объект-функцию с аргументами user и rights, где последний будет иметь значение, равное вновь созданному объекту-списку". Соответственно, как только в этот объект-список добавляются элементы, значение rights по умолчанию уже будет равно не пустому списку, а именно изменнному объекту-списку.

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re[2]: Безопасность динамических языков
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 25.12.11 14:31
Оценка:
Здравствуйте, мыщъх, Вы писали:

М>а если вот так: некоторые из ворон черные. следовательно, все что черное, это ворона.


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

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

Вот и все объяснение полученным цифрам

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re[3]: Безопасность динамических языков
От: мыщъх США http://nezumi-lab.org
Дата: 25.12.11 21:42
Оценка: 27 (2)
Здравствуйте, kochetkov.vladimir, Вы писали:

KV>Здравствуйте, мыщъх, Вы писали:


М>>а если вот так: некоторые из ворон черные. следовательно, все что черное, это ворона.


KV> Любые аналогии лживы и уводят обсуждение в сторону, если используются как аргументы.

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

KV> Вот и все объяснение полученным цифрам

то есть, вы все же считаете, что проблемы безопасности php вызваны его динамической природой, а бюджетом разработки? мы на php не пишем. у нас web на java. и пишут его профи, которые на этом собаку съели. думаете, что тестировщики не находят ошибок? у нас целый отдел проверяет сайт на информационную безопасность и там работают люди типа нас с вами. правда, вам достаточно найти одну дыру, чтобы считать работу сделанной, а нашим тестировщикам необходимо убедиться в отсуствии дыр, что существенно сложнее и затратнее. и потому, релизы выходят не часто, т.к. после внесения в код любых изменений, он автоматически становится dirty и на паблик попадет только после полного цикла тестирования. в небольших конторах, пишуших на php, изменения вносятся на лету, зачастую вообще без тестирования.

вот и объяснения полученным цифрам.

ЗЫ. если я предложу свои написать код на php на меня посмотрят как на дурака, ибо php не сертифицирован ни в одной серьезной области. например, он не сертифицирован для работы с финансами и потому интернет-банк на php не напишешь. и отсутствие сертификата у php и его наличие у других языков, говорит намного больше цифр, т.к. сертификацией не идиоты занимаются.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re: Еще один пример
От: __lambda__ Россия http://zen-hacker.blogspot.com/
Дата: 25.12.11 22:13
Оценка:
Здравствуйте, kochetkov.vladimir, Вы писали:

KV>
KV># -*- coding: UTF-8

KV>userRights = [
KV>  ('kochetkov.vladimir', 'read'),
KV>  ('kochetkov.vladimir', 'write'),
KV>  ('__lambda__', 'read')
KV>]

KV>def getUserRights(user, rights = []):
KV>  for (k,v) in userRights:
KV>    if user == k:
KV>      rights.append(v)
KV>  return rights

KV>def doSomeWriteAction(login):
KV>  if 'write' in getUserRights(login):
KV>    print('Action allowed')
KV>  else:
KV>    print('Action disallowed')

KV>doSomeWriteAction('__lambda__') # Action disallowed
KV>doSomeWriteAction('kochetkov.vladimir') # Action allowed
KV>doSomeWriteAction('__lambda__') # Action allowed <- WTF?!!!
KV>


Это просто кривые руки, тут у Вас rights — глобальная переменная, от того и проблемы. Динамическая типизация тут не причем. Перепишем Ваш код так:
def getUserRights(user):
  rights = []
  for (k,v) in userRights:
    if user == k:
      rights.append(v)
  return rights


И все, проблемы как рукой сняло. Точно так же я мог сделать и в статически типизированных языках, например в C#:
void getUserRights(string user, List<string> rights)
{
    // same stuff as in python code
}
Computer science is no more about computers than astronomy is about telescopes (c) Edsger Dijkstra
Re[2]: Еще один пример
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 25.12.11 23:04
Оценка:
Здравствуйте, __lambda__, Вы писали:

___>Это просто кривые руки, тут у Вас rights — глобальная переменная, от того и проблемы.


Любая уязвимость — это кривые руки. Вопрос только в пороговом радиусе кривизны, допускаемом языком. Но с чего бы ей быть глобальной?

>>> def getUserRights(user, rights = []):
...   for (k,v) in userRights:
...     if user == k:
...       rights.append(v)
...   return rights
...
>>> rights
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'rights' is not defined


___>Динамическая типизация тут не причем.


Тут при чем внутренняя реализация аргументов по умолчанию в питоне, продиктованная динамической типизацией. Nemerle, например, таким не болеет:

#pragma indent

using System.Console;

module Program
  Main() : void
    def userRights = [
        ("kochetkov.vladimir", "read"),
        ("kochetkov.vladimir", "write"),
        ("__lambda__", "read")
    ]
    
    def getUserRights(user, mutable rights = [])
        foreach ((k,v) in userRights)
            when (user == k)
                rights = v :: rights
        rights
    
    def doSomeWriteAction(login)
        if (getUserRights(login).Contains("write"))
            WriteLine("Action allowed")
        else
            WriteLine("Action disallowed")
   
    doSomeWriteAction("__lambda__") // Action disallowed
    doSomeWriteAction("kochetkov.vladimir") // Action allowed
    doSomeWriteAction("__lambda__") // Action disllowed <- No WTF...


___>Перепишем Ваш код так:

___>[code]
___>def getUserRights(user):

Так его переписать нельзя, т.к. эта функция принимает два аргумента не просто так и там, откуда я это взял, в ее втором аргументе ей передают права по умолчанию, которые определены для каждого пользователя на текущий момент. Правильно переписать эту функцию так:

def getUserRights(user, rights = None):
  if rights == None:
        rights = []
  for (k,v) in userRights:
    if user == k:
      rights.append(v)
  return rights


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

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re[5]: Чем конкретно чревата разработка сложных проектов на
От: __lambda__ Россия http://zen-hacker.blogspot.com/
Дата: 25.12.11 23:16
Оценка:
Здравствуйте, kochetkov.vladimir, Вы писали:

KV>Это не синонимы. Сильная типизация еще не подразумевает типобезопасность, как бы не считал человек, писавший эту и связанные с ней статьи в википедии. Рассуждать о безопасности типов в языках, допускающих модификацию контрактов в рантайме — по меньшей мере странно.


Да, кругом одни идиоты и криворукие программисты, это я уже понял

KV># И тут нам в куки приходит...

KV>
KV>malformedState = ViewState.Deserialize('Y29zCnN5c3RlbQooUydjYWxjLmV4ZScKdFIu') # OMG, почему моя винда запустила калькулятор?!
KV>


Спасибо, буду знать, что модуль pickle не безопасен. Но я все равно не увидел связи с динамической типизацией. Тем более, та симпатичная Nadia Alramli, привела в своем блоге безопасные аналоги типа JSON, YAML. И пишет, что эта проблема применима для обоих модулей pickle & cPickle, где cPickle это аналог написанный на статичном Си. Так что, тоже не убедительно.
Computer science is no more about computers than astronomy is about telescopes (c) Edsger Dijkstra
Re[3]: Еще один пример
От: __lambda__ Россия http://zen-hacker.blogspot.com/
Дата: 26.12.11 00:37
Оценка:
Здравствуйте, kochetkov.vladimir, Вы писали:

KV>Любая уязвимость — это кривые руки. Вопрос только в пороговом радиусе кривизны, допускаемом языком. Но с чего бы ей быть глобальной?


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

KV>Тут при чем внутренняя реализация аргументов по умолчанию в питоне, продиктованная динамической типизацией.


Вот выделенное тоже неверно. Ruby c динамической типизацией, но там оно не диктует такую семантику.
Computer science is no more about computers than astronomy is about telescopes (c) Edsger Dijkstra
Re[6]: Чем конкретно чревата разработка сложных проектов на
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 26.12.11 06:43
Оценка: +1
Здравствуйте, __lambda__, Вы писали:

___>Спасибо, буду знать, что модуль pickle не безопасен.


Ну вообще-то это открытым текстом записано в его документации.

Пример Кочеткова интересен, но на грамотном code review все эти бомбочки были бы достаточно легко найдены. Разумеется, ключевое слово — "грамотное" — ещё поди найди того, кто это умеет...

___> Но я все равно не увидел связи с динамической типизацией.


Она слишком часто тянет за собой возможность eval(). Так что там, где он недопустим, приходится выгрызать с корнями, насколько это вообще возможно.
Re[3]: Еще один пример
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 26.12.11 06:51
Оценка:
Здравствуйте, kochetkov.vladimir, Вы писали:

KV>Здравствуйте, __lambda__, Вы писали:


___>>Это просто кривые руки, тут у Вас rights — глобальная переменная, от того и проблемы.


KV>Любая уязвимость — это кривые руки. Вопрос только в пороговом радиусе кривизны, допускаемом языком. Но с чего бы ей быть глобальной?


Пример с rights = [] в объявлении функции — специфическая грабля именно Питона и не существует, насколько я знаю, ни в одном другом языке схожего характера (Perl, Ruby, etc.)

Ловить её, да, трудно, но если бы её сделали из-за маскировки проблем чуть более сложным механизмом, её спокойно можно было бы получить и на Си.

KV>Тут при чем внутренняя реализация аргументов по умолчанию в питоне, продиктованная динамической типизацией.


Почему другим такого не продиктовало?

KV>def getUserRights(user, rights = None):

KV> if rights == None:
KV> rights = []
KV> for (k,v) in userRights:
KV> if user == k:
KV> rights.append(v)
KV> return rights

Ну да, это даже в документации сказано — переписывайте именно так.

KV>Но на то, чтобы только отловить то место, в котором внезапно у пользователей появляются несуществующие права, у разработчиков ушло несколько дней.


Это говорит только про недостаток опыта у разработчиков и отсутствие желания читать FAQ по типичным граблям. Впрочем, не буду считать то или другое их просчётом, потому что я сам на такое нарывался в своём коде. (Там история была интереснее — я сразу после тегирования релиза совершенно мимоходом исправил это в рабочей ветке на нормальный вариант, практически идентичный твоему примеру исправления rights, и забыл об этом. Потом, когда система начала сходить с ума, долго не мог найти граблю, сделал целый механизм подсчёта занятости и когда увидел, что именно лежит в списке длиной в сотню миллионов элементов — полез сравнивать код и увидел, что в релиз таки пошёл кривой код.)
Re[6]: Чем конкретно чревата разработка сложных проектов на
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 26.12.11 12:56
Оценка: 24 (3)
Здравствуйте, __lambda__, Вы писали:

___>Здравствуйте, kochetkov.vladimir, Вы писали:


KV>>Это не синонимы. Сильная типизация еще не подразумевает типобезопасность, как бы не считал человек, писавший эту и связанные с ней статьи в википедии. Рассуждать о безопасности типов в языках, допускающих модификацию контрактов в рантайме — по меньшей мере странно.


___>Да, кругом одни идиоты и криворукие программисты, это я уже понял


Отнюдь, скорее — кругом одни люди, которым свойственно ошибаться

KV>># И тут нам в куки приходит...

KV>>
KV>>malformedState = ViewState.Deserialize('Y29zCnN5c3RlbQooUydjYWxjLmV4ZScKdFIu') # OMG, почему моя винда запустила калькулятор?!
KV>>


___>Спасибо, буду знать, что модуль pickle не безопасен. Но я все равно не увидел связи с динамической типизацией.


Связь очень простая: в динамических языках, традиционным (а в некоторых языках и единственным) способом создания новых типов на лету является eval создающего их кода.

___>Тем более, та симпатичная Nadia Alramli, привела в своем блоге безопасные аналоги типа JSON, YAML.


Так я и не утверждал, что на динамических языках написать безопасный код вообще невозможно. Кстати, я бы воздержался от упоминания JSON всуе. Иначе столько DOM-based XSS накидаю, которые обусловлены исключительно динамической природой javascript, что разбирать будем до нового года Да, вот кстати, пример: есть небольшой сайт одного телекоммуникационного стартапа, организованного, судя по всему, студентами: http://www.aol.com

Если в тамошнюю строку поиска вставить:

aa&cb=alert("domXSS!!!")


и, не нажимая "search", подождать несколько секунд, то будет вам dom-xss, отловить который тестами вообще невозможно. Его и на code review обнаружить практически невозможно, т.к. строка поиска пробрасывается через кучу внешних скриптов, прежде чем попадает туда, где и происходит XSS. Эта уязвимость существует у них много лет и у того, кто ее обнаружил, такая возможность появилась только после того, как он смастерил собственную сборку firefox, под названием DOMinator, которая трейсит все переменные js на лету и осуществляет что-то типа перловского taint-cheking'а, выкидывая варнинги, когда tainted-переменные попадают в опасные sink'и. Еще один DOM-based (исправленный на данный момент, поэтому не покажу) на нашем сайте, нашли вообще случайно (чел по ошибке не в тот параметр вбил вектор атаки), когда тестили форму отправки SMS-ок, после июльской утечки у Мегафона. Так вот ее не выявил даже DOMinator за счет того, что этот параметр упаковывался в json и уходил на внешний скрипт, в котором и возникал XSS.

___>И пишет, что эта проблема применима для обоих модулей pickle & cPickle, где cPickle это аналог написанный на статичном Си. Так что, тоже не убедительно.


То, что канонический питон написан на С не делает его более статическим языком, по сравнению с PyPy, написанным на самом питоне. Язык реализации модулей питона не имеет здесь никакого значения, т.к. пишутся они для того, чтобы с ними взаимодействовала динамическая среда исполнения. И проблемы, о которых мы говорим, возникают именно в ней (в нашем случае, когда она создает новый объект-типа), а не в самих модулях.

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re[6]: Чем конкретно чревата разработка сложных проектов на
От: Miroff Россия  
Дата: 26.12.11 13:15
Оценка:
Здравствуйте, Eugeny__, Вы писали:

E__>А можно для тех, кто про Питон слышал только очень отдаленно(ну и вообще толком не знаком с динамическими языками) разъяснить, в чем суть? А то у меня только мутные подозрения.


Там сериализован объект совсем не того типа как ожидается. У него перегружен метод iteritems() так, что он вызывает калькулятор. Прикольные грабли любителей объектной сериализации.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.