Files
build-web-application-with-…/ru/04.3.md
2021-06-21 22:01:42 +07:00

68 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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"))) // отправляет клиенту
Если кто-то попробует ввести в поле для ввода имени пользователя `<script>alert()</script>`, мы увидим следующую картину в браузере:
![](images/4.3.escape.png?raw=true)
Рисунок 4.3 JavaScript после обработки escape-последовательностью
Функции пакета `html/template` помогут Вам заменить все теги HTML на их безопасные аналоги. Но что, если Вам нужно передать в браузер `<script>alert()</script>`? В этом случае нужно использовать пакет `text/template`:
import "text/template"
...
t, err := template.New("foo").Parse(`{{define "T"}}Привет, {{.}}!{{end}}`)
err = t.ExecuteTemplate(out, "T", "<script>alert('Вы попались!')</script>")
Вывод:
Привет, <script>alert('Вы попались!')</script>!
Или можно использовать тип `template.HTML`. Содержимое переменной типа `template.HTML` не изменяется с учетом escape-последовательностей:
import "html/template"
...
t, err := template.New("foo").Parse(`{{define "T"}}Привет, {{.}}!{{end}}`)
err = t.ExecuteTemplate(out, "T", template.HTML("<script>alert('Вы попались!')</script>"))
Вывод:
Привет, <script>alert('Вы попались!')</script>!
Еще один пример эскейпинга:
import "html/template"
...
t, err := template.New("foo").Parse(`{{define "T"}}Привет, {{.}}!{{end}}`)
err = t.ExecuteTemplate(out, "T", "<script>alert('Вы попались!')</script>")
Вывод:
Привет, &lt;script&gt;alert(&#39;Вы попались!&#39;)&lt;/script&gt;!
## Ссылки
- [Содержание](preface.md)
- Предыдущий раздел: [Проверка введенных данных](04.2.md)
- Следующий раздел: [Дублирование отправки](04.4.md)