そのため、しばらくの間、さまざまなAJAXを使用して、MySQLデータベース内で処理および保存されるデータをサーバーに送信する方法を試してきました。
AJAXリクエストがapi.php
にヒットする]ページは、PHPのPDO準備済みステートメントを使用してデータを保存するため、MySQLインジェクションは実際には問題ではなく、パスワードまたはデータは暗号化もapi.php
によって処理されますが、これは私がここで尋ねているものではありません。私の質問は、クライアントからサーバーに転送されるときにデータを安全にする方法に関するものです。
私は現在持っています(以下に含まれるログイン例のために):
login.php
とapi.php
の両方で使用されています)。api.php
のレート制限。api.php
内のデータベースと対話するときにステートメントを準備しました。api.php
内の機密データを暗号化します(質問には関係ありません)。最後に、私の質問は次のとおりです。
サイトのデータを処理し、そのデータを転送するには、誰もが異なるアプローチを持っていることを理解しています。また、あなたが何をしようとも、100%保護されることはありえないことを理解しています。システムに対処できない脆弱性や方法があるかもしれないからです。これは単なる例であるため、以下の特定のコードに対する批判ではなく、データを安全に送信するための一般的なアプローチに関するフィードバック/改善を探しています。しかし、建設的な答えは大歓迎です。読んで/答えてくれてありがとう。
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"
});
}
1。 Originヘッダーを確認します
OWASPで指定 のように、これでは十分ではありませんが推奨されます:
自分のブラウザからヘッダーをスプーフィングすることは簡単ですが、一般的に、XSS脆弱性を介さない限り、CSRF攻撃でそれを行うことは不可能です。だからこそ、ヘッダーをチェックすることはCSRF防御の妥当な最初のステップですが、ヘッダーが常に存在するとは限らないので、通常、それ自体では十分な防御とは見なされません。
そして Mozillaによる :
Originヘッダーは、JSONデータの盗難やCSRF攻撃に対して役立つと考えられています。 Originが提供する情報-ちょっとしたコンテキストのリクエスト作成情報-はリクエストの信頼性についてウェブサーバーにヒントを提供する必要があります[...]
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']));
}
1。 (bis)REFERERヘッダーを確認します
もう一度 OWASPから :
Originヘッダーが存在しない場合、Refererヘッダーのホスト名がサイトのOriginと一致することを確認します。リファラーの確認は、ユーザーごとの状態を必要としないため、組み込みネットワークデバイスでCSRFを防止する一般的に使用される方法です。このCSRF軽減方法は、認証されていない要求でも一般的に使用されます
HTTP_REFERER
もPHP with $_SERVER['HTTP_REFERER']
、上記のコードを更新できます。
BE CAREFUL常に具体的に確認する必要があるチェック:example.comまたはapi.example.comただし、完全なhttps://example.com。どうして ? api.example.com.hacker.comのようなOriginを使用してこのチェックを偽装する可能性があるためです。
2。 CSRFトークンの生成
十分に説明された PHPが与えられている)に固有の答え 、要するに:
トークンを生成します。
session_start();
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
メタ(Githubなど)を介して生成されたビューに追加します。
<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.']));
}
ほとんどのPHPフレームワークには独自のCSRF実装があり、これは多かれ少なかれ同じ原則に基づいています。
3。 消毒する ユーザー入力を検証します。
あなたはいつも フィルタ espace入力 および それらを検証 。
4。サーバーを保護する
5。ユーザー入力を信頼しない
@ blue112が言ったように、それは最も基本的なものの1つです セキュリティ原則 。
簡単な答え:クライアント側を保護することはできません。
長い答え:
クライアント側で実行されるのは実際にあなたのJavaScriptコードであることをブラウザに証明させるために何もすることはできません。次に、実行する明らかなアクションは最も単純なアクションです。NEVER TRUST USER INPUT。
これは、あなたが始めたときに、セッション、レート制限、データ検証、fail2ban(一定数の失敗後にクライアントIPを禁止する)、ログ監視を使用してサーバー側を保護することを意味します...
最善の方法は、サーバー側のセキュリティ保護を行うことです。サイトにログインしているユーザーであれば、メタタグのcsrfトークンを確認して、サーバーにスクリプトを偽造することもできます。確実な賭けはサーバー側の検証です