Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Иван Громов. Кроссдоменная безопасность в браузере

Иван Громов. Кроссдоменная безопасность в браузере

Все видели кнопки оплаты платежных систем в Интернете. Рассмотрим как они устроены. Челлендж в том, чтобы не отправлять пользователя на сайт оплаты с номером заказа, а сделать всё на сайте магазина. Для этого мы вооружимся кроссдоменными запросами и iframe-ами. Также рассмотрим, что нужно учесть на стороне сервера, чтобы это заработало

Python Community Chelyabinsk

February 03, 2018
Tweet

More Decks by Python Community Chelyabinsk

Other Decks in Programming

Transcript

  1. Ambient Authority Ранние браузеры могли делать только GET и POST

    запросы Ambient authority — «размытые полномочия» <form action="http://bank.com/transfer.do"> <input type="hidden" name="acct" value="Bob"> <input type="hidden" name="value" value="10000"> <input type="submit" value="Earn $100 now!"> </form>
  2. Same Origin Policy Origin = протокол + домен + порт

    + IE* * политика отключена в trust zones, локальных сетях и не учитывает порт Можно ✔ Подключить ресурсы Отправить форму POST-ом ❌ Нельзя AJAX запросы Доступ к DOM (для iframe, popup)
  3. Cross Origin Resource Sharing (CORS) Simple запросы Метод: GET, POST,

    HEAD Заголовки: Accept, Accept-Language, Content-Language, Content-Type Content-Type: application/x-www-form-urlencoded, multipart/form-data, text/plain
  4. Пример CORS Preflight (Предзапрос) Предзапрос OPTIONS /resources/post/ Access-Control-Request-Method: PUT Access-Control-Request-Headers:

    X-PINGOTHER, Content-Type Ответ Access-Control-Allow-Methods: PUT, GET, OPTIONS Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
  5. Заголовки ответа CORS Access-Control-Allow-Origin — [https://]example.com[:8081], *, null нельзя: site1.com

    site2.com, *.example.com, null Access-Control-Allow-Credentials — true | false нельзя с Access-Control-Allow-Origin: * Access-Control-Max-Age: 60 обязательно Vary: Origin
  6. База данных class Wallet(models.Model): balance = models.DecimalField('Balance') user = models.ForeignKey('auth.User')

    class Transfer(models.Model): amount = models.DecimalField('Amount') wallet_from = models.ForeignKey('wallet.Wallet') wallet_to = models.ForeignKey('wallet.Wallet') timestamp = models.DateTimeField(auto_now_add=True)
  7. Наивное API POST /api/tx/ {"to": "user1", "amount": 1} > Access-Control-Allow-Origin:

    https://good-partner.com > {"ok": true} 1. В API принимайте только application/json, его нельзя послать из обычной формы 2. Используйте Сross Site Request Forgery (CSRF) токены (а в Django просто не отключайте)
  8. TokenAuthentication Подходит для Desktop, Mobile клиентов и… CORS from rest_framework.authtoken.models

    import Token token = Token.objects.create(user=request.user) $ curl -X GET http://127.0.0.1:8000/api/example/ -H 'Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b'
  9. PostMessage API «...предоставляет контролируемый механизм, чтобы обойти это ограничение [SOP]

    способом, который безопасен при правильном использовании.» Mozilla Developer Network Web Docs
  10. PostMessage API Сайт партнера (основная страница) var popup = window.open("https://payment.com/iframe")

    popup.postMessage('getToken', 'https://payment.com'); Платежная система (popup/iframe) function receiveMessage(event) { if (event.origin !== "https://good-partner.com") return; } window.addEventListener("message", receiveMessage);
  11. API с токенами POST /api/token?origin=https://good-partner.com > {"token": "absdef12345"} POST /api/tx/

    {"user_to": 'user1", "amount": 1} + Token Auth > Access-Control-Allow-Origin: https://good-partner.com > Access-Control-Allow-Headers: Authorization > {"ok": true}
  12. Получение токена через iframe partner.com КУПИТЬ iframe payment.com/iframe.html 1 /token

    API Session Cookie 2 token payment.com server 3 /api/tx TokenAuthentication
  13. Авторизация через iframe partner.com КУПИТЬ iframe payment.com/iframe.html 1 /token API

    Session Cookie 2 token??? :( 3 payment.com/login.html Session Cookie, window.open 4 postMessage(“try again”)
  14. Заголовки безопасности X-Frame-Options Content Security Policy (SCP) HSTS (HTTP Strict

    Transport Security) HPKP (Public Key Pinning) SRI (Subresource Integrity) X-XSS-Protection Referrer-Policy а также — cookies: http, secure, SameSite — TFA (СМС код) — область действия токена
  15. Ссылки securityheaders.io — использует ли ваш сайт все возможные заголовки

    W3C CORS for Developers — использовал при подготовке Cure53 Browser Security White Paper — 300+ страниц про веб безопасность Understanding CSRF — статья про CSRF, как работает, зачем нужен OWASP 2017 Top 10 — рейтинг уязвимостей в вебе за прошлый год Демо — репозиторий на github с платежной системой и магазином