CSRFトークンの追加
This commit is contained in:
@@ -18,10 +18,16 @@ class User {
|
|||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
$doLogin = count($_POST) > 0;
|
$doLogin = $_SERVER['REQUEST_METHOD'] === 'POST';
|
||||||
$error = '';
|
$error = '';
|
||||||
|
|
||||||
if ($doLogin) {
|
if ($doLogin) {
|
||||||
|
if (!\verify_csrf_token($_POST['csrf_token'])) {
|
||||||
|
header('Location: /');
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
unset($_POST['csrf_token']);
|
||||||
|
|
||||||
$a = [];
|
$a = [];
|
||||||
if (count($_POST) === 2) {
|
if (count($_POST) === 2) {
|
||||||
$i = 0;
|
$i = 0;
|
||||||
@@ -91,6 +97,12 @@ class User {
|
|||||||
$nyuE = '';
|
$nyuE = '';
|
||||||
|
|
||||||
if ($doRegister) {
|
if ($doRegister) {
|
||||||
|
if (!\verify_csrf_token($_POST['csrf_token'])) {
|
||||||
|
header('Location: /');
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
unset($_POST['csrf_token']);
|
||||||
|
|
||||||
$a = [];
|
$a = [];
|
||||||
if (count($_POST) === 4) {
|
if (count($_POST) === 4) {
|
||||||
$i = 0;
|
$i = 0;
|
||||||
|
|||||||
@@ -51,17 +51,6 @@ class Auth {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$userData = $this->purgeOldTokens($userData);
|
$userData = $this->purgeOldTokens($userData);
|
||||||
$expire = 0;
|
|
||||||
$tokenExist = false;
|
|
||||||
|
|
||||||
foreach ($userData->tokens as $t) {
|
|
||||||
if ($t->ip === $ip) {
|
|
||||||
$tokenExist = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$tokenExist) {
|
|
||||||
$token = bin2hex(random_bytes(64));
|
$token = bin2hex(random_bytes(64));
|
||||||
$expire = time() + $this->tokenDuration;
|
$expire = time() + $this->tokenDuration;
|
||||||
$newToken = [
|
$newToken = [
|
||||||
@@ -74,7 +63,6 @@ class Auth {
|
|||||||
];
|
];
|
||||||
|
|
||||||
$userData->tokens[] = $newToken;
|
$userData->tokens[] = $newToken;
|
||||||
}
|
|
||||||
|
|
||||||
$path = $this->dataDir.$this->id.'.'.$userData->username.'.json';
|
$path = $this->dataDir.$this->id.'.'.$userData->username.'.json';
|
||||||
$json = json_encode($userData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
$json = json_encode($userData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||||
@@ -83,21 +71,16 @@ class Auth {
|
|||||||
return \Result::error('エラー:ユーザーデータの保存に失敗。');
|
return \Result::error('エラー:ユーザーデータの保存に失敗。');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$tokenExist) {
|
|
||||||
$secure = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off');
|
|
||||||
$domain = $_SERVER['SERVER_NAME'];
|
|
||||||
|
|
||||||
if (!setcookie('kerozen', $token, [
|
if (!setcookie('kerozen', $token, [
|
||||||
'expires' => $expire,
|
'expires' => $expire,
|
||||||
'path' => '/',
|
'path' => '/',
|
||||||
'domain' => $domain,
|
'domain' => $_SERVER['SERVER_NAME'],
|
||||||
'secure' => $secure,
|
'secure' => (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'),
|
||||||
'httponly' => true,
|
'httponly' => true,
|
||||||
'samesite' => 'Strict'
|
'samesite' => 'Strict'
|
||||||
])) {
|
])) {
|
||||||
return \Result::error('エラー:クッキーを設定に失敗。');
|
return \Result::error('エラー:クッキーを設定に失敗。');
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return \Result::success('ログイン成功');
|
return \Result::success('ログイン成功');
|
||||||
}
|
}
|
||||||
@@ -111,8 +94,6 @@ class Auth {
|
|||||||
|
|
||||||
public function logout(?string $token = null): \Result {
|
public function logout(?string $token = null): \Result {
|
||||||
if (!AUTH_ENABLED) return \Result::Error('エラー:認証システムは無効です。');
|
if (!AUTH_ENABLED) return \Result::Error('エラー:認証システムは無効です。');
|
||||||
$secure = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off');
|
|
||||||
$domain = $_SERVER['SERVER_NAME'];
|
|
||||||
$userData = $this->getUserData();
|
$userData = $this->getUserData();
|
||||||
|
|
||||||
if (!$token) {
|
if (!$token) {
|
||||||
@@ -124,8 +105,8 @@ class Auth {
|
|||||||
setcookie('kerozen', null, [
|
setcookie('kerozen', null, [
|
||||||
'expires' => 0,
|
'expires' => 0,
|
||||||
'path' => '/',
|
'path' => '/',
|
||||||
'domain' => $domain,
|
'domain' => $_SERVER['SERVER_NAME'],
|
||||||
'secure' => $secure,
|
'secure' => (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'),
|
||||||
'httponly' => true,
|
'httponly' => true,
|
||||||
'samesite' => 'Strict'
|
'samesite' => 'Strict'
|
||||||
]);
|
]);
|
||||||
|
|||||||
18
util.php
18
util.php
@@ -160,6 +160,24 @@ if (AUTH_ENABLED) {
|
|||||||
|
|
||||||
return $color.$suffix;
|
return $color.$suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function make_csrf_token(?bool $force = false): string {
|
||||||
|
if (null !== getcookie('csrf_token') && !$force) return getcookie('csrf_token');
|
||||||
|
$token = bin2hex(random_bytes(32));
|
||||||
|
setcookie('csrf_token', $token, [
|
||||||
|
'expires' => time() + 300, // 5分
|
||||||
|
'path' => '/',
|
||||||
|
'domain' => $_SERVER['SERVER_NAME'],
|
||||||
|
'secure' => (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'),
|
||||||
|
'httponly' => true,
|
||||||
|
'samesite' => 'Strict'
|
||||||
|
]);
|
||||||
|
return $token;
|
||||||
|
}
|
||||||
|
|
||||||
|
function verify_csrf_token(string $token): bool {
|
||||||
|
return hash_equals(getcookie('csrf_token'), $token);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function count_special_chars(string $str): int {
|
function count_special_chars(string $str): int {
|
||||||
|
|||||||
@@ -28,7 +28,10 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td><button>サインイン</button></td>
|
<td>
|
||||||
|
<input type="hidden" id="csrf_token" name="csrf_token" value="{{ make_csrf_token() }}" />
|
||||||
|
<button>サインイン</button>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@@ -38,7 +38,10 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td><button>登録</button></td>
|
<td>
|
||||||
|
<input type="hidden" id="csrf_token" name="csrf_token" value="{{ make_csrf_token() }}" />
|
||||||
|
<button>登録</button>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
Reference in New Issue
Block a user