Западня JavaScript
Ричард СтолменЕсть два вида несправедливостей, которые могут выполняться страницей сайта. Эта страница описывает несправедливость отправки несвободных программ для выполнения в вашем компьютере. Есть также несправедливость, которую мы называем услугой-заменой программ, когда страница приглашает вас высылать свои данные, чтобы она могла проводить над ними вычисления на сервере — вычисления, которые несправедливы, поскольку у вас нет контроля над тем, какие вычисления проводятся.
Не исключено, что вы запускаете несвободные программы на своем компьютере каждый день, даже не осознавая этого — из вашего браузера.
Сообщество свободного программного обеспечения хорошо знакомо с идеей, что любая несвободная программа несправедлива по отношению к пользователям. Некоторые из нас защищают нашу свободу, отвергая всякие несвободные программы на наших компьютерах. Многие другие считают несвободность программы серьезным недостатком.
Многим пользователям известно, что этот вопрос касается модулей, которые браузеры предлагают установить, поскольку они могут быть свободными или несвободными. Но существуют другие несвободные программы, которые браузеры выполняют, не спрашивая вас и даже не говоря вам об этом — это программы, на которые ссылаются или которые содержат страницы сайта. Эти программы чаще всего написаны на языке JavaScript, хотя используются и другие языки.
JavaScript (официально называемый “ECMAScript”, но мало кто употребляет это название) когда-то применяли для мелких излишеств на страницах Интернета, таких как занятные, но несущественные детали отображения и навигации. Было допустимо рассматривать их просто как дополнения к разметке HTML, а не как настоящие программы, и не задаваться этим вопросом.
Некоторые сайты до сих пор используют JavaScript таким же образом, но многие применяют его для крупных программ, которые решают серьезные задачи. Например, “Google Docs” пытается установить в вашем браузере программу на JavaScript, занимающую полмегабайта, в сжатом виде, который мы называем “Obfuscript” (запутанный сценарий). Это программа в сжатом виде, полученная из исходного текста удалением избыточных пробелов, без которых программу невозможно читать, а также пояснительных замечаний, которые позволяют понять программу, и заменой всех значащих идентификаторов в программе на произвольные краткие идентификаторы, так что невозможно понять, что это должно означать.
Часть представления о свободных программах заключается в том, что у пользователей есть доступ к исходному тексту программы (ее плану). Исходный текст программы — это форма, предпочтительная для внесения программистами изменений — она содержит полезное форматирование, пояснительные заметки, а также осмысленные идентификаторы. Сжатая программа в качестве исходного текста никуда не годится; настоящий исходный текст этих программ пользователям не доступен, так что пользователи не могут разбираться в них; таким образом, программы несвободны.
Кроме того, что они несвободны, многие из этих программ вредоносны, потому что они шпионят за пользователем. Что еще более гадко, некоторые сайты пользуются службами, которые записывают все действия пользователя при просмотре страницы. Предположительно службы “урезают” записи, чтобы исключить какие-то конфиденциальные данные, которые сайт получать не должен. Но даже если это работает надежно, само назначение этих служб состоит в том, чтобы дать сайту персональные данные, которых он получать не должен.
Браузеры обычно не сообщают вам о том, что они загружают программы на JavaScript. В некоторых браузерах есть способ полностью выключить JavaScript, но даже если вы знакомы с этой проблемой, вам было бы достаточно трудно распознать содержательные несвободные программы и заблокировать их. Однако даже в сообществе свободного программного обеспечения большинство пользователей не знает об этой проблеме; молчание браузеров не выставляет ее напоказ.
Для ясности: язык JavaScript сам по себе не лучше и не хуже для свободы пользователей, чем любой другой язык. Можно сделать программу на JavaScript свободной, распространяя исходный текст по лицензии свободных программ. Если программа самостоятельна — если ее работа и назначение не зависят от страницы, на которой она используется — прекрасно; вы можете сохранить ее на своей машине, изменить ее и открыть в браузере, чтобы работать с ней. Можно даже упаковать ее для установки точно так же, как другие свободные программы, и вызова из командной оболочки. Эти программы не представляют никаких особых нравственных проблем по сравнению с программами на Си.
Проблема западни JavaScript возникает, когда программа на JavaScript загружается со страницей сайта, который посещает пользователь. Эти программы на JavaScript написаны для работы с конкретной страницей или сайтом, и они нужны, чтобы страница или сайт работали.
Предположем, вы копируете и модифицируете программу JavaScript данной страницы. Тогда встает другая проблема: даже если исходный текст программы доступен, браузеры не предлагают способа работать с измененной вами версией вместо исходной, когда вы посещаете этот сайт. Этот эффект сравним с тивоизацией, хотя его в принципе не так трудно преодолеть.
JavaScript — не единственный язык, на котором написаны программы, передаваемые с сайтов пользователю. Flash поддерживал программирование с помощью расширенного варианта языка JavaScript, но это все в прошлом. Microsoft Silverlight, кажется, создает проблемы, сходные с Flash, только еще хуже, поскольку Microsoft применяет его как базу для несвободных кодеков. Свободная замена Silverlight не решит адекватно проблему для свободного мира, если вместе с ней не будут поставляться свободные замены кодеков.
Апплеты на языке Java тоже выполняются в браузере и приводят к похожим проблемам. Вообще говоря, любая система апплетов приводит к проблемам этого рода. Наличие свободной среды для выполнения апплетов приводит нас только к постановке этого вопроса.
Теоретически возможно программировать на HTML и CSS, но на практике эти возможности ограничены, это неудобно; для каждой малости требуется незаурядное мастерство. Такие программы должны быть свободны, но на 2019 год CSS не представляет серьезной проблемы для пользователей.
Возникло мощное движение, которое призывает применять на сайтах только форматы и протоколы, которые свободны (некоторые говорят “открыты”); другими словами, те, документация на которые опубликована и которые каждый волен реализовать. Однако наличие программ на JavaScript на страницах сайтов делает это условие недостаточным. Сам по себе JavaScript свободен как формат, и когда его применяют на сайте, это не обязательно плохо. Однако, как мы видели выше, это может быть нехорошо — если программа на JavaScript несвободна. Когда сайт передает программу пользователю, недостаточно, чтобы программа была написана на документированном и не вызывающем затруднений языке — эта программа тоже должна быть свободна. Условие “пользователю передаются только свободные программы” должно стать частью критерия этичного поведения сайтов.
Молчаливая загрузка и выполнение несвободных программ — один из нескольких вопросов, поднимаемых “веб-приложениями”. Термин “веб-приложение” был создан, чтобы стереть принципиальное различие между программами, которые передают пользователям, и программами, которые работают на сервере. Он может обозначать особую клиентскую программу, которую выполняет браузер; он может обозначать особую серверную программу; он может обозначать особую клиентскую программу, которая работает рука об руку с особой серверной программой. Клиентская и серверная стороны затрагивают разные этические вопросы, даже если они так тесно связаны, что можно утверждать, что они представляют собой части одной программы. Эта статья рассматривает только вопрос программ на клиентской стороне. Вопрос серверной стороны мы рассматриваем отдельно.
Как на практике мы можем решать проблему нетривиальных несвободных программ на языке JavaScript на сайтах? Первый шаг — избегать выполнения их.
Что мы подразумеваем под “нетривиальным”? Это понятие растяжимое, так что это вопрос создания простого критерия, дающего хорошие результаты, а не поиска единственно верного ответа.
В настоящее время мы пользуемся правилом, согласно которому программа на JavaScript нетривиальна, если выполняется любое из условий:
- на нее ссылаются как на внешний сценарий (с другой страницы);
- в ней объявляется массив длиной более 50 элементов;
- в ней определяется именованный объект (функция или метод), который вызывает что-либо кроме примитива;
- в ней определяется именованный объект с более чем тремя условными конструкциями или циклами;
- программы вне именованных определений вызывают что-либо кроме примитивов и функций, определенных далее на этой странице;
- программы вне именованных определений содержат более чем три условных конструкции и цикла (всего);
- в ней вызывается eval;
- в ней делаются вызовы Ajax;
- в ней применяется нотация квадратных скобок для доступа к свойствам динамического объекта, что выглядит как объект[свойство].
- в ней изменяется DOM;
- она применяет динамические конструкции, которые трудно анализировать без интерпретации программы или загружается с программами, которые применяют такие конструкции. А именно, применение любых конструкций, кроме литерала строки с определенными методами (Obj.write, Obj.createElement и другие).
Как мы узнаем, свободны ли программы на JavaScript? В отдельной статье мы предлагаем метод, которым нетривиальная программа на языке JavaScript на странице сайта может указать адрес, по которому находится ее исходный текст, а также может указать и лицензию с помощью стилизованных комментариев.
Наконец, нам нужно изменить свободные браузеры так, чтобы они обнаруживали и блокировали несвободные нетривиальные программы на языке JavaScript на страницах сайтов. Программа LibreJS обнаруживает несвободные нетривиальные программы на JavaScript на страницах, которые вы посещаете, и блокирует их. LibreJS входит в состав IceCat и доступен в качестве дополнения для Firefox.
Пользователям браузера нужен также удобный механизм для указания программ, которые нужно использовать вместо программ на определенной странице. (Указанные программы могут быть полной заменой или только измененной версией свободных программ с той страницы.) Greasemonkey приближается к этому, но не совсем, потому что не гарантирует, что программа со страницы будет изменена перед тем, как эта программа начинает выполняться. Можно использовать локальный прокси-сервер, но это слишком непрактично для реального решения. Нам нужно построить решение, которое будет надежным и удобным, так же как и сайты для обмена модификациями. Проект GNU хотел бы рекомендовать сайты, выделенные только для свободных изменений.
Эти особенности будут позволять программе на JavaScript со страницы сайта быть по-настоящему свободной в практическом смысле. JavaScript больше не будет особенным препятствием на пути к нашей свободе — не более, чем C и Java сейчас. Мы сможем отвергать и даже заменять несвободные нетривиальные программы на языке JavaScript точно так же, как мы отвергаем и заменяем несвободные пакеты, предлагаемые для установки обычным образом. Тогда мы сможем начать кампанию по освобождению JavaScript на сайтах.
А пока выполнять несвободную программу на JavaScript допустимо в одном случае: если это нужно, чтобы послать жалобу операторам сайта и сообщить им, что им следует освободить или удалить программы на JavaScript с этого сайта. Пожалуйста, смело включайте временно JavaScript, чтобы сделать это — но не забудьте выключить его после этого.
Благодарности: Я благодарю Мэтта Ли и Джона Резига за их помощь в определении предлагаемого нами критерия, и Давида Парунакяна за то, что он обратил мое внимание на эту проблему.
Вебмастеры: есть несколько способов указать лицензию программ на JavaScript на сайте.