1. Первая и едва ли не самая громкая ошибка в Java, даже удостоившаяся внимания некомпьютерной прессы, позволяла обойти ограничение на соединение с посторонними хостами. Не будь этого ограничения, Java бы превратилась в идеальный инструмент взломщика, позволяющий делать черную работу чужими руками. При загрузке апплета запоминалось имя хоста. Взломщик, имеющий доступ к DNS-серверу своего домена, вполне мог подставить вместо своего адреса адрес жертвы. С тех пор все реализации Java запоминают IP-адрес сервера, с которого они загружались, а не имя хоста.
2. Netscape Navigator 2.01 воспринимал имя класса, начинающееся с символа «\», как вполне нормальное, что позволяло ссылаться практически на любой файл в системе, например лежащий в кэше браузера. Причем этот файл воспринимался уже как локальный и не попадал под ограничения для апплетов, загруженных из сети.
3. Ошибка, дающая возможность воспользоваться смешением типов.
4. Ошибки в верификаторе и механизме загрузки классов, позволяющие апплету создать свой ClassLoader. Это легко приводит к полному проникновению в систему. Защита строилась на том, что при создании нового ClassLoader вызывается конструктор предка, который возбуждает исключительную ситуацию. Был найден способ обойти вызов конструктора предка. Ошибка исправлена следующим образом: функция ClassLoader.defineClass, выполняющая ранее всю критичную работу, стала проверять флаг, устанавливаемый в конструкторе, и, только если он был установлен, вызывать private-функцию defineClass0.
5. Ошибка, связанная с приведением типов.
6. Проблема с пространствами имен. В двух разных апплетах могут быть описаны классы, имеющие одинаковые имена. Поскольку они выполняются в разных пространствах имен, проблема смешения типов не возникает. Но в Netscape Navigator 2.02 и первой бета-версии Internet Explorer типы исключений и интерфейсов сравнивались по именам, а не по парам (имя, пространство имен). И если один апплет передавал другому в качестве параметра объект такого класса, возникала стандартная ситуация смешения типов.
7. Незадолго до выхода Internet Explorer 3.0 в его последней бета-версии была обнаружена ошибка, связанная с именами пакетов (packages). Пакеты представляют собой группы классов, объединенных под одним именем. Их назначение двояко: во-первых, полное имя класса включает в себя имя пакета, которому он принадлежит; во-вторых, пакеты можно использовать для ограничения доступа – если не указан спецификатор доступа, считается, что переменная или функция доступна только классам этого пакета. Некоторые пакеты ограничивают свое членство лишь классами, входящими в стандартную поставку, за чем следит менеджер безопасности. Ошибка заключалась в следующем: менеджер безопасности учитывал только часть имени пакета при проверке контроля доступа, что не срабатывало для пакетов, чье имя начиналось с com.ms. В результате посторонний пакет мог получить доступ к внутренним переменным системных пакетов, в том числе к списку файлов, к которым апплет может получить доступ.
Остановимся чуть подробнее на некоторых из них.
Смешение типов может работать следующим образом. Предположим, что у нас есть два класса
class T
{
SecurityManager x;
}
class U
{
MyObject x;
}
Далее заводим два указателя – t класса T и u класса U, каким-то образом заставляем их указывать на одну и ту же область памяти, после чего выполняем следующий код:
t.x = System.getSecurity(); // получаем SecurityManager MyObject m = u.x;
Теперь m указывает на ту же область памяти, где находится SecurityManager, и мы можем безболезненно менять его содержимое через поля объекта m. Подобная атака сработает при любом смешении типов, остается лишь найти ошибку, позволяющую проделать подобное совмещение указателей.
И такая ошибка была найдена в одной из бета-версий Netscape Navigator. При создании класса T неявно создается тип массив класса Т для внутреннего пользования. Его имя начинается с «[», и, поскольку нельзя создать класс, имя которого начинается с этого символа, все работает безошибочно. Но в той версии Netscape Navigator удавалось загрузить класс с таким именем. Точнее, при этом выдавалась ошибка, но виртуальная машина устанавливала имя в своей внутренней таблице. В результате Java считала объект массивом, хотя он принадлежал совсем другому типу. Итог – замена SecurityManager и потенциальный захват системы.
Ошибка, связанная с приведением типов:
interface Inter
{
void f();
}
class Secure implements Inter
{
private void f();
}
class Dummy extends Secure implements Inter
{
public void f();
Dummy()
Читать дальше
Конец ознакомительного отрывка
Купить книгу