Аналог NoScript для Opera
Однажды, после того как очередной раз на моём компьютере поселились трояны из-за посещения заражённого сайта, я подумал о возможном аналоге плагина NoScript, только для Оперы. Широко известно, что Опера поддерживает пользовательские javascript-ы, так почему бы не воспользоваться встроенным функционалом браузера и не написать свой скрипт-плагин? Изучение документации с сайта opera.com выводит нас на необходимое АПИ для управления разрешением/запретом выполнения js на страничке. События:
[BeforeScript]
[BeforeExternalScript]
[BeforeJavascriptURL]
Этого вполне достаточно для реализации затеи. Но встаёт другая проблема: откуда скрипт будет брать настройки безопасности для сайтов? Вариант установить Denwer и использовать php для хранения такой информации конечно неплох, но подходит лишь для частного случая. Поэтому выбор пал на кукисы. Но вот незадача, вредоносный скрипт так же имеет доступ к кукисам и если userjs обрабатываются раньше, то это значит, что мы можем лишь полностью блокировать выполнение javascript. При частичной блокировке вредоносный скрипт изменит наши cookies и повысит тем самым себе привелегии до нужных.
А что, собственно требуется? Четыре режима работы:
0) Полная блокировка
1) Разрешено выполнение скриптов только с данного домена
2) Разрешено выполнение скриптов с домена и его поддоменов
3) Разрешено выполнение скриптов из любого места
Чтобы вредоносному скрипту было не повадно трогать наши кукисы поступим так: если кукис с именем А (условно) отсутствует, либо его значение не равно одному из прописанных внутри скрипта-плагина, то включается режим полной блокировки. Пользователь всегда может изменить настройки для данного сайта на более лояльные.
Итак, при открытии странички первыми выполняются userjs. Плагин должен получить значения нужного кукиса и на основе его выставить во внутренних настройках (поле объекта) номер режима работы javascript. При любом из вышеуказанных событий следует проверить номер режима и принять решение на основе его значения.
Привожу ниже законченный пример реализации. У скрипта есть некоторые баги, но в целом работает и для демонстрации идеи вполне подойдёт. Для безопасного серфинга следует изменить значения некоторых переменных на случайный набор символов:
var CookieName = 'SafeGuard'; имя кукиса с настройками
var ModeOnlyDomain = 's,i4yla84c,tl'; только текущий домен
var ModeDomAndSub = '98347qv4c,u58tu8'; домен и поддомены
// Слияние строк ModeOnlyDomain и ModeDomAndSub даёт режим "разрешено всё"
Меню настройки вызывается по CTRL+ALT+двойному клику в любом месте документа.
Полный код скрипта:
/*INFO
NAME = 'SafeGuard 2B'
VERSION = '1.01'
AUTHOR = 'Berserker'
DATE = '19.03.2009'
DESCRIPTION = '"NoScript" analog for Opera'
*/
z = function() {
// CONFIG
var CookieName = 'SafeGuard'; // #1 - SafeGuard CookieName (use smth like "monkey")
var ModeOnlyDomain = 's,i4yla84c,tl'; // #3 - Allow Only This Domain Mode (Attention! use smth unreadable like "li48nv8cn54t8m")
var ModeDomAndSub = '98347qv4c,u58tu8'; // #4 - Allow Domain and Subdomains Mode (Attention! use smth unreadable like "lwn<cmxl&54*")
// RUN
var win = self;
var doc = win.document;
var opera = win.opera;
var z = {}; // SafeGuard Protected Object
z.Cookie = CookieName;
z.Trim = function(Str) {
return Str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
} // .function z.Trim
z.GetCookie = function(Name) {
var Cookie = document.cookie.split(';');
var Len = Cookie.length;
var Res = '';
var i=0;
for(; i<Len; i++) {
Res = (this.Trim(Cookie[i])).split('=');
if(this.Trim(Res[0])===Name) {
return unescape(this.Trim(Res[1]));
} // .if
} // .for
return '';
} // .function z.GetCookie
z.SetCookie = function(Name, Value, Expire) {
document.cookie = Name+'='+escape(Value)+'; expires='+(new Date((new Date).getTime()+Expire*1000)).toGMTString();
} // .function z.SetCookie
z.Modes = {}
z.ModeNames = {}
z.Modes[ModeOnlyDomain] = 1;
z.Modes[ModeDomAndSub] = 2;
z.Modes[ModeOnlyDomain+ModeDomAndSub] = 3;
z.ModeNames[0] = 'BlockAll';
z.ModeNames[1] = ModeOnlyDomain;
z.ModeNames[2] = ModeDomAndSub;
z.ModeNames[3] = ModeOnlyDomain+ModeDomAndSub;
z.Mode = z.GetCookie(CookieName);
z.Mode = z.Modes[z.Mode]!==undefined ? z.Modes[z.Mode] : 0;
var Dialog = function(e) {
if(!((e.event.altKey) || (e.event.ctrlKey))) {
return;
} // .if
var z = arguments.callee.z;
var Res = prompt('SafeGuard Mode: (0 - Block All, 1 - Allow only this domain, 2 - Allow this domain and subdomains, 3 - Allow All (dangerous!))', z.Mode);
if(Res===undefined) {
e.preventDefault();
return false;
} // .if
z.Mode = Math.floor(parseInt(Res));
z.Mode = ((z.Mode>=0) && (z.Mode<=3)) ? z.Mode : 0;
z.SetCookie(z.Cookie, z.ModeNames[z.Mode], 3600*24*365);
location.reload();
} // .function Dialog
var ExtScript = function(e) {
var z = arguments.callee.z;
if(!z.Mode) {
e.element.src = '';
e.preventDefault();
return false;
} // .if
if(z.Mode==3) {
return;
} // .if
var Src = e.element.src;
var Pos = 0;
Src = Src.slice(Pos=Src.indexOf('://')+3, Src.indexOf('/', Pos+1));
var Domain = Src.split('.', 2);
Domain = Domain[Domain.length-1];
var DocDomain = document.domain.split('.', 2);
DocDomain = DocDomain[DocDomain.length-1];
if(((z.Mode==1) && ((Src!==DocDomain))) || ((z.Mode==2) && (Domain!==DocDomain))) {
e.element.src = '';
e.preventDefault();
return false;
} // .if
return;
} // .function ExtScript
var GenBlock = function(e) {
var z = arguments.callee.z;
if(!z.Mode) {
e.preventDefault();
return false;
} // .if
return;
} // .function GenBlock
Dialog.z = z;
ExtScript.z = z;
GenBlock.z = z;
opera.addEventListener('BeforeScript', GenBlock, false);
opera.addEventListener('BeforeExternalScript', ExtScript, false);
opera.addEventListener('BeforeJavascriptURL', GenBlock, false);
opera.addEventListener('BeforeEventListener', GenBlock, false);
opera.addEventListener('BeforeEvent', GenBlock, false);
opera.addEventListener('BeforeEvent.dblclick', Dialog, false);
return win.z;
}();
Плагин не загрязняет окружение переменных "window" и вообще не использует глобальные переменные.
Данный код не претендует на абсолютную корректность, а представлен скорее как демонстрационный пример. Если мы не возьмёмся за свою безопасность, она возьмётся за нас
P.S Для работы скрипта необходимо добавить в начало кода строчки:
// ==UserScript==
// @exclude http://example.com/*
// ==/UserScript==
...которые почему-то данный движок не переваривает
P.S.S В приложении вы можете скачать готовый плагин.
|
Спасибо будем опробывать.
А то только слез с FF на Opera обратно и понял что не хватает привычного уже ТщЫскшзе
а можно ли как-то переделать скрипт что бы работали кнопки вида
Item, ""="Go to page, "javascript:(...
например кнопка google поиск на странице и т.п. при режиме "0" не работают
спасибо
Это все конечно хорошо, но вот надо бы еще написать специкльно для таких ламеров как я куда потом этот плагин девать
Скрипт поместить в Opera\Profile\UserJs\
Давно искал подобную штучку-дрючку.Идеалом было-бы автоматически всплывающее,при наведении курсора,меню настройки.Большое спасибо за проделанную работу,заменю им ранее установленный block-external-scripts.js,т.к.он блокирует загрузку скриптов с других доменов и пропускает с данного.
в опере можно средствами оперы, правая кнопка, настройки для сайта, скрипты, отключить. или в глобальный настройках отклюбчить и в каких надо включать.
Вот откуда вы берётесь такие умные? Таким макаром, как вы предлагаете, крайне затруднительно индивидуально блокировать/разрешать скрипты, встраивающие элементы других сайтов. Как самые очевидные примеры - встраивание видео с ютуб и т.п., различные флеш. Да и кроме них на сайтах зачастую нужно блокировать не все скрипты, часть оставляя разрешёнными и имея возможность в любой момент разрешать/запрещать отдельные элементы. Встроенному механизму Оперы тут не сравниться с NoScript.
Скрипт понравился.Но есть одна проблемка. При использовании данного скрипта перестают работать другие пользовательские скрипты в Опере. Можно как-то этого избежать не путем изменения работы скрипта 1-2-3, а первоначальной настройкой?
Кроче я так понял этот скрипт ставить только на браузер через который реально только по порнушке лазить! вердикт: не годится для начинающих пользователей, а опытный ни када не поймает! В моем случае я только у клинтов вижу эти банера а сам при желаний хотел поймать и поглядеть как ловят, опыт оказался безрезультатным, какой только дряни не пересмотрел да и по различным всплыв окнам кликал! Может это судьба хапать такую херь! ))
Лучше отказатся от всей рекламы :-) Adguard - судите сами (а стоит пачку сигарет)