А еще в java можно отрефлексировать какой-нить массив с совершенно левым полем length а потом смотреть туда и писать без всяких исключений - забавные вещи просматривались.
> Там должна фигурировать не JCE, а просто система безопасности Java2...
Так вот эта самая система безопасности и подвергалась критике. Да, ее по сравнению с Java 1 доработали. Ну и что, общие принцыпы построения как GUI, так и системы безопасности не поменялись. Остерхут критиковал именно принципы.
Вообще Java vs Tcl это гораздо более интересная тема для флейма чем это кажется на первый взгляд.
Особенно забавно, что году в 96-97 Остерхут и Гослинг сидели в Sun-е в соседних комнатах. И реализовалывали в своих языках совершенно противоположные подходы ко всему, к чему только можно.
Я думаю, что заниматься флеймом - это вообще недостойное занятие, или я просто уже вышел из того возраста :)
По твоей статье честно скажу, что просмотрел ее очень бегло. Но мне показалось, что сравнение с Java несколько натянутое и не всегда выдерживает критики (стр. 14):
"...Hower, they [имеется ввиду Java и Telescript] differ from Safe-Tcl in that they provide only a single virtual machine that contains all of the objects and classes [и т.д.]..."
Это не совсем так (а в Mac OS X вообще не так), да и статья по-моему старовата.
На самом деле, Java позволяет запускать разные приложения под разными виртуальными машинами и c разными политиками безопасности, что и наглядно демонстрирует J2EE.
На мной взгляд, существующая система безопасности Java - это вполне удачный компромисс между возможным и желаемым.
>А вот с этого места поподробнее, желательно с примером кода. >Очень хочеться на это посмотреть.
Короче рефлексируем поле класса отнесенное к какому-либо объекту. Знаем что поле класса есть byte[].class (знаем что так делать не рекомендуется - для этого есть пакет Arrays.reflection однако ничто и не запрещает!)Так вот для class Dummy { public byte[] name = new byte[16]; } 1.4.1 давала мне name.length == 128! Спокойно пишем - читаем за границы массива. Ну и где тут безопасность?
$ cat Dummy.java
class Dummy{
public byte[] name = new byte[16];
public static void main(String args[]){
try{
Dummy d=new Dummy();
System.out.println("without reflection length="+d.name.length);
Теперь по поводу топика (раз уж пошла такая пьянка - тесты писАть)
Написал я и апплет и создаёт он класс (под 1.4.0).
Подгружаю File объект например, но ведь _каждый_ метод или memberfunction (проверял только File, FileInputStreams, Socket и соответственно их производные как FileReader итд) - обязан заново получать доступ к SecurityManager и throws Exception в методе. А класс без поведения - что это мне даст? Ещё раз прредупреждаю что не рылся по всем сановским сырцам на предмет: делают ли они в конструкторе какой-нить call в нижние лэеры, минуя свои методы (в которых уже сработает SecurityException). Пример: FileInputStream не имеет пустого конструктора (и я его как бы могу экстендить), но там же, в сановском конструкторе он тут-же делает вызов метода exist() который выбрасывает мне SecurityException. То есть я не вижу как же мне что-то такое сделать.
Кто предложит реальный эксплойт(с показом реального и _работающего_ кода могущего принести действительный ущерб)?
public class Test extends Applet{
public void init(){}
public void start(){
try{
Class clazz=getClass().getClassLoader().loadClass("org.MyFile");
Object instance=clazz.newInstance();
}
catch(Exception e){
System.out.println(e);
}
}
}
$ cat MyFile.java
package org;
import java.io.*;
/** Here we are experimenting */
class MyFile extends FileInputStream{
MyFile() throws Exception{
super("/tmp/test");
DataInputStream dis=new DataInputStream(this);
String line=dis.readLine();
System.out.println(line);
System.out.println("Esli mi sdes' - eto exploit");
}
}
$cd ..
$javac org/*.java
>Я думаю, что заниматься флеймом - это вообще недостойное занятие, или я просто уже вышел из того возраста
Бывают такие флеймы, в которых рождается истина.
Можно еще перловые SandBox-ы вспомнить (которые я так и не смог по-человечески задействовать, хотя пытался).
Проблема не в том, сколько у нас виртуальных машин, а в том как организовано взаимодействие между разными кусками untrusted кода.
Вторая проблема состоит в том, насколько легко дать нужному куску кода столько прав, сколько нужно и ни граном больше. От этого страдают и классическая модель Unix со всемогущим рутом, и достаточно мощная, но переусложненная и плохо документированная модель NT.
Кстати, недавно вот полез в POSIX capabilities на предмет посмотреть, как бы без suid root в одной программе обойтись, и выяснил что вот такой вот capability, чтобы можно было mlock сделать на кусок памяти, стандартом не предусмотрено.
Политики Safe-Tcl эту задачу решают. Причем просто, понятно и хорошо. Здесь сказался общий подход Tcl, где переопределение стандартных команд является штатным способом программирования. Кроме того, модель Safe interpreters Tcl делит приложение на достаточно крупные и обозримые блоки с четко специфицированными (посредством алиасов) интерфейсами. Чего нельзя сказать о Java, где разграничение прав доступа делается на уровне классов. Классы значительно мельче чем интерпретаторы и за их взаимодействием гораздо труднее уследить.
В Perl, где ограничение идет на уровне кодов операций все еще хуже. Я так и не понял, каким образом я могу предоставить контейнеру безопасный способ вызывать полезные операции (что тривиально делается в safe tcl через врапперы)
> Проблема не в том, сколько у нас виртуальных машин, а в том как организовано взаимодействие между разными кусками untrusted кода.
Согласен с этим утверждением.
На сколько помню, в J2EE очень многое определяется на уровне так называемых дескрипторов. Это - специальные XML-файлы, где определяются разные вещи, в том числе, и правила безопасности, применяемые при взаимодействии компонентов (beans).
Другими словами, очень многие вещи вынесены за уровень самого языка.
Думаю, что с реализацией метаданных (a la атрибуты в .NET) в ожидаемом JDK 1.5 (Tiger) Сан и дальше будет углублять эту линию, все больше увеличивая роль декларативного подхода.
Кстати, это может повлиять и на изменение существующей системы безопасности в Java. В некотором смысле это было бы очень удобным подходом к решению описанной Вами второй проблемы:
> Вторая проблема состоит в том, насколько легко дать нужному куску кода столько прав, сколько нужно и ни граном больше