Sapper:基于用户权限呈现敏感数据是否安全?
Sapper: is it safe to render sensitive data, based on user rights?
我想为管理员呈现 500 错误的回溯来自服务器,所以:
- 在
server.js
中,会话由从 http_only cookie 中检索到的用户填充,就像 {'username': 'admin'}
polka()
.use(
sapper.middleware({
session: (req, res) => {
return { 'user': parseCookie('user') }
}
})
)
.listen(PORT);
- 在某些
index.js
中有一个全局变量来存储来自服务器的 500 错误的可能回溯:
import { writable } from 'svelte/store';
export const error = writable();
- 在
index.html
文章被预加载,如果当前用户是 admin,则在 500 错误的情况下会在下面呈现回溯:
<script context="module">
import { error } from 'index.js';
export async function preload(page, session) {
return { article : await this.fetch('/api/article/').then(response => {
if (response.status == 500 && session.user.username === 'admin') {
error.set(response);
}
return response.json();
})}
}
</script>
<script>
export let article
</script>
<h1>{ article.title }</h1>
<div>{ article.text }</div>
<!-- 500 ERROR TRACEBACK --->
{#if $error}
{@html $error}
{/if}
那么,如果通过 preload
函数设置 $error
,它是否安全并且仅在服务器端呈现?
如果不是,如何改进?
也许 if (process.browser)
能以某种方式提供帮助?
谢谢
更新
查看 Rich Harris 的以下回答
原创
如果您将其中一个模板与 webpack 或 rollup 一起使用,您会看到 process.browser
被替换为 true
,这意味着无法访问的代码将被摇树。
简短的回答是肯定的,只要在适当的地方用 process.browser
围绕该代码就可以使用它
但是话虽如此,当涉及到 500 错误代码时,您最好还是依赖服务器日志。仅向所有用户返回错误代码,仅此而已,并将堆栈跟踪推送到日志系统以进行调试。
避免使用这样的商店。
想象一下 response.json()
需要几毫秒才能解决,而在那段时间内发生新请求 也 错误。第一个用户是普通用户,第二个用户是管理员。由于 error
存储对于连接到该服务器的所有用户都是通用的,因此第一个用户会看到该场景中针对管理员用户的错误。
相反,只需公开 error
作为道具:
<script context="module">
export async function preload(page, session) {
const response = await this.fetch('/api/article/');
return {
article: await response.json(),
error: response.status === 500 && session.user.username === 'admin'
? response
: null
};
}
</script>
<script>
export let article;
export let error;
</script>
<h1>{ article.title }</h1>
<div>{ article.text }</div>
<!-- 500 ERROR TRACEBACK --->
{#if error}
{@html error}
{/if}
(更严格地说,最好避免以这种方式使用 session
对象,因为足够专注的人可以找到访问该对象并改变它的方法——服务器应该负责确定向用户而不是客户端显示哪些信息。虽然在这种情况下这并不重要,因为您只是显示可通过网络选项卡轻松访问的信息。)
我想为管理员呈现 500 错误的回溯来自服务器,所以:
- 在
server.js
中,会话由从 http_only cookie 中检索到的用户填充,就像{'username': 'admin'}
polka()
.use(
sapper.middleware({
session: (req, res) => {
return { 'user': parseCookie('user') }
}
})
)
.listen(PORT);
- 在某些
index.js
中有一个全局变量来存储来自服务器的 500 错误的可能回溯:
import { writable } from 'svelte/store';
export const error = writable();
- 在
index.html
文章被预加载,如果当前用户是 admin,则在 500 错误的情况下会在下面呈现回溯:
<script context="module">
import { error } from 'index.js';
export async function preload(page, session) {
return { article : await this.fetch('/api/article/').then(response => {
if (response.status == 500 && session.user.username === 'admin') {
error.set(response);
}
return response.json();
})}
}
</script>
<script>
export let article
</script>
<h1>{ article.title }</h1>
<div>{ article.text }</div>
<!-- 500 ERROR TRACEBACK --->
{#if $error}
{@html $error}
{/if}
那么,如果通过 preload
函数设置 $error
,它是否安全并且仅在服务器端呈现?
如果不是,如何改进?
也许 if (process.browser)
能以某种方式提供帮助?
谢谢
更新
查看 Rich Harris 的以下回答
原创
如果您将其中一个模板与 webpack 或 rollup 一起使用,您会看到 process.browser
被替换为 true
,这意味着无法访问的代码将被摇树。
简短的回答是肯定的,只要在适当的地方用 process.browser
围绕该代码就可以使用它
但是话虽如此,当涉及到 500 错误代码时,您最好还是依赖服务器日志。仅向所有用户返回错误代码,仅此而已,并将堆栈跟踪推送到日志系统以进行调试。
避免使用这样的商店。
想象一下 response.json()
需要几毫秒才能解决,而在那段时间内发生新请求 也 错误。第一个用户是普通用户,第二个用户是管理员。由于 error
存储对于连接到该服务器的所有用户都是通用的,因此第一个用户会看到该场景中针对管理员用户的错误。
相反,只需公开 error
作为道具:
<script context="module">
export async function preload(page, session) {
const response = await this.fetch('/api/article/');
return {
article: await response.json(),
error: response.status === 500 && session.user.username === 'admin'
? response
: null
};
}
</script>
<script>
export let article;
export let error;
</script>
<h1>{ article.title }</h1>
<div>{ article.text }</div>
<!-- 500 ERROR TRACEBACK --->
{#if error}
{@html error}
{/if}
(更严格地说,最好避免以这种方式使用 session
对象,因为足够专注的人可以找到访问该对象并改变它的方法——服务器应该负责确定向用户而不是客户端显示哪些信息。虽然在这种情况下这并不重要,因为您只是显示可通过网络选项卡轻松访问的信息。)