php 网站中防止重放攻击的好方法
a good approach to prevent replay attack in websites with php
我是网络开发的菜鸟。我正在设计一个 MVC 登录页面,为了防止重放攻击,每当用户请求登录页面时,我都会创建一个会话。我的代码如下:
public function login(){
if($_SERVER['REQUEST_METHOD'] == 'GET') {
session_start();
$_SESSION["requestToken"] = generateToken(3);
}else if ($_SERVER['REQUEST_METHOD'] == 'POST'){
session_start();
if (isset($_SESSION["requestToken"])){
if(successfulLogin()){
unset($_SESSION["requestToken"]);
session_destroy();
}
}else{
header("location:localhost:public/users/login");
}
}
我读过一篇文章,其中实施了类似的方法来防止重播攻击,但我引用它说,“这远非一个完整的解决方案。它有缺陷和悬而未决的问题”。 Here
你能帮我找出我的方法的问题并告诉我哪种方法最适合应用吗?
我来晚了,但我希望我的回答能帮助其他一些试图保护他们的网页/API免受重放攻击的人。我使用以下方法来保护我的 API 免受重放攻击
应用端
- 首次使用您的应用程序时,或者如果您的应用程序需要登录,则在服务器上为设备生成一个唯一的 device_id/token,然后您可以在登录时生成令牌
- 每当应用程序调用服务器时,它都会在 HTTP headers 中添加以下内容
- 令牌
- 128 个字符长的随机值 (Random1)
- 设备的当前 Unix 时间戳
- “令牌+|||+随机1+|||+时间戳”(随机2)的SHA256
服务器端
当 API 收到呼叫时,它会像这样验证 headers
检查令牌是否是数据库中存在的有效令牌(您可以
实施过期机制以使其更安全)
-
检查时间戳是否有效
生成“Token+|||+Random1+|||+Timestamp”的SHA256并进行比较
header.
的 Random2
检查您的数据库中是否不存在此 SHA256 结果
如果所有检查都通过,则根据此令牌将此 SHA256 结果保存在数据库中。
您可以通过添加更多随机数来提高安全性。在我的示例中,您可以看到我对 3 个管道进行了两次硬编码。您可以使管道数量随机。
示例服务器端PHP代码
//This function will perform all the steps to validate the request
//returns TRUE if all good else FALSE
function headers_valid(){
$headers=getallheaders();
if (!isset($headers["Token"])
|| !isset($headers["Random1"])
|| !isset($headers["Timestamp"]
|| !isset($headers["Random2"])
){
return FALSE;
}
$token=$headers["Token"];
$random1=$headers["Random1"];
$timestamp=$headers["Timestamp"];
$random2=$headers["Random2"];
if (!is_numeric($timestamp)){
return FALSE;
}
$ts=intval($timestamp);
$tsNow=time();
$diffTs=$tsNow-$ts;
if ($diffTs<0){
$diffTs*=-1;
}
//extra check to make sure that timestamp is not off
//by 1 or more minutes
if ($diffTs>=60){
return FALSE;
}
$hashInput=$token."|||".$random1."|||".$timestamp;
$calcHash=strtolower(hash("sha256",$hashInput));
if (strtolower($random2)!=$calcHash){
return FALSE;
}
//add your database code. following is a dummy database code
$row=resultof("SELECT hash FROM request_hash WHERE hash='".$calcHash."'");
//if row is returned by this query then return false
if (row_exists($row))
return FALSE;
//all good now you can store this hash in your database
execute_query("INSERT INTO request_hash(hash) VALUES('".$calcHash."')");
return TRUE;
}
我希望我的回答能帮助其他想要防范重放攻击的人
我是网络开发的菜鸟。我正在设计一个 MVC 登录页面,为了防止重放攻击,每当用户请求登录页面时,我都会创建一个会话。我的代码如下:
public function login(){
if($_SERVER['REQUEST_METHOD'] == 'GET') {
session_start();
$_SESSION["requestToken"] = generateToken(3);
}else if ($_SERVER['REQUEST_METHOD'] == 'POST'){
session_start();
if (isset($_SESSION["requestToken"])){
if(successfulLogin()){
unset($_SESSION["requestToken"]);
session_destroy();
}
}else{
header("location:localhost:public/users/login");
}
}
我读过一篇文章,其中实施了类似的方法来防止重播攻击,但我引用它说,“这远非一个完整的解决方案。它有缺陷和悬而未决的问题”。 Here
你能帮我找出我的方法的问题并告诉我哪种方法最适合应用吗?
我来晚了,但我希望我的回答能帮助其他一些试图保护他们的网页/API免受重放攻击的人。我使用以下方法来保护我的 API 免受重放攻击
应用端
- 首次使用您的应用程序时,或者如果您的应用程序需要登录,则在服务器上为设备生成一个唯一的 device_id/token,然后您可以在登录时生成令牌
- 每当应用程序调用服务器时,它都会在 HTTP headers 中添加以下内容
- 令牌
- 128 个字符长的随机值 (Random1)
- 设备的当前 Unix 时间戳
- “令牌+|||+随机1+|||+时间戳”(随机2)的SHA256
服务器端
当 API 收到呼叫时,它会像这样验证 headers
检查令牌是否是数据库中存在的有效令牌(您可以 实施过期机制以使其更安全) -
检查时间戳是否有效
生成“Token+|||+Random1+|||+Timestamp”的SHA256并进行比较 header.
的 Random2检查您的数据库中是否不存在此 SHA256 结果
如果所有检查都通过,则根据此令牌将此 SHA256 结果保存在数据库中。
您可以通过添加更多随机数来提高安全性。在我的示例中,您可以看到我对 3 个管道进行了两次硬编码。您可以使管道数量随机。
示例服务器端PHP代码
//This function will perform all the steps to validate the request
//returns TRUE if all good else FALSE
function headers_valid(){
$headers=getallheaders();
if (!isset($headers["Token"])
|| !isset($headers["Random1"])
|| !isset($headers["Timestamp"]
|| !isset($headers["Random2"])
){
return FALSE;
}
$token=$headers["Token"];
$random1=$headers["Random1"];
$timestamp=$headers["Timestamp"];
$random2=$headers["Random2"];
if (!is_numeric($timestamp)){
return FALSE;
}
$ts=intval($timestamp);
$tsNow=time();
$diffTs=$tsNow-$ts;
if ($diffTs<0){
$diffTs*=-1;
}
//extra check to make sure that timestamp is not off
//by 1 or more minutes
if ($diffTs>=60){
return FALSE;
}
$hashInput=$token."|||".$random1."|||".$timestamp;
$calcHash=strtolower(hash("sha256",$hashInput));
if (strtolower($random2)!=$calcHash){
return FALSE;
}
//add your database code. following is a dummy database code
$row=resultof("SELECT hash FROM request_hash WHERE hash='".$calcHash."'");
//if row is returned by this query then return false
if (row_exists($row))
return FALSE;
//all good now you can store this hash in your database
execute_query("INSERT INTO request_hash(hash) VALUES('".$calcHash."')");
return TRUE;
}
我希望我的回答能帮助其他想要防范重放攻击的人