mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-28 05:46:36 +08:00
fix: 修复源站错误页「仅针对 GET 请求」导致配置发布失败并回滚
This commit is contained in:
+1
-1
@@ -110,7 +110,7 @@ services:
|
||||
- ./data/agent/:/data
|
||||
environment:
|
||||
OPENFLARE_SERVER_URL: "http://host.docker.internal:3000"
|
||||
OPENFLARE_AGENT_TOKEN: "af2fb112f36a0055ec25dd164c908fea"
|
||||
OPENFLARE_AGENT_TOKEN: "7c7c4c13df0f3a77866bcd8cde492610"
|
||||
LOG_LEVEL: "debug"
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
|
||||
@@ -28,6 +28,7 @@ sidebar: false
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复源站错误页「仅针对 GET 请求」导致配置发布失败并回滚:`proxy_intercept_errors` 不能写在 `limit_except` 内,现改为内部错误页按请求方法处理,非 GET 请求保留原始状态码且不注入自定义错误页,配置可通过 `openresty -t` 校验。
|
||||
- 修复 PoW 挑战页潜在 XSS:错误提示与状态文案改用纯文本渲染,挑战通过后的 `redir` 跳转参数仅允许 http/https 协议,防止异常文本被当作 HTML 执行或跳转到危险协议。
|
||||
- 修复邮件发送的邮件头注入风险:标题、发件人、收件人在写入邮件头前清除 CR/LF 换行符,防止注入额外邮件头(CWE-93)。
|
||||
- 修复 UptimeKuma 同步调试日志泄露凭据:输出日志前对 password/token/secret 等敏感字段打码,避免凭据进入日志。
|
||||
|
||||
@@ -266,7 +266,7 @@ Server 的所有核心基础配置定义在 `config.yaml` 中,且均支持环
|
||||
| 配置键 (Key) | 数据类型 | 作用说明 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| `origin_error_page_enabled` | `bool` | 是否启用全局源站错误页。开启后,源站或网关返回的匹配状态码由自定义/默认 HTML 替换,**HTTP 状态码保持原值**;关闭后不生成相关指令,恢复透传。修改后需发布配置版本生效 | `true` |
|
||||
| `origin_error_page_get_only` | `bool` | 是否仅对 **GET** 请求生效。开启后仅 GET 的匹配错误状态码返回自定义错误页;POST/PUT 等其它方法透传源站响应 | `false` |
|
||||
| `origin_error_page_get_only` | `bool` | 是否仅对 **GET** 请求生效。开启后仅 GET 的匹配错误状态码返回自定义错误页;POST/PUT 等其它方法不返回自定义错误页(保留原始错误状态码) | `false` |
|
||||
| `origin_error_page_status_codes` | `json` | 触发错误页的状态码标签 JSON 数组。支持单码(如 `522`)与闭区间(如 `500-599`);单码与区间两端均须在 **400–599**,且 `lo ≤ hi`。启用时展开结果不能为空 | `["500-599"]` |
|
||||
| `origin_error_page_html` | `string` | 错误页自定义 HTML。空字符串表示使用内置 OpenFlare 默认模板(极简白底);支持占位符 `{{status}}`(与 HTTP 状态码一致)、`{{host}}`(请求 Host)。最大 **256 KiB**(按字节)。勿嵌入不可信第三方脚本 | 空 |
|
||||
|
||||
|
||||
@@ -130,17 +130,11 @@ func renderOriginErrorPageIntercept(cfg ConfigSnapshot) string {
|
||||
if _, err := ExpandStatusCodeTags(effectiveOriginErrorPageStatusTags(cfg)); err != nil {
|
||||
return ""
|
||||
}
|
||||
// Always enable intercept for GET (and all methods when get_only is false).
|
||||
// limit_except GET applies to non-GET methods: turn intercept off so origin
|
||||
// error bodies (e.g. JSON 5xx) pass through unchanged.
|
||||
var builder strings.Builder
|
||||
builder.WriteString(" proxy_intercept_errors on;\n")
|
||||
if cfg.OriginErrorPageGetOnly {
|
||||
builder.WriteString(" limit_except GET {\n")
|
||||
builder.WriteString(" proxy_intercept_errors off;\n")
|
||||
builder.WriteString(" }\n")
|
||||
}
|
||||
return builder.String()
|
||||
// Intercept at the proxy level for all methods. nginx does not allow
|
||||
// proxy_intercept_errors inside limit_except (only allow/deny are valid
|
||||
// there), so GET-only is enforced in the internal error location's Lua:
|
||||
// non-GET requests exit with the original status and no custom HTML.
|
||||
return " proxy_intercept_errors on;\n"
|
||||
}
|
||||
|
||||
// renderOriginErrorPageServerBits emits server-level error_page + internal location.
|
||||
|
||||
@@ -88,11 +88,14 @@ func TestRenderOriginErrorPageGetOnly(t *testing.T) {
|
||||
if !strings.Contains(out, "proxy_intercept_errors on") {
|
||||
t.Fatal("missing intercept on")
|
||||
}
|
||||
if !strings.Contains(out, "limit_except GET") {
|
||||
t.Fatal("get_only must emit limit_except GET")
|
||||
// nginx rejects proxy_intercept_errors inside limit_except (only allow/deny
|
||||
// are valid there), which made the generated config fail `openresty -t` and
|
||||
// caused apply rollback. GET-only must rely on the internal location's Lua.
|
||||
if strings.Contains(out, "limit_except") {
|
||||
t.Fatal("get_only must not emit limit_except (proxy_intercept_errors is not allowed there)")
|
||||
}
|
||||
if !strings.Contains(out, "proxy_intercept_errors off") {
|
||||
t.Fatal("get_only must turn intercept off for non-GET")
|
||||
if strings.Contains(out, "proxy_intercept_errors off") {
|
||||
t.Fatal("get_only must not emit proxy_intercept_errors off")
|
||||
}
|
||||
if !strings.Contains(out, `get_only = true`) {
|
||||
t.Fatal("internal location must set get_only = true")
|
||||
|
||||
Reference in New Issue
Block a user