CORS
JSONP
CORS - cross origin resource sharing
CSP - content security policy
Идемпотентность - когда запросы вида GET, HEAD не изменяют состояние данных (если бы было иначе - можно послать картинку админу)
Чтобы злоумышленник не мог сделать через POST и формочку придумали CSRF-token
CSRF - cross site request forgery - подделка крос-доменных запросов
Это значит, что каждая формочка на нашем сайте должна содержать еще одно скрытое поле CSRF, в котором будет находится каждый раз разный токен.
JSONP
window.cb = (data) => {}
подключаем скрипт с сервера, куда пеередаем имя нашей функции, которую надо вызвать с данными
<script src=".../?callback=cb"></script>
cb({data})
Недостатки:
- только GET запрос (предназначено прежде всего для получения данных)
- вынуждены доверять сайту, с которого подключаем
CORS
Браузер шлет заголовок Origin (управлять из js нельзя).
Сервер проверяет и в Access-Control-Allow-Origin отвечает откуда разрешен доступ (список сайтов или звездочка). Если заголовок есть - сможем увидеть данные.
Но очень часто перед тем как отправить наш запрос отправляется дополнительный запрос OPTIONS
Должен быть получен ответ с заголовками Access-Control-Allow-Origin Access-Control-Allow-Methods. И если в списке есть наш метод - тогда наш запрос отправится.
Явная установка заголовков приводит к отправке OPTIONS (ждет Access-Ctonrol-Allow-Headers)
const a = new XMLHttpRequest()
a.open('GET', 'url')
a.setRequestHeader('content-type', 'application/json')
a.send()
a.addEventListener('readystatechange', () => {
if (a.readyState === a.DONE) {
console.log(a.responseText)
}
})
xhr.responseType // можно изменить формат выдачи text, arraybuffer, blob, document
xhr.reponse //запрошенные данные после выполнения
OPTIONS не отправляются, когда заголовок считается простым (GET, HEAD, POST) и заголовки только:
- Accept (какие форматы данных браузер готов принимать)
- Accept-Language (языковые предпочтения, устаревший Content-Language)
- Content-Type (значения x-www-form-urlencoded, multipart/form-data, text/plain - для совместимости при отправке форм)
a.getAllResponseHeaders()
a.getResponseHeader()
Небезопасные заголовки просто так не отдаются.
Сервер должен явно указать Access-Control-Expose-Headers, чтобы клиент мог читать заголовки.
По умолчанию заголовки кеширования cache-control, expires, last-modified, pragma + content-type, content-language
По умолчанию браузер не передает куки, и заголовки авторизации.
Чтобы передать куки в запросе (до send):
a.withCredentials = true
И проверка Access-Control-Allow-Credentials и Access-Control-Allow-Origin не должен быть звездочкой.
CSP
XSS-инъекция - подключение к странице кода, может украсть куки Content-Security Policy
default-src,
base-uri
block-all-mixed-content
child-src
connect-src
font-src
form-action
frame-src
img-src
media-src
object-src
plugin-types
script-src
style-src
report-uri
Content-Security-Policy-Report-Only