通过用户身份验证防止中间人攻击 (Node/Vue/Passport)
Preventing man-in-the-middle attacks with user authentication (Node/Vue/Passport)
我目前有一个正在使用 Passport 处理身份验证的 Node/Vuejs 编写的 Web 应用程序,但我 运行 遇到了问题。我正在考虑当前如何设置身份验证,然后我意识到我有一个明显的安全漏洞。
简而言之,我的 Vuex 商店访问了本地 API 端点 /api/me
。该端点执行 req.user
的简单 return。为了简洁起见,典型的响应如下所示:
{
username: 'Bob',
roles: [] // normal user has no roles,
email: 'someguy@bob.com'
}
我的管理路由 /admin
有一个 beforeEnter 检查,如下所示,它使用 Vuex 存储合并了这个检查,所以我可以在前端访问用户数据的缓存版本。
{
path: '/admin',
name: '/admin',
component: Admin,
beforeEnter: (to, from, next) => {
store.dispatch('getMe').then(() => {
if (store.getters.user.roles && store.getters.user.roles.includes('administrator')) {
next();
return;
}
next({ path: '/' });
});
}
}
事情是这样的 - 我意识到有人可以轻松地玩弄系统。事实上,我自己用一个测试的非管理员帐户进行了尝试,我能够通过 return 从为此目的在 Postman 中设置的本地服务器输入以下内容来进入:
{
username: 'Super Admin Joe',
roles: ['administrator'] // normal user has no roles,
email: 'admin@bob.com'
}
还有中提琴!用户现在可以完全访问管理页面。
我的问题是,我该如何防止这种情况发生?
我需要检查用户是否在每个页面上都经过身份验证,但潜在的攻击者可以很容易地代理任何请求(在本例中是 /api/me
),让自己成为他们想要的任何用户。他们可以使用自己的帐户正常登录,打开“网络”选项卡并复制响应有效负载,然后根据需要更改用户数据。我相信在检查用户的登录状态时,前端和后端之间需要某种加密。
我试着考虑如何防止这种情况发生,但我这边的任何东西(至少是服务器端)似乎都没用,因为任何请求都可以很容易地重定向到攻击者的本地机器。
关于如何 "sign" 我的请求以确保它们没有被代理的任何建议?提前致谢!
您不必签署 api 请求的响应 body。进行身份验证的典型方法是建立一个签名的 session cookie,作为外部数据库中 session 信息的标识符,或包含 session 信息本身。此 cookie 应该在您的回复的 header 中,passport 应该给您一种管理此 cookie 的方法,您甚至都没有意识到。
这样一来,用户就无法以易于检测的方式篡改从服务器发送的信息,并且由于它是一个 cookie,您的浏览器会在每次请求时自动发送它(尽管如果您使用某些 AJAX 库,您可能必须明确指定您想要发送 cookie)。 MadEard 在评论中指的是可以使用 passprt 访问 cookie 信息的地方,passprt 是“req”object.
中的“user”属性
阅读你的 github 个文件后:
server.get("/admin", function(req, res){
if(req.user && req.user.roles.includes("administrator")){
//user is an administrator, render the admin panel view
}else{
//is not an admin, redirect or send error message
}
});
在每个 Express 路由中,在使用 Passport 进行身份验证后,您都有 req.user
对象。
通过检查请求cookieconnect.sid
,并检查该cookie在服务器上属于哪个会话来建立。
因此,您可以相信在任何 Express 路由中,对象 req.user
包含与该 cookie 相关的信息,您可以根据它采取行动。
一点注意事项:随着时间的推移,进行服务器端验证应该成为你的本能反应。
客户端是用来显示信息的。如果,在任何时候,你让客户做出任何可能成为安全责任的决定,请退后一步,重新考虑一下。
我目前有一个正在使用 Passport 处理身份验证的 Node/Vuejs 编写的 Web 应用程序,但我 运行 遇到了问题。我正在考虑当前如何设置身份验证,然后我意识到我有一个明显的安全漏洞。
简而言之,我的 Vuex 商店访问了本地 API 端点 /api/me
。该端点执行 req.user
的简单 return。为了简洁起见,典型的响应如下所示:
{
username: 'Bob',
roles: [] // normal user has no roles,
email: 'someguy@bob.com'
}
我的管理路由 /admin
有一个 beforeEnter 检查,如下所示,它使用 Vuex 存储合并了这个检查,所以我可以在前端访问用户数据的缓存版本。
{
path: '/admin',
name: '/admin',
component: Admin,
beforeEnter: (to, from, next) => {
store.dispatch('getMe').then(() => {
if (store.getters.user.roles && store.getters.user.roles.includes('administrator')) {
next();
return;
}
next({ path: '/' });
});
}
}
事情是这样的 - 我意识到有人可以轻松地玩弄系统。事实上,我自己用一个测试的非管理员帐户进行了尝试,我能够通过 return 从为此目的在 Postman 中设置的本地服务器输入以下内容来进入:
{
username: 'Super Admin Joe',
roles: ['administrator'] // normal user has no roles,
email: 'admin@bob.com'
}
还有中提琴!用户现在可以完全访问管理页面。
我的问题是,我该如何防止这种情况发生?
我需要检查用户是否在每个页面上都经过身份验证,但潜在的攻击者可以很容易地代理任何请求(在本例中是 /api/me
),让自己成为他们想要的任何用户。他们可以使用自己的帐户正常登录,打开“网络”选项卡并复制响应有效负载,然后根据需要更改用户数据。我相信在检查用户的登录状态时,前端和后端之间需要某种加密。
我试着考虑如何防止这种情况发生,但我这边的任何东西(至少是服务器端)似乎都没用,因为任何请求都可以很容易地重定向到攻击者的本地机器。
关于如何 "sign" 我的请求以确保它们没有被代理的任何建议?提前致谢!
您不必签署 api 请求的响应 body。进行身份验证的典型方法是建立一个签名的 session cookie,作为外部数据库中 session 信息的标识符,或包含 session 信息本身。此 cookie 应该在您的回复的 header 中,passport 应该给您一种管理此 cookie 的方法,您甚至都没有意识到。
这样一来,用户就无法以易于检测的方式篡改从服务器发送的信息,并且由于它是一个 cookie,您的浏览器会在每次请求时自动发送它(尽管如果您使用某些 AJAX 库,您可能必须明确指定您想要发送 cookie)。 MadEard 在评论中指的是可以使用 passprt 访问 cookie 信息的地方,passprt 是“req”object.
中的“user”属性阅读你的 github 个文件后:
server.get("/admin", function(req, res){
if(req.user && req.user.roles.includes("administrator")){
//user is an administrator, render the admin panel view
}else{
//is not an admin, redirect or send error message
}
});
在每个 Express 路由中,在使用 Passport 进行身份验证后,您都有 req.user
对象。
通过检查请求cookieconnect.sid
,并检查该cookie在服务器上属于哪个会话来建立。
因此,您可以相信在任何 Express 路由中,对象 req.user
包含与该 cookie 相关的信息,您可以根据它采取行动。
一点注意事项:随着时间的推移,进行服务器端验证应该成为你的本能反应。
客户端是用来显示信息的。如果,在任何时候,你让客户做出任何可能成为安全责任的决定,请退后一步,重新考虑一下。