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

59 lines
4.5 KiB
JSON

{
"topic": "secure-coding",
"type": "code_reading",
"schema_version": "1.0.0",
"generated": "2026-09-17T00:00:00+08:00",
"questions": [
{
"id": "cr-001",
"type": "code_reading",
"difficulty": 2,
"tags": [
"安全编程",
"整数溢出",
"内存安全"
],
"question": "阅读以下C代码,回答问题。",
"code": "#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\nvoid process_input(const char *user_input) {\n unsigned int len = strlen(user_input);\n // 检查长度是否合理\n if (len > 1024) {\n printf(\"Input too long!\\n\");\n return;\n }\n // 分配缓冲区:len + 1 用于存放结尾的 '\\0'\n char *buffer = (char *)malloc(len + 1);\n if (buffer == NULL) {\n printf(\"Memory allocation failed!\\n\");\n return;\n }\n strcpy(buffer, user_input);\n printf(\"Processed: %s\\n\", buffer);\n free(buffer);\n}\n\nint main(int argc, char *argv[]) {\n if (argc < 2) {\n printf(\"Usage: %s <input>\\n\", argv[0]);\n return 1;\n }\n process_input(argv[1]);\n return 0;\n}",
"language": "c",
"sub_questions": [
{
"index": 1,
"type": "single_choice",
"question": "当 user_input 的 strlen 返回值恰好为 SIZE_MAX(即 (size_t)-1)时,len + 1 的结果是什么?",
"options": {
"A": "0,因为无符号整数溢出后回绕到 0",
"B": "SIZE_MAX + 1 = 一个更大的数",
"C": "程序会崩溃",
"D": "编译器会报错"
},
"answer": "A",
"explanation": "unsigned int 在 C 语言中发生溢出时会进行模 2^N 回绕(wrap around)。当 len 为 SIZE_MAX 时,len + 1 回绕为 0。此时 malloc(0) 的行为是实现定义的——可能返回 NULL 或一个可 free 的指针,但分配的大小为 0 字节。后续 strcpy 会写入远超分配空间的数据,导致堆缓冲区溢出。"
},
{
"index": 2,
"type": "single_choice",
"question": "这段代码在上述溢出场景下,strcpy(buffer, user_input) 会导致什么后果?",
"options": {
"A": "正常复制,程序正常运行",
"B": "堆缓冲区溢出(heap buffer overflow),可能执行任意代码",
"C": "栈溢出",
"D": "只会影响 buffer 变量,不会影响其他数据"
},
"answer": "B",
"explanation": "当 len + 1 回绕为 0 时,malloc(0) 可能分配一个极小的内存块(或返回一个有效指针但大小为 0),而 user_input 的实际长度远超分配空间。strcpy 会将整个 user_input 复制到这个过小的缓冲区中,造成堆缓冲区溢出,可能覆盖堆上的其他数据结构,攻击者可利用此漏洞执行任意代码。"
},
{
"index": 3,
"type": "short_answer",
"question": "请修改 process_input 函数,修复其中存在的所有安全问题(至少指出并修复 2 个问题)。",
"answer": "修复方案应包括:\n1. 将 strlen 返回值类型改为 size_t(而非 unsigned int),避免类型截截断;\n2. 在 len + 1 运算前检查 len 是否等于 SIZE_MAX(或使用安全的加法函数如 __builtin_add_overflow / SafeInt),防止整数溢出回绕;\n3. 使用 strncpy 或 memcpy 替代 strcpy,限制拷贝长度;\n4. 检查 malloc 返回值后,对 buffer 大小为 0 的情况进行防御;\n5. 考虑使用 calloc 或更安全的内存分配函数。\n\n示例修复代码:\nvoid process_input(const char *user_input) {\n size_t len = strlen(user_input);\n if (len > 1024) { printf(\"Input too long!\\n\"); return; }\n if (len == SIZE_MAX) { printf(\"Invalid input length!\\n\"); return; }\n char *buffer = (char *)malloc(len + 1);\n if (buffer == NULL || len + 1 == 0) { printf(\"Allocation failed!\\n\"); return; }\n memcpy(buffer, user_input, len);\n buffer[len] = '\\0';\n printf(\"Processed: %s\\n\", buffer);\n free(buffer);\n}",
"explanation": "修复涉及多个层面:类型安全(size_t)、整数溢出检查(SIZE_MAX 边界)、安全的内存复制(memcpy 替代 strcpy)。这些都是安全编码的基本实践。"
}
],
"explanation": "此代码阅读题考察学生对整数溢出导致缓冲区溢出的安全漏洞理解,以及修复安全漏洞的能力。",
"source": null,
"related": []
}
]
}