как отправить безопасным ajax запросы с php и jquery

<h2>эта проблема</h2><p>итак, какое-то время я экспериментировал с различными ajax подходами при отправке данных на сервер, который будет обрабатываться и храниться в базе данных mysql. </p><p>страница, на которую запрос ajax попадает в <code>api.php</code>, использует подготовленные операторы php pdo для сохранения данных, поэтому инъекции mysql на самом деле не являются проблемой, а пароли или данные, которые должны быть зашифрованы, также обрабатываются <code>api.php</code>, который не является ' т, что я здесь спрашиваю. мой вопрос больше относится к тому, как обеспечить безопасность данных при передаче от клиента к серверу.</p><h2>подходы</h2><p>в настоящее время у меня есть (для примера входа в систему я включил ниже):</p><ul> <li>сертификат ssl/https работает на домене.</li> <li>определенный запрос ajax (очевидно, не этот пример запроса на вход в систему, так как сессия не начинается) будет работать только в том случае, если сеанс php действителен для всего сайта (используется в обоих случаях <code>login.php</code> и <code>api.php</code> в этом примере) ,.</li> <li>ограничение скорости на <code>api.php</code> при доступе к функциям.</li> <li>php pdo подготовил операторы при взаимодействии с базой данных внутри <code>api.php</code>.</li> <li>шифрует конфиденциальные данные внутри <code>api.php</code> (не имеет отношения к вопросу).</li> </ul><h2>вопросы</h2><p>наконец, мои вопросы:</p><ol> <li>является ли этот подход к использованию асинхронных http (ajax) запросов достаточно безопасным, чтобы использовать его вместо того, чтобы просто отправлять данные на страницу php и перенаправлять дальше? (как этот способ улучшает пользовательский опыт).</li> <li>как я могу проверить, что данные, отправляемые моим пользователем, не были подделаны?</li> <li>достаточно ли я делаю достаточно для защиты данных моего пользователя, если нет, что еще я могу сделать?</li> </ol><h2>пример</h2><p>я понимаю, что у всех разные подходы к обработке данных своего сайта и их транспортировке. я также понимаю, что независимо от того, что вы делаете, вы никогда не сможете быть защищены на 100%, поскольку в вашей системе могут быть уязвимости и пути, которые вы не можете объяснить. мне нужны отзывы/улучшения относительно моего общего подхода к безопасной отправке данных, а не критика конкретного кода, приведенного ниже, поскольку это только пример. но любые конструктивные ответы приветствуются. спасибо, что нашли время, чтобы прочитать/ответить.</p><pre class="lang-js prettyprint-override"><code>function loginuser() { var process = "loginuser"; var data = $("form").serializearray(); data[1].value = sha512(data[1].value); // sha then encrypt on api.php page data = json.stringify(data); $("#loginbutton").html('<i class="fa fa-spinner fa-pulse fa-lg fa-fw"></i> login'); $.ajax({ type: "post", url: "api.php", data: {"process": process, "data": data}, success: function(data) { if (data.response.state == "success") { // if api.php returns success, redirect to homepage } else { // if api.php returns failure, display error } }, error: function(jqxhr, textstatus, errorthrown, data) { // error handling }, datatype: "json" }); } 

<strong>1. проверьте заголовок источника</strong>как <a href="https://www.owasp.org/index.php/cross-site_request_forgery_(csrf)_prevention_cheat_sheet#standard_header_checks">определено owasp , этого недостаточно, но рекомендуется:<blockquote> несмотря на то, что подделать любой заголовок из вашего собственного браузера довольно просто, это обычно невозможно сделать при атаке csrf, кроме как через уязвимость xss. вот почему проверка заголовков является разумным первым шагом в защите csrf, но поскольку они не всегда присутствуют, обычно они не считаются достаточной защитой. </blockquote>и <a href="https://wiki.mozilla.org/security/origin#origin_header_proposal_for_csrf_and_clickjacking_mitigation">от mozilla :<blockquote> заголовок origin считается полезным против кражи данных json и csrf-атак. информация, предоставляемая origin - немного контекстуальной информации о создании запросов - должна давать подсказки веб-серверам о достоверности запросов [...] </blockquote>проверка заголовка http_origin может быть записана как:header('content-type: application/json'); if (isset($\_server['http\_origin'])) { $address = 'http://' . $\_server['server\_name']; if (strpos($address, $\_server['http\_origin']) !== 0) { exit(json\_encode([ 'error' => 'invalid origin header: ' . $_server['http_origin'] ])); } } else { exit(json_encode(['error' => 'no origin header'])); } <strong>1. (бис) проверьте заголовок referer</strong>снова <a href="https://www.owasp.org/index.php/cross-site_request_forgery_(csrf)_prevention_cheat_sheet#checking_the_referer_header">из owasp :<blockquote> <strong>если заголовок origin отсутствует</strong>, убедитесь, что имя хоста в заголовке referer соответствует происхождению сайта. проверка реферера является широко используемым методом предотвращения csrf на встроенных сетевых устройствах, поскольку он не требует состояния для каждого пользователя. этот метод ослабления csrf также обычно используется с запросами без аутентификации [...] </blockquote>проверить http_referer также довольно просто в php с помощью $\_server['http\_referer']</code>, вы можете просто обновить вышеуказанный код с его помощью.</p><hr><p><strong>будьте осторожны</strong> с проверкой, которая всегда должна быть действительно конкретной: не проверяйте только <em>example.com</em> или <em>api.example.com</em>, но полный <strong> <a href="https://example.com">https: // example.com</a> </strong>. зачем ? потому что вы можете подделать эту проверку с помощью origin, например <em>api.example.com.hacker.com</em>.</p><hr><p><strong>2. генерация токенов csrf</strong></p><p>хорошо объясненный <a href="https://stackoverflow.com/a/31683058/2736233">там был дан ответ, специфичный для php</a> , короче говоря:</p><ol> <li><p>создайте токен:</p> <pre><code>session\_start(); if (empty($_session['csrf_token'])) { $\_session['csrf\_token'] = bin2hex(random\_bytes(32)); } </code></pre></li> <li><p>добавьте его в ваши сгенерированные представления с помощью мета (например, github):</p> <pre><code><meta name="csrf-token" content="<?= $_session['csrf_token'] ?>">  установите вызовы jquery ajax для включения этого токена: $.ajaxsetup({ headers : { 'csrftoken': $('meta[name="csrf-token"]').attr('content') } });  на стороне сервера проверьте ваши ajax запросы: session_start(); if (empty($\_session['csrf\_token'])) { $_session['csrf_token'] = bin2hex(random_bytes(32)); } header('content-type: application/json'); $headers = apache\_request\_headers(); if (isset($headers['csrftoken'])) { if ($headers['csrftoken'] !== $\_session['csrf\_token']) { exit(json\_encode(['error' => 'wrong csrf token.'])); } } else { exit(json\_encode(['error' => 'no csrf token.'])); } </code></pre></li> </ol><p>большинство php фреймворков имеют собственную реализацию csrf, которая более или менее основана на том же принципе.</p><hr><p><strong>3. <del>sanitize</del> подтвердить ввод пользователя.</strong></p><p>вы всегда должны <a href="https://stackoverflow.com/a/130323/2736233"><del>фильтр</del> входные данные пробела</a> и <a href="https://security.stackexchange.com/a/42521">проверить их</a> .</p><hr><p><strong>4. защитите свой сервер</strong></p><ul> <li> <a href="https://calomel.org/web\_server\_abuse\_detection.html">ограничьте количество ваших запросов</a> .</li> <li> <a href="https://developers.google.com/web/fundamentals/security/encrypt-in-transit/why-https?hl=en">используйте https как можно больше</a> .</li> <li> <a href="https://perishablepress.com/block-bad-queries/#bbq-php-script">блокировать некорректные запросы</a> .</li> <li> <a href="https://perishablepress.com/protect-post-requests/">защита post запросов</a> .</li> </ul><hr><p><strong>5. никогда не доверяйте пользовательскому вводу</strong></p><p>как сказал @ blue112, это один из самых элементарных <a href="https://www.owasp.org/index.php/category:principle">принципов безопасности</a> .</p><p> <a href="https://i.stack.imgur.com/fq4an.jpg"><img src="https://i.stack.imgur.com/fq4an.jpg" alt="enter image description here"> </a> </p>

<p>лучший способ по-прежнему заключается в обеспечении безопасности на стороне сервера, и если бы я был вошедшим в систему пользователем на сайте, я бы также смог проверить токен csrf в моем метатеге и создать сценарий на сервере. так что верная ставка - это проверка на стороне сервера</p>