应配置安全响应头防御点击劫持和xss:启用frame-ancestors限制嵌入,收紧csp策略移除unsafe-inline/eval,关闭匿名访问、html变量渲染及swagger文档,并辅以运行时js校验。

要防护 Grafana 生产环境免受点击劫持(Clickjacking)和跨站脚本(XSS)攻击,核心是正确配置安全响应头(Security Headers),并配合服务端与前端策略协同防御。单纯依赖前端逻辑或单点设置容易失效,必须从 HTTP 层面强制约束浏览器行为。
启用并配置 X-Frame-Options 或 frame-ancestors
这是防御点击劫持最直接有效的手段。Grafana 默认禁用 iframe 嵌入,但需确认配置已生效且未被覆盖:
- 编辑 grafana.ini,在 [server] 区块中显式设置:
推荐使用 Content-Security-Policy 的 frame-ancestors 指令(优先级高于 X-Frame-Options):
-
[security]content_security_policy = "frame-ancestors 'self';" - 若需允许特定域名嵌入(如内部运维平台),可写为:
content_security_policy = "frame-ancestors 'self' https://ops.yourcompany.com;" - 避免使用
frame-ancestors *或完全关闭该策略 - 删除或注释掉旧式
x_frame_options = SAMEORIGIN(除非明确需要兼容极老浏览器)
强化 Content-Security-Policy 防御 XSS
Grafana 自带的 CSP 策略较宽松,生产环境必须收紧。重点限制脚本、样式、内联资源来源:
- 在 grafana.ini 的 [security] 区块中完整定义 CSP:
content_security_policy = "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self' ws: wss:; frame-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self';"
- 生产环境中应移除
'unsafe-inline'和'unsafe-eval'—— 这要求你将所有内联 JS/CSS 提取为外部文件,并对 Grafana 插件做兼容性验证 - 若使用自定义面板或前端扩展,需按实际域名白名单追加,例如:
script-src 'self' https://cdn.jsdelivr.net; - 启用 report-uri 或 report-to 收集违规事件,便于持续优化策略
禁用危险功能与默认暴露面
很多 XSS 和点击劫持利用的是 Grafana 默认开启但非必需的功能:
- 关闭匿名访问(除非业务强需求):
[auth.anonymous]enabled = false - 禁用模板变量中的 HTML 渲染(防止用户输入注入):
在仪表板 JSON 中设"sanitize_html": true;或全局限制变量类型为字符串/数字,避免使用regex或custom类型的高风险变量 - 禁用 Grafana 的公开 API 文档(Swagger UI):
[api]enable_swagger = false - 确保
[server].router_logging = false,避免日志泄露请求路径与参数
补充运行时防护(防御纵深)
响应头是第一道防线,但可叠加轻量级运行时校验增强鲁棒性:
- 在 Grafana 启动前注入简单 JS 片段(通过自定义 index.html 或插件方式):
if (window.top !== window.self) { document.documentElement.style.display = 'none'; }
- 该逻辑不替代 CSP,仅作为 fallback:当 header 被意外绕过或旧浏览器不支持时提供基础保护
- 不要依赖
window.top.location = ...跳转,可能被同源 iframe 拦截或触发循环 - 敏感操作页面(如告警管理、数据源编辑)可额外增加二次确认弹窗,降低误操作风险











