Jak utrudnić kopiowanie tekstu ze strony? – cz. 2

cyber security javascript protect hacker 1944688 Jak utrudnić kopiowanie tekstu ze strony? - cz. 2
4.5/5 - (2 votes)

Autor: Paweł Rajewski

Stosując kilka prostych instrukcji można utrudnić kopiowanie także zwyczajnego tekstu, wpisanego „z klawiatury”. Gdy zostaną pomysłowo zastosowane, mogą pomieszać szyki komuś, kto chciałby szybko i nieuczciwie wykorzystać naszą pracę.

Artykuł Grzybka pod tym samym tytułem (dział: Grafika), zainspirował mnie do przedstawienia paru prostych metod utrudniających „kradzież” tekstu z serwisu. Przedstawione metody funkcjonują w Internet Explorerze, być może także w innych przeglądarkach, a jeśli nie, z pewnością dadzą się do nich przystosować.

Prosta zamiana tekstu na grafikę, o czym pisał Grzybek, to sposób radykalny, ale mający sporo wad. Przy dłuższych tekstach plik robi się ogromny, praktycznie niemożliwe jest wprowadzenie w nim jakichkolwiek poprawek, tekst nie układa się na stronie przy zmianach rozdzielczości (a czasem bywa to pożądane). No i metoda ta rzeczywiście, jak wspomniał sam Autor, nie gwarantuje niemożności kradzieży – wszak co można przeczytać, można też przepisać (ręcznie lub szybciej – programem OCR).

Tymczasem stosując kilka prostych instrukcji można utrudnić kopiowanie także zwyczajnego tekstu, wpisanego „z klawiatury”. Ponieważ metody te bazują na skryptach (JScript), nie są to sposoby na ochronę tekstów, na których nierozpowszechnianiu naprawdę nam zależy. Niemniej, gdy zostaną pomysłowo zastosowane, mogą pomieszać szyki komuś, kto chciałby szybko i nieuczciwie wykorzystać naszą pracę.

Niestety, już sama natura HTML-a ułatwia rozprzestrzenianie i kopiowanie informacji. Wszystko co widzi internauta odwiedzający serwis, „spłynęło” już do jego komputera i może być bez trudu zapisane na dysk i skopiowane do innego programu. Jedyne co możemy zrobić, to zdezorientować złodzieja i narazić go na tyle zaskakujących niespodzianek, ile tylko jest możliwe.

Zacznijmy od zmylenia przeciwnika. Ponad tekstami kursor zmienia się w pionową kreskę – już to zaprasza do zaznaczania i kopiowania. A zatem na początek zmieńmy kursor nad tekstem na typową strzałkę. Załóżmy, że „chronimy” tekst znajdujący się w ramach paragrafu P.

<P STYLE="cursor: default">Udaję, że nie jestem tekstem.</P> 

Nad tym paragrafem kursor pozostanie strzałką. To oczywiście żadne zabezpieczenie, bo tekst nadal można zaznaczyć i skopiować. Spróbujmy zatem utrudnić zaznaczenie tekstu. Wykorzystam w tym celu zdarzenie onselectstart wywoływane w momencie rozpoczynania zaznaczania:

<P STYLE="cursor: default" onselectstart="alert('Tego nie 
możesz zaznaczyć');">Udaję, że nie jestem tekstem i nie można mnie 
zaznaczyć.</P> 

Próba zaznaczenia fragmentu zdania w tym paragrafie zakończy się wyświetleniem okienka z komunikatem. Można jeszcze bardziej zdezorientować przeciwnika nie wyświetlając mu żadnego komunikatu, a jedynie uniemożliwiając zaznaczenie. Taki tekst będzie sprawiał wrażenie grafiki, przy czym nie da się go skopiować czy zapisać tak jak obrazek:

<P STYLE="cursor: default" onselectstart="window.event.returnValue=false;">Udaję, że nie 
jestem tekstem i nie można mnie zaznaczyć.</P>

To jest już całkiem niezłe zabezpieczenie przed kradzieżą fragmentu tekstu, bo przecież czego nie można zaznaczyć, tego nie można skopiować. Nadal jednak można zaznaczyć tak zabezpieczony paragraf jako całość np. rozpoczynając zaznaczenie w poprzednim paragrafie i przeciągając je poprzez zabezpieczony tekst aż do paragrafu następującego po nim. Można też zaznaczyć go razem z całą stroną korzystając z funkcji „Zaznacz wszystko”. Jak się przed tym uchronić?

Najprostsze rozwiązanie to wykorzystanie „bąblowania” zdarzenia onselectstart i umieszczenie go w ramach znacznika BODY (bliższe informacje o „bąblowaniu” w artykule „Bąblujące zdarzenia„):

<BODY onselectstart="window.event.returnValue=false;"> 

Na tak opisanej stronie nie można zaznaczyć tekstu ani jako fragmentu, ani jako całości (bloku). Nie można też zaznaczyć całej strony. Wydaje się to bardzo skuteczne, ale może również utrudnić, czy wręcz uniemożliwić korzystanie ze strony uczciwym użytkownikom – np. wtedy, gdy strona zawierać będzie formularze.

Jeśli na zabezpieczonej w całości stronie chcielibyśmy zachować możliwość zaznaczania tekstu w ramach wybranych obiektów, można w ramach tych obiektów zablokować „bąblowanie” zdarzenia onselectstart instrukcją window.event.calcelBubble=true. Oto przykład formularza z okienkiem tekstowym umieszczonego na zabezpieczonej przez zaznaczaniem stronie. W ramach formularza można zaznaczać wpisany tekst, gdziekolwiek indziej na stronie – nie:

<BODY onselectstart="window.event.returnValue=false;"> 
<BR> 
Tego nie zaznaczysz<BR> 
<FORM onselectstart="window.event.cancelBubble=true;"> 
<TEXTAREA NAME="okienko"></TEXTAREA> 
</FORM> 
<BR> 
...i tego też nie.<BR> 
</BODY> 

Inny sposób zabezpieczenia, jaki można stosować zamiast (albo obok) utrudniania zaznaczania, to uniemożliwienie przeniesienia zaznaczonego fragmentu do schowka. To dość perfidna metoda, bo na stronie pozornie wszystko działa poprawnie, a tylko w schowku, nie wiedzieć czemu, nie pojawia się „skopiowany” fragment… W tym celu korzystamy ze zdarzenia oncopy wywoływanego w momencie przenoszenia danych do schowka:

<BODY oncopy="window.event.returnValue=false;">

Na takiej stronie wszystko będzie można zaznaczyć, ale żadnego tekstu nie da się z niej skopiować. Zdarzenie oncopy można też stosować w ramach pojedynczych obiektów np. paragrafów. Wówczas nie będzie możliwe skopiowanie fragmentów takiego paragrafu, choć będzie można skopiować go jako całość.

Tego rodzaju chwyty są skuteczne, dopóki nasz złodziej nie wpadnie na pomysł, aby zablokować działanie skryptów. Pozornie zostajemy tym rozbrojeni – wszystkie zabezpieczenia przestają funkcjonować i droga do naszych tekstów stoi otworem. Chyba, że…

…chyba, że bez uruchamiania skryptów te teksty w ogóle nie będą widoczne! A czego nie widać, tego nie można skopiować. Aby zobaczyć tekst trzeba uruchomić skrypty, a uruchamiając skrypty blokuje się możliwość zaznaczania (kopiowania). Aby to osiągnąć można wpisywać tekst instrukcją document.write() co daje dodatkowo możliwość zaszyfrowania tekstu (o czym za chwilę). Można również zadziałać prościej, bez większej ingerencji w stronę i stworzyć taki, na przykład, prosty skrypt:

<BODY STYLE="visibility: hidden;" 
oncopy="window.event.returnValue=false;" 
onload="window.document.body.style.visibility='visible';">

Tak opisana strona nie będzie widoczna bez uruchomienia skryptów, a po uruchomieniu nie da się z niej skopiować tekstu do schowka.

Naszemu złodziejowi artykułów, mającemu jakie-takie pojęcie o HTML-u, pozostaje teraz wyjście brutalne, choć w sumie proste – wyświetlić źródło strony i skopiować tekst z jej kodu. Chyba, że i tym razem zaskoczymy go dbając, aby tekstu, którego szuka, w kodzie strony nie było. Bez większego problemu możemy wpisywać tekst na stronę instrukcją document.write(), a skrypt (lub sam tekst w postaci zmiennej) umieścić w osobnym pliku. W takiej sytuacji wyświetlenie źródła strony nic nie da.

Zdeterminowany złodziej zapisze więc stronę na dysk i zajrzy do zewnętrznego pliku zawierającego tekst i, ewentualnie, skrypt wpisujący. Tu może trafić na kolejną niespodziankę. Tekst przeznaczony do wyświetlenia może być zapisany w postaci pomieszanych fragmentów porządkowanych przed wyświetleniem przez skrypt wyświetlający. Każdy paragraf może być osobną zmienną, a kolejność ich zapisu – przypadkowa. Może to być też specjalny mini-skrypt szyfrujący. Już zwykłe poprzestawianie liter czy wyrazów, łatwe do błyskawicznego odkodowania, może całkowicie uniemożliwić skopiowanie tekstu z kodu strony. A dokładniej – uniemożliwić skopiowanie tekstu mającego jakikolwiek sens. Nasz włamywacz będzie bardzo zdziwiony, gdy zamiast oczekiwanego artykułu zobaczy w kodzie mnóstwo bezsensownie pomieszanych liter lub wyrazów… Np:

<SCRIPT TYPE="text/Jscript" LANGUAGE="JScript"> 
var t=' Wyt metśkic eokelnj oywtspęjucą enzka ioztsła yazimneoienp rama i  -apzrsyetz n eiapzrsyytim .oPswat łetsk trtduynd  odozctynaai , aabdrozł taywd  odookodawin.aS rkpy tamp zr yyt mpsro ąazelęt- j se tysemrtcynz.yP dotswap doz  imneąnt t ketsj wayn ,rucuoh mksyrtp ,kspoui jezs rtno yywin kejogd izłanaai(  etsk tazzsfyorawyn ) ikwel jodz imneen j t wokzdeis rtno.yB<>RwUga:ap  maęiat,jż  erpezlgdąraikn eiw śyiwtealąjn eitkrócy hnzkawó , aikkl apscaijw  syętupąjychcp  oosib eazimneaiąjn  aejnd.ąD aletogp zrdes yzrfwonaei mbojeim  jksyrtpz anzcinakim& tlP;ERg&;t<.RBT>nes rkpy tejtst lyokp  goąlodyw mrpyzłkdamei w t kap ortsjef roim eomeżn eis rpwazdćis ęiw p artkcynzcy  haztssowonaaihc.'; 
var dlt=t.length; 
for (i=1;i<=dlt;i+=2) 
{ window.document.write(t.charAt(i)); 
  window.document.write(t.charAt(i-1)); 
}; 
</SCRIPT>

Uruchom ten skrypt, aby przeczytać jak prosto działa!

I tak wkroczyliśmy w zupełnie nowy obszar, jakim jest szyfrowanie tekstów. Raczej nie wykorzystamy w swoim serwisie profesjonalnych algorytmów szyfrujących, ale nawet tak proste, jak przedstawiony, mogą skutecznie zniechęcić amatora cudzej własności. Tym bardziej, że sam algorytm można również zakodować lub ukryć co sprawi, że będzie trudniejszy do zidentyfikowania. Ilość prostych przestawień, zamian lub podmian jest praktycznie nieograniczona i zależy tylko od naszej pomysłowości.

Dotarliśmy więc do momentu gdy:
– skopiowanie tekstu ze strony jest niemożliwe, bo bronią go skrypty;
– wyłączenie skryptów jest niemożliwe, bo strona nie będzie wyświetlona;
– podejrzenie źródła nic nie daje, bo tekstu nie ma w kodzie strony;
– podejrzenie pliku ze skryptem nie daje efektu, bo tekst jest pomieszany…

Utrudniliśmy co tylko się dało stosując przy tym raczej proste metody. Teraz pozostaje już tylko nadzieja, że złodziej nie odwiedza stron Creamsoft-u i nie czyta naszych artykułów…

Udanych prób i miłej zabawy w szyfrowanie
Paweł Rajewski

Skomentujesz?

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Administratorem Twoich danych osobowych będzie Rafał Płatek, prowadzący działalność gospodarczą pod firmą CREAM.SOFTWARE RAFAŁ PŁATEK, wpisaną do rejestru ewidencji gospodarczej CEiDG pod numerem NIP 681-112-89-55. Szczegóły związane z przetwarzaniem danych osobowych znajdziesz w polityce prywatności.