Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   безопасность, не выполнять javascript (https://javascript.ru/forum/misc/26929-bezopasnost-ne-vypolnyat-javascript.html)

tadjik1 28.03.2012 11:32

безопасность, не выполнять javascript
 
Добрый день.

Возник такой вопрос — как вывести javascript код, не выполняя его.
Простейшее приложение tasklist, пользователь может вводить любые данные в качестве текста таска. Надо затем отдавать это также текстом.

И вопрос сразу в догонку — какие еще могут возникнуть проблемы безопасности.

пример приложения — http://radiowav.es:3000

9xakep 28.03.2012 11:36

Ну попробуйте, что-то вроде этого:
<input type='button' value='push' onclick='a()'>
<script>
var b = false;
function a() {
if(b) {
alert('1') //тут ваш код
}
}
</script>

В общем изменяете все что хотите, но пока b = false, код не заработает
=======
Насчет приложения, уберите эти алерты, мол создано, исправлено..

tadjik1 28.03.2012 11:45

ну основной вопрос — как вывести javascript-код текстом, по аналогии с mysql-инъекциями.

<!doctype html>
<html>
<head>
<script>
function test(){
var string = 'alert("hack it")';
document.getElementById('example').innerHTML = string;
}
</script>
</head>
<body onLoad="test()">
<h3 id="example"></h3>
</body>
</html>

tadjik1 28.03.2012 11:49

ой, а так работает))
дело в том, что это строка?

9xakep 28.03.2012 11:53

tadjik1,
да

9xakep 28.03.2012 11:55

<div id='div'></div>
<script>
var a,b,c,d;
function a() {  }
a = {}
b = []
document.getElementById('div').innerHTML = document.getElementsByTagName('script')[0].innerHTML
</script>

tadjik1 28.03.2012 11:56

хорошо. тогда полная история =)

у меня есть файл tasks.json, в котором массивом сохранены объекты (таски).

{"id":"7","text":"ыав","lastupdate":"28.03.2012","complete":false}


вот если "text":"alert('1')", то он запускается, несмотря на то, что я добавил проверку и на клиенте, и на сервере (node.js)

server.js
newTask.text = String(post.text);


index.html

$('#taskList').append('<li id="' + String(value.id) + '">' + String(value.text) + '</li>');

9xakep 28.03.2012 12:01

Может тупость сморожу, попробуй взять в двойные кавычки: ""alert('1')""

tadjik1 28.03.2012 12:04

всё равно сработало =((

сработала вот такая строчка — "<script>alert('11')</script>"

просто алерт не работает

tadjik1 28.03.2012 12:17

кстати, на форуме где-то видел, заменяли специальные знаки <, > и /.

tadjik1 28.03.2012 12:29

нашел вот. называется это xss, примитивная защита такая —

string.replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;").replace(/"/g, "&quot;");


гуру, подскажите, какие еще могут быть проблемы и как от них защититься? не говорю о целенаправленных атаках, а просто вот от таких «болванов».

9xakep 28.03.2012 12:56

А почему он у вас вообще выполняется? Он в eval чтоли стоит?

tadjik1 28.03.2012 13:02

нет, зачем?
$.getJSON('tasks.json', function(data) {
          $(data.tasks).each(function(index,value){
            if(!value.complete){
              $('#taskList').append('<li id="' + value.id + '">' + value.text + ' <input type="button" class="edit" value="edit"><input type="button" class="complete" value="mark complete"></li>');
            }
          });
        });


вставляет в html тэги <script></script>, браузер их исполняет

9xakep 28.03.2012 13:11

Стоп...так вы пробовали в таксе написать: { id: "5", text:""alert('1')""... }

tadjik1 28.03.2012 14:16

9xakep, всё верно, так не работает. а вот так { id: "5", text:""<script>alert('1')</script>""... } запускается. в общем, решение — это заменить их на ascii коды. только теперь новая проблема — не пойму как их отображать правильно для клиента =)

tadjik1 28.03.2012 17:10

вы, наверное, имели ввиду этот. он в данном контекте не подходит.
через регулярки хорошо получается, но не пойму как их обратно клиенту хтмл кодом отдавать, а не текстом, чтобы красиво было. сам механизм не могу никак понять(

Questioner 28.03.2012 17:17

str.replace(new RegExp("<", "mig"), "&lt;");

9xakep 28.03.2012 18:48

Ну попробуйте при отправке проверять если в строке: <script> или </script>
<script>
var a = ''<script>asd</script>''
if((/\<script\>/).test(a)) {
a = a.replace(/\<script\>/, '')
a = a.replace(/\<\/script\>/, '')
alert(a)
} else { alert('noscript') }
</script>

===========
Мда...опять тупость сморозил...

nyols 28.03.2012 19:07

Цитата:

Сообщение от Maxmaxmахimus
сть специальный тег внутри которого теги парсится не будут, но я его забыл

Наверное вы имели в виду plaintext. Но он вроде глючит по всюду, никто не видит закрывающий тег.

9xakep 28.03.2012 19:25

Тогда code еще в добавок
Хотя там не грамотно сказано, код и без этих тегов читаться не будет:
function a() {
alert('')
}
<code><script>alert('a')</script></code>

=============
А скрипт и без этих тегов выполняется..
===========
<plaintext>
<script>
alert('a')
</script>

А вот это уже что-то рабочее(в хроме), в других браузерах не проверял..

9xakep 28.03.2012 20:28

Так пусть юзает plaintext
====
pre никогда не работал ктстаи, хз почему(ну у меня по крайней мере)

9xakep 28.03.2012 20:49

Maxmaxmахimus,
Почему не сделали то? Работает же?
P.S. у него есть закрывающий тег если что
В опере тоже работает:
facebook:

Раед 28.03.2012 20:56

Цитата:

Сообщение от 9xakep
пусть юзает plaintext

Это ваш плейнтекст всю страницу после себя текстом выводит

9xakep 28.03.2012 21:13

...
<plaintext>
<script>
alert('1')
</script>
</plaintext>
<script>
alert('2')
</script>

==========
Ок...лохонулся
=======
Единственный закрывающий тег: поместить скрипт в конец страницы, т.к. он не закрывает код сверху, но ниже его не остановить...


Часовой пояс GMT +3, время: 01:38.