From bcf9adf1556eb49058e5eef388ba237fd046f285 Mon Sep 17 00:00:00 2001 From: Slava Zgordan Date: Mon, 28 Sep 2015 12:11:47 +0200 Subject: [PATCH] 04.3 --- ru/04.3.md | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 ru/04.3.md diff --git a/ru/04.3.md b/ru/04.3.md new file mode 100644 index 00000000..28408081 --- /dev/null +++ b/ru/04.3.md @@ -0,0 +1,68 @@ +# 4.3 Межсайтовый скриптинг + +Для совершенствования взаимодействия с пользоваталем современные сайты содержат все больше динамического контента, что означает, что мы должны предоставлять информацию динамически в зависимости от поведения каждого пользователя. К сожалению, существует такое явление как "межсайтовый скриптинг" (известный как "XSS"), осуществляющее постоянные атаки на динамические сайты, в то время как сайты со статическим содержимым этим атакам не подвержены. + +Злоумышленники посылают на сайты, подверженные межсайтовому скриптингу, скрипты на JavaScript, VBScript, ActiveX или Flash. Если скрипт удачно вторгся на сайт, пользовательская инормация может быть похищена, а сайт наполнен спамом. Злоумышленники могут также изменить настройки пользователя на те, которые захотят. + +Если Вы хотите предотвратить этот тип атаки, Вам нужно комбинировать два следующих подхода: + +- Проверка всех данных, идущих от пользователя, о чем мы поговорили в предыдущей главе. +- Обработка всех данных, посылаемых клиенту, для того, чтобы предотвратить запуск опасных скриптов в браузере. + +Итак, как нам осуществить эти два пункта в Go? К счастью, пакет `html/template` имеет в своем распоряжении несколько полезных функций, чтобы обезопасить данные: + +- `func HTMLEscape(w io.Writer, b []byte)` отправляет в w версию b с заменой потенциально опасных символов на их escape-последовательности. +- `func HTMLEscapeString(s string) string` возвращает версию s с заменой потенциально опасных символов на их escape-последовательности. +- `func HTMLEscaper(args ...interface{}) string` формирует строку из множества аргументов с заменой потенциально опасных символов на escape-последовательности. + +Давайте изменим пример из раздела 4.1: + + fmt.Println("Имя пользователя:", template.HTMLEscapeString(r.Form.Get("username"))) // печатает на стороне сервера + fmt.Println("Пароль:", template.HTMLEscapeString(r.Form.Get("password"))) + template.HTMLEscape(w, []byte(r.Form.Get("username"))) // отправляет клиенту + +Если кто-то попробует ввести в поле для ввода имени пользователя ``, мы увидим следующую картину в браузере: + +![](images/4.3.escape.png?raw=true) + +Рисунок 4.3 JavaScript после обработки escape-последовательностью + +Функции пакета `html/template` помогут Вам заменить все теги HTML на их безопасные аналоги. Но что, если Вам нужно передать в браузер ``? В этом случае нужно использовать пакет `text/template`. + + import "text/template" + ... + t, err := template.New("foo").Parse(`{{define "T"}}Привет, {{.}}!{{end}}`) + err = t.ExecuteTemplate(out, "T", "") + +Вывод: + + Привет, ! + +Или можно использовать тип `template.HTML` : +Содержимое переменной типа `template.HTML` не изменяется с учетом escape-последовательностей. + + import "html/template" + ... + t, err := template.New("foo").Parse(`{{define "T"}}Привет, {{.}}!{{end}}`) + err = t.ExecuteTemplate(out, "T", template.HTML("")) + +Вывод: + + Привет, ! + +Еще один пример эскейпинга: + + import "html/template" + ... + t, err := template.New("foo").Parse(`{{define "T"}}Привет, {{.}}!{{end}}`) + err = t.ExecuteTemplate(out, "T", "") + +Вывод: + + Привет, <script>alert('Вы попались!')</script>! + +## Ссылки + +- [Содержание](preface.md) +- Предыдущий раздел: [Проверка введенных данных](04.2.md) +- Следующий раздел: [Дублирование отправки](04.4.md)