Безопасность динамических языков
От: 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(). Так что там, где он недопустим, приходится выгрызать с корнями, насколько это вообще возможно.
The God is real, unless declared integer.
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, и забыл об этом. Потом, когда система начала сходить с ума, долго не мог найти граблю, сделал целый механизм подсчёта занятости и когда увидел, что именно лежит в списке длиной в сотню миллионов элементов — полез сравнивать код и увидел, что в релиз таки пошёл кривой код.)
The God is real, unless declared integer.
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() так, что он вызывает калькулятор. Прикольные грабли любителей объектной сериализации.
Re[4]: Безопасность динамических языков
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 26.12.11 13:34
Оценка: :)
Здравствуйте, мыщъх, Вы писали:

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

М>хорошо, давайте без аналогий. крупные компании, пишушие на php крупные сайты, мне не известны, зато известны студенты и админы, подрабатывающие на php.

wikipedia, digg, flickr, yahoo, photobucket, морда facebook (с оговорками)...

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


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

М>ибо программистам свойственно ошибаться и java сама по себе не обеспечивает безопасность автоматом.


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

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

М>то есть, вы все же считаете, что проблемы безопасности php вызваны его динамической природой, а бюджетом разработки?

Я глубоко задумался на этим вопросом и конечно причины не только в типизации. Думаю, что скоро набросаю где-нибудь заметку на эту тему. Мыслей много. Более того, я уверен, что если взять очень большое количество веб-приложений, то количество серьезных уязвимостей там для различных будет отличаться на 10-20% максимум. Но это будет средняя температура по больнице, не говорящая ни о чем. В общем, эту мысль раскрою позже.

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


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

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


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

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


Это точно.

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


А можно пример сертифицированного языка?

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

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


Где я такой бред утверждал?

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


Ага, конечно! Проблемы в модуле написанном на С++ для .NET, в котором утечки памяти тоже не имеют никакого значения. Они же написаны для взаимодействия с .NET в которой утечек памяти нет

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


Ну даже если так, что проблемы при создании нового объекта-типа, тут нужно доказать, что это связано именно с динамической типизацией, а не определенной семантикой создания новых типов.
Computer science is no more about computers than astronomy is about telescopes (c) Edsger Dijkstra
Re[4]: Еще один пример
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 04.01.12 13:51
Оценка:
Здравствуйте, __lambda__, Вы писали:
___>Здравствуйте, kochetkov.vladimir, Вы писали:

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

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

А есть динамические языки, где дефолтные параметры не являются мутабельными?

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

___>Вот выделенное тоже неверно. Ruby c динамической типизацией, но там оно не диктует такую семантику.

И что это доказывает? Что в ruby разработчики потратили больше времени на грамотную организацию деревьев объектов в исполняющей среде?

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

N>отсутствие желания читать FAQ по типичным граблям.


А можно ссылки на исчерпывающие факи по граблям в питоне и яваскрипте?

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re[8]: Чем конкретно чревата разработка сложных проектов на
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 04.01.12 13:51
Оценка: :)
Здравствуйте, __lambda__, Вы писали:
___>Здравствуйте, kochetkov.vladimir, Вы писали:

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

___>Ага, конечно! Проблемы в модуле написанном на С++ для .NET, в котором утечки памяти тоже не имеют никакого значения. Они же написаны для взаимодействия с .NET в которой утечек памяти нет

Если утечка таки-случится в CLR, а не модуле на C++, то мы получим примерную аналогию того, что происходит в моем примере.

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

___>Ну даже если так, что проблемы при создании нового объекта-типа, тут нужно доказать, что это связано именно с динамической типизацией, а не определенной семантикой создания новых типов.

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

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re[5]: Еще один пример
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 04.01.12 13:57
Оценка:
Здравствуйте, kochetkov.vladimir, Вы писали:

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


N>>отсутствие желания читать FAQ по типичным граблям.


KV>А можно ссылки на исчерпывающие факи по граблям в питоне и яваскрипте?


Я вообще-то говорил про типичные, а не про исчерпывающие. Не думаю, что такие есть хоть по какому-нибудь языку.
А для типичных — хотя бы книга Dive into Python, там много таких разъяснено.
Про JS ничего не скажу, я его не знаю.
The God is real, unless declared integer.
Re[6]: Еще один пример
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 04.01.12 14:02
Оценка:
Здравствуйте, netch80, Вы писали:

KV>>А можно ссылки на исчерпывающие факи по граблям в питоне и яваскрипте?


N>Я вообще-то говорил про типичные, а не про исчерпывающие. Не думаю, что такие есть хоть по какому-нибудь языку.

N>А для типичных — хотя бы книга Dive into Python, там много таких разъяснено.
N>Про JS ничего не скажу, я его не знаю.

Я не для поспорить, думал, может есть где-нибудь в структурированном виде что-то типа http://stackoverflow.com/questions/1995113/strangest-language-feature

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re[7]: Еще один пример
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 04.01.12 14:17
Оценка:
Здравствуйте, kochetkov.vladimir, Вы писали:

N>>Я вообще-то говорил про типичные, а не про исчерпывающие. Не думаю, что такие есть хоть по какому-нибудь языку.

N>>А для типичных — хотя бы книга Dive into Python, там много таких разъяснено.
N>>Про JS ничего не скажу, я его не знаю.

KV>Я не для поспорить, думал, может есть где-нибудь в структурированном виде что-то типа http://stackoverflow.com/questions/1995113/strangest-language-feature


Там интересный набор, но нет самого жуткого, на мой взгляд, примера — ALTER GOTO в Коболе.
А то, что JavaScript на первом месте по чудесам — очень показательно (это уже к соседнему постингу).
The God is real, unless declared integer.
Re[9]: Чем конкретно чревата разработка сложных проектов на
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 04.01.12 14:24
Оценка: +2
Здравствуйте, kochetkov.vladimir, Вы писали:

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

___>>Ну даже если так, что проблемы при создании нового объекта-типа, тут нужно доказать, что это связано именно с динамической типизацией, а не определенной семантикой создания новых типов.

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


Вообще-то совсем не очевидно, потому что
1) "хэш-таблиц" не всегда является верным (оно верно по умолчанию, но не всегда; см. хотя бы питоновские __slots__)
2) "изменяемых" тоже не абсолютно (кроме слотов, можно ввести явные ограничения)
3) не обязательно это влияет на безопасность

Правильно всё-таки сформулировать, что статически значимое большинство языков и реализаций на них — именно такие (с представлением объектов в изменяемых хэш-таблицах, без эффективного контроля назначения произвольных атрибутов), и это даёт определённую (порой заметную) часть проблем в реализации, включая защиту. Мнэээ... вот как загнул, самому завидно Актуальная проблема может быть выражена следующим образом:
1) Слишком большой вес набрали те из динамических языков, которые обладают наиболее диверсионными свойствами — как JavaScript и PHP. См. хотя бы твою ссылку про strangest language feature и множество примеров на JS. Питон по сравнению с ними ещё хороший пример (например, в нём в принципе нет автоконверсии между числом и строкой, как в перле, PHP или JS). Включение JS в нынешнем виде в HTML5 меня в этом смысле вообще ужасает.
2) Программисты на этих языках не получают адекватную подготовку, которая бы помогала компенсировать гибкость этих языков, чрезмерную для большинства практических задач. Каждый, кто пишет на таких языках, должен контролировать себя сильнее, чем там, где состав полей, названия функций и прочие места, где легко ошибиться, проверяются компилятором. Должны использоваться средства контроля имён, разнообразные чекеры с хитрой логикой, анализаторы, их подсказки должны тщательно проверяться. Никакая фича крупнее десятка строк, или оформленная как use-case для пользователя, не должна считаться законченной без теста, анализирующего реализацию во всех основных аспектах. Обязателен code review, для особо важных мест — парное написание. И так далее.

Только вот всё это пока что благие пожелания, увы. А вместо нормального подхода мы имеем яваскрипты в стандарте. Да уж, с тем, что тебе работы будет ещё лет на 20 минимум, я согласен
The God is real, unless declared integer.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.