Files
wonder 70e368e235
Deploy Examination / deploy (push) Successful in 7s
feat: add cybersecurity topic with 6 subtopics (204 questions)
New topic group: 网络安全专题 (cybersecurity)
Subtopics:
- web-security: Web 安全基础 (34 questions)
- crypto-basics: 密码学基础 (34 questions)
- buffer-overflow: 缓冲区溢出与漏洞利用 (34 questions)
- os-security: 操作系统安全 (34 questions)
- network-attack: 网络攻防 (34 questions)
- secure-coding: 安全编程实践 (34 questions)

Question types per subtopic:
- single_choice × 20
- true_false × 10
- short_answer × 3
- code_reading × 1

Difficulty range: 1-3 (基础)
2026-09-17 13:33:04 +08:00

83 lines
9.1 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"topic": "secure-coding",
"type": "short_answer",
"schema_version": "1.0.0",
"generated": "2026-09-17T00:00:00+08:00",
"questions": [
{
"id": "sa-001",
"type": "short_answer",
"difficulty": 1,
"tags": [
"安全编程",
"输入校验"
],
"question": "简述Web应用中输入校验的「双重校验」原则(客户端+服务端),以及各自的作用和局限性。",
"answer": "双重校验原则要求在客户端和服务端都对用户输入进行校验,两者缺一不可。\n\n1. 客户端校验:在浏览器/前端通过JavaScript等脚本对用户输入进行即时检查(如格式、长度、范围)。其作用是提升用户体验,减少无效请求,提供即时反馈。局限性在于客户端代码完全受用户控制,攻击者可以绕过(禁用JS、篡改请求、使用代理工具直接发送恶意请求),因此不能作为安全保障。\n\n2. 服务端校验:在后端对所有接收到的输入进行严格校验,是安全的最后一道防线。其作用是防止恶意数据进入系统,防御SQL注入、XSS、命令注入等攻击。局限性在于反馈延迟、增加服务端负担,且校验规则需要与业务逻辑紧密配合。\n\n核心原则:永远不要信任来自客户端的任何数据。客户端校验是便利性措施,服务端校验是安全性措施。",
"keywords": [
"客户端校验",
"服务端校验",
"输入验证",
"不可信输入",
"XSS",
"SQL注入",
"白名单"
],
"scoring_rubric": "满分标准:(1) 说明双重校验的概念,即客户端和服务端都需要校验(2分);(2) 正确描述客户端校验的作用:提升用户体验、即时反馈(2分);(3) 正确描述客户端校验的局限性:可被绕过、不可信赖(2分);(4) 正确描述服务端校验的作用:安全最后防线、防御注入攻击(2分);(5) 提出核心原则——不信任客户端数据(2分)。",
"explanation": "输入校验是Web安全的基础。OWASP Top 10中多次将注入类漏洞列为第一大安全风险。双重校验体现了纵深防御思想:客户端校验解决易用性问题,服务端校验解决安全性问题。很多初级开发者误以为客户端校验就够了,导致直接通过API发送未经校验的恶意数据,引发SQL注入、存储型XSS等严重漏洞。理解这一原则是安全编程的入门基础。",
"source": null,
"related": []
},
{
"id": "sa-002",
"type": "short_answer",
"difficulty": 2,
"tags": [
"安全编程",
"整数溢出"
],
"question": "解释整数溢出的原理,并给出至少两种防御方法。",
"answer": "整数溢出原理:计算机中整数以固定位数的二进制存储(如32位有符号整数范围为 -2^31 ~ 2^31-1)。当算术运算的结果超出该数据类型能表示的范围时,高位被截断,导致结果「回绕」(wrap around)。例如,32位无符号整数 0xFFFFFFFF + 1 = 0x00000000(回绕为0)。有符号整数溢出还可能导致正数变负数,这在C/C++中属于未定义行为(UB)。\n\n整数溢出在安全上的危害包括:(1) 缓冲区溢出——分配内存时计算出的大小因溢出变小,导致后续写入越界;(2) 绕过边界检查——索引或长度校验因溢出被绕过;(3) 逻辑错误——资金计算、权限判断等场景产生错误结果。\n\n防御方法(至少两种):\n1. 使用安全的整数运算库/内置函数:如 GCC 的 __builtin_add_overflow()、Clang 的 __builtin_*_overflow 系列函数,或 C23 标准的 <stdckdint.h> 中的 ckd_add/ckd_mul 等检查溢出宏。这些工具在发生溢出时返回溢出标志,程序可据此进行错误处理。\n\n2. 运算前进行边界检查(前置校验):在执行加减乘除之前,检查操作数是否会导致溢出。例如,乘法前检查 a > SIZE_MAX / b;加法前检查 a > MAX - b。若会溢出则拒绝操作。\n\n3. 使用更大位宽的数据类型:将计算临时提升到更大的类型(如用64位计算后再检查是否超出32位范围),但这只是权宜之计,不能根本解决问题。\n\n4. 使用支持安全算术的语言或编译选项:如 Rust 默认在 debug 模式下检测溢出,Java 的 Math.addExact() 会在溢出时抛出 ArithmeticException,或使用 -ftrapv 编译选项让C程序在有符号溢出时中止。",
"keywords": [
"整数溢出",
"回绕",
"缓冲区溢出",
"未定义行为",
"边界检查",
"安全算术",
"__builtin_add_overflow",
"前置校验"
],
"scoring_rubric": "满分标准:(1) 正确解释整数溢出原理——固定位数存储、结果超出范围导致回绕或截断(3分);(2) 说明溢出的安全危害,如缓冲区溢出、边界检查绕过等(2分);(3) 给出至少两种有效的防御方法并说明原理(各2分,共4分);(4) 表述准确,术语使用正确(1分)。若仅给出一种防御方法扣2分;若原理描述不完整扣1-2分。",
"explanation": "整数溢出是一种常见但容易被忽视的安全漏洞,尤其在C/C++等系统编程语言中。2014年OpenSSL的Heartbleed漏洞的根因之一就涉及整数溢出。在安全编程中,任何涉及内存分配大小、数组索引、循环计数的整数运算都必须考虑溢出可能。掌握溢出原理和防御方法是编写安全系统软件的基本功。",
"source": null,
"related": []
},
{
"id": "sa-003",
"type": "short_answer",
"difficulty": 2,
"tags": [
"安全编程",
"格式化字符串"
],
"question": "对比 sprintf/snprintf 和 printf/fprintf 在安全性上的差异,说明为什么格式化字符串漏洞是危险的。",
"answer": "函数分类与安全性差异:\n\n1. printf/fprintf 是输出到标准输出/文件流的格式化输出函数。它们的安全风险在于:如果格式字符串(format string)来自用户输入,攻击者可以在格式串中插入 %x(读取栈内容)、%n(向任意地址写入)、%s(读取指针指向的内容)等格式说明符,导致信息泄露或任意内存写入。\n\n2. sprintf/snprintf 是输出到缓冲区的格式化写入函数。除了与 printf 相同的格式化字符串漏洞外,sprintf 还有一个额外风险:没有长度限制,如果格式化后的字符串长度超过目标缓冲区大小,就会发生缓冲区溢出。snprintf 通过限制最大写入字节数(包括 NUL 终止符)来缓解这个问题,是 sprintf 的安全替代品。\n\n安全性对比:\n- sprintf vs snprintf:snprintf 通过 size 参数防止缓冲区溢出,应始终优先使用 snprintf 而非 sprintf。\n- printf 类 vs sprintf 类:printf 类将结果输出到标准流,不会直接造成缓冲区溢出;sprintf 类可能同时面临缓冲区溢出和格式化字符串漏洞的双重风险。\n\n格式化字符串漏洞为什么危险:\n1. 信息泄露:%x、%p 等可以读取栈上的敏感数据(密钥、地址、canary 值)。\n2. 任意地址写入:%n 可以将已输出的字符数写入任意内存地址,攻击者可以精确控制写入的值和地址,从而覆写函数返回地址、GOT 表项等,实现代码执行。\n3. 进程崩溃:%s 对栈上随机值的解引用大概率导致段错误,可造成拒绝服务。\n4. 组合利用:信息泄露 + 任意写入的组合使得这类漏洞几乎总能转化为完整的代码执行利用。\n\n防御方法:始终将格式字符串硬编码为字面量(如 printf(\"%s\", user_input) 而非 printf(user_input)),对 sprintf 使用 snprintf 并正确计算缓冲区大小。",
"keywords": [
"格式化字符串",
"sprintf",
"snprintf",
"printf",
"缓冲区溢出",
"%n",
"任意写入",
"信息泄露",
"GOT覆写"
],
"scoring_rubric": "满分标准:(1) 正确区分 printf/fprintf 和 sprintf/snprintf 的功能差异(2分);(2) 说明 snprintf 相比 sprintf 的安全优势——防止缓冲区溢出(2分);(3) 解释格式化字符串漏洞的原理——用户可控的格式串中的 %x、%n 等(2分);(4) 说明危害性:信息泄露、任意地址写入、可能实现代码执行(3分);(5) 提出正确的防御方法——硬编码格式字符串、使用 snprintf(1分)。若未说明 %n 的写入能力扣2分;若未区分 sprintf/snprintf 扣1分。",
"explanation": "格式化字符串漏洞是经典的C/C++安全问题,常见于将用户输入直接作为 printf 系列函数的第一个参数。虽然现代编译器(如 GCC 的 -Wformat-security)会对此发出警告,但该漏洞在遗留代码中仍然广泛存在。snprintf 是 sprintf 的安全替代,但 snprintf 本身不能防御格式化字符串攻击——它只防止缓冲区溢出。理解这些函数族的安全特性差异对于编写安全的C程序至关重要。",
"source": null,
"related": []
}
]
}