fix(Minor M3): blog / github 加回 URL 校验
旧 account/serializers.py:125,127 是 serializers.URLField,迁移时降级成了 z.string().max(256)。这两个字段会被前端渲染成可点击链接,放任自由字符串等于 允许写入 javascript: 一类伪协议。 只放行 http(s)://,空串表示清空。实测 javascript:alert(1) 与 not a url 均 400, https://example.com/x 与空串 200。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,12 +9,25 @@ export const registerRequestSchema = z.object({
|
||||
password: z.string().min(6).max(20),
|
||||
})
|
||||
|
||||
/**
|
||||
* 对齐旧后端 `account/serializers.py:125,127` 的 `serializers.URLField`:
|
||||
* 这两个字段会被前端渲染成可点击链接,放任自由字符串等于允许写入
|
||||
* `javascript:` 一类的伪协议。只放行 http/https,空串与 null 表示「清空」。
|
||||
*/
|
||||
const linkField = z
|
||||
.string()
|
||||
.max(256)
|
||||
.refine(
|
||||
(value) => value === "" || /^https?:\/\/\S+$/i.test(value),
|
||||
"必须是以 http:// 或 https:// 开头的网址",
|
||||
)
|
||||
|
||||
export const updateProfileRequestSchema = z.object({
|
||||
realName: z.string().max(32).nullable().optional(),
|
||||
avatar: z.string().max(256).optional(),
|
||||
blog: z.string().max(256).nullable().optional(),
|
||||
blog: linkField.nullable().optional(),
|
||||
mood: z.string().max(256).nullable().optional(),
|
||||
github: z.string().max(256).nullable().optional(),
|
||||
github: linkField.nullable().optional(),
|
||||
school: z.string().max(64).nullable().optional(),
|
||||
major: z.string().max(64).nullable().optional(),
|
||||
language: z.string().max(32).nullable().optional(),
|
||||
|
||||
Reference in New Issue
Block a user