English
Security engineering studies how systems preserve stated properties against specified adversaries. Confidentiality restricts disclosure, integrity restricts unauthorized change, and availability concerns access to a service. Begin by naming the asset, the attacker’s capabilities, and the property to protect. A vulnerability has consequences through an attack path; its existence does not mean that every asset and every boundary have failed.
Cryptography provides precisely defined constructions for secrecy, authentication, and related tasks. Security proofs compare an adversary’s success against a mathematical bound under stated assumptions. Formal guarantees also exist for access control, information flow, and verified implementations; they are not exclusive to cryptography. A cryptographic proof and a system-security claim cover different things. Key handling, protocol state, implementation behavior, and recovery procedures must connect the construction to the application.
Cryptography studies specified guarantees under mathematical assumptions; security engineering integrates mechanisms across a system; vulnerability analysis examines ways those properties can fail. These activities inform each other. Different roles require different depth, but each should identify the assumptions and boundaries of the protection being claimed.
Prerequisites: Computer networks (§4.3) — protocols, TLS, and network-layer attacks. Operating systems (§4.2) — privilege separation, memory management, and system calls. Discrete mathematics (§2.2) — modular arithmetic, number theory, and probability for cryptography. Complexity theory (§3.2–§3.3) — cryptographic security is based on computational hardness.
From Military Codes to Mathematical Proof
Classical substitution ciphers illustrate why hidden messages can still reveal structure. A Caesar shift preserves letter frequencies; repeating-key polyalphabetic ciphers obscure them but introduce repeating relationships that analysis can exploit. Cryptanalysis therefore asks what information the construction leaks, not just whether the text looks unreadable. Modern definitions make the attacker’s observations and success criterion explicit.
Wartime cryptanalysis combined mathematical insight, operational information, and machinery. The attack on Enigma built on prewar Polish work and later efforts by Turing, Welchman, and many colleagues at Bletchley Park and elsewhere. Machine design mattered, but so did procedures, available traffic, and operator mistakes. The historical lesson is that a cipher is deployed within a system of people and practices, and its nominal key space alone does not determine security.
Shannon’s 1949 Communication Theory of Secrecy Systems formalized secrecy in probabilistic terms. A one-time pad uses a uniformly random, independent key, as long as the encoded message and never reused, to achieve perfect secrecy. Ciphertext then does not change the adversary’s distribution over messages under the model. This does not provide integrity: modifying ciphertext can modify the recovered message. Key distribution and single use also remain operational obligations. Later computational security relaxes the unlimited-adversary model in order to use shorter keys.
Diffie and Hellman’s 1976 paper introduced public-key ideas and a concrete key-agreement construction. Two parties could derive a shared value across a publicly observed channel, under computational assumptions, without a previously shared secret. Unauthenticated agreement remained vulnerable to an active intermediary replacing the exchanged values. RSA, introduced shortly afterward, supplied another public-key construction. These developments separated agreement, encryption, and signatures into distinguishable tasks; authenticating the public key or the exchange remained essential to the intended security claim.
SSL and then TLS helped deploy protected web communication widely. Their evolution addressed protocol design, negotiation, cryptographic constructions, and implementation flaws. TLS 1.3, standardized in 2018, changed the handshake and removed many legacy choices. Different historical attacks targeted different layers and versions; a protocol name alone does not specify whether a deployment is appropriately configured and maintained.
The 1988 Morris Worm showed how vulnerabilities and network connectivity could combine into widespread service disruption. It exploited several weaknesses, including in Unix network services, and its repeated propagation overloaded affected machines. Later public analyses of buffer-overflow exploitation made a recurring systems problem more explicit: treating attacker-controlled bytes as trusted memory contents or control information can turn a local coding error into an intrusion path.
Memory-corruption defenses illustrate why mechanisms need explicit scopes. Stack canaries can detect certain overwrites, ASLR makes addresses less predictable, and non-executable mappings restrict execution of injected data. Code-reuse attacks can use instructions already present, so preventing injected-code execution is not the same as preventing control-flow hijacking. Memory-safe languages and checked interfaces address causes of many corruption bugs, while unsafe code and foreign interfaces remain boundaries to examine.
Public-key systems made large-scale secure communication easier to organize, but each scheme relies on particular assumptions and protocol rules. Diffie–Hellman agreement, RSA-based schemes, and elliptic-curve signatures are not interchangeable operations, and there is no standard elliptic-curve version of RSA. Computational assumptions concern the difficulty of specific attack problems with specified resources; they are not established merely by the worst-case NP-hardness of some related problem.
Transient-execution attacks such as Spectre and Meltdown connected security analysis to microarchitectural behavior (§4.1). A discarded computation can still affect timing or cache state. The failures require distinctions between architectural access checks, speculative execution, and observations available to another participant. Different attacks need different mitigations; functional correctness of the final instruction result alone does not establish confidentiality during execution.
Shor’s algorithm threatens factoring- and discrete-logarithm-based schemes if sufficiently capable fault-tolerant quantum computers become available. In 2024, NIST finalized three initial post-quantum standards: ML-KEM for key encapsulation, ML-DSA for signatures, and the hash-based SLH-DSA for signatures. A key-encapsulation mechanism establishes a shared secret for subsequent symmetric protection; it is not itself arbitrary-message encryption. Migration also concerns protocol compatibility, key and signature sizes, implementation assurance, and how long captured information must remain secret. It does not require claiming a known date for a cryptographically capable quantum computer.
Cryptographic Primitives, System Security, and the Adversarial Mindset
Ask what each mechanism establishes. Encryption hides content; authentication checks a claimed source or credential; authorization decides which operation that identity may perform. Integrity detects unauthorized changes under a specified threat model. These guarantees can be combined, but one does not automatically imply the others.
Cryptographic Building Blocks
Symmetric encryption uses a shared secret key. AES is a block cipher with a 128-bit block size and several key sizes; a mode specifies how it handles messages. Authenticated encryption, such as AES-GCM or ChaCha20-Poly1305, protects confidentiality and detects modification under its rules. Nonces and keys must be managed according to the construction: reusing a nonce under a key can invalidate security. Encryption without authentication is not a substitute for authenticated encryption.
A cryptographic hash summarizes data into a fixed-size output. Preimage, second-preimage, and collision resistance are computational requirements, not claims that collisions do not exist. A downloaded file and its hash can both be replaced by an attacker unless the expected hash arrives through an authenticated path. HMAC uses a secret key to authenticate messages; a digital signature allows verification with a public key whose identity binding must itself be trusted.
Passwords need a different cost model from general-purpose hashing. A fast digest lets an attacker test many guesses after stealing a password database. Password hashing uses a per-password salt and a deliberately costly construction such as Argon2id, with parameters chosen for the deployment. The salt prevents identical passwords from automatically having identical stored values and prevents broad reuse of precomputation; it does not make a weak password hard to guess. OWASP’s password-storage guidance explains the roles of salts and work factors.
Public-key encryption, key agreement, key encapsulation, and signatures have different interfaces. ECDH is key agreement; ML-KEM is key encapsulation; ECDSA and Ed25519 are signature schemes. A signature proves a relation between a message and a key under the scheme’s assumptions, not that the message is true or that its author is authorized to act. Do not describe signing generally as encrypting with the private key.
Use a maintained protocol and library appropriate to the task, and study its required inputs and failure behavior. TLS secures a connection between its endpoints; an end-to-end messaging design can have different endpoints and key-management requirements. Key generation, storage, rotation, revocation, and recovery are part of the system. Selecting a named algorithm is only one step in establishing the desired property.
The Security Engineering Mindset
Security engineering differs from ordinary software engineering in its required adversarial perspective. An engineer building a reliable system asks: what could go wrong accidentally? A security engineer adds: what could an adversary do deliberately, given complete knowledge of the system’s design? Kerckhoffs’s principle, formulated in 1883 for military cryptography, states that a cryptographic system should be secure even if everything about it except the key is public knowledge. The modern interpretation is broader: system security should not depend on obscurity about how the system works.
Threat modeling is the systematic practice of identifying what could go wrong adversarially. The STRIDE framework (Microsoft Research, late 1990s) categorizes threats into Spoofing (impersonation), Tampering (modification), Repudiation (denying actions), Information Disclosure, Denial of Service, and Elevation of Privilege. For any system component, applying STRIDE generates a systematic list of threat categories to consider. The output is not a checklist but a set of questions: which threats are relevant, which mitigations apply, and what residual risk remains.
Least privilege is the design principle that every component should have only the capabilities it requires. A web server process that needs to read static files should not run as root; a database connection used for reads should not have write permissions; a microservice that needs to call one API should not have credentials for another. Violations of least privilege allow compromised components to cause damage beyond their intended scope. Defense in depth is the complementary principle: every security boundary might fail, and systems should be designed so that multiple boundaries must fail for the most important properties to be violated.
Application-security categories such as those in the OWASP Top 10 provide starting questions rather than a complete or universally ranked inventory. Parameterized queries separate SQL syntax from supplied values; output encoding must match the HTML, script, or URL context; authorization checks must bind the authenticated identity to the requested object and action. For example, authenticating a user does not permit that user to change an account identifier in a request and read somebody else’s record. Such properties need explicit checks even when every connection uses TLS.
Finding Vulnerabilities: Fuzzing, Penetration Testing, and Code Review
Offensive security is the practice of finding vulnerabilities before adversaries do. Understanding attacks well enough to prevent them requires learning to think like an attacker.
Coverage-guided fuzzing mutates inputs and uses execution feedback to reach new behavior. A harness defines what is exercised, and an oracle defines what counts as failure. Sanitizers, assertions, differential comparisons, and domain-specific invariants can detect different classes of defects, including some logic errors. A crash-only oracle misses failures that do not crash, and a shallow harness misses behavior it never reaches. The quality of the experiment matters as much as the tool name.
Static analysis examines code and its modeled data or control flow without running every case. CodeQL, Semgrep, and other analyzers expose different rule languages and tradeoffs. False positives and missed findings depend on the rule, model, and codebase; they do not have one universal rate. Review the reported path and assumptions, then fix the cause and preserve a regression check where it verifies the intended security property.
Penetration testing examines a specified system within agreed authorization and scope. Human analysis can connect business rules, deployment details, and sequences of operations that an automated scan does not cover. The report should explain the affected property, evidence, preconditions, and remediation. A test samples attack paths under its time and access limits; neither a clean test nor a large number of findings alone measures the whole system’s security.
What Studying This Changes
Security changes how practitioners design and evaluate systems.
The first change is the adversarial mindset: the habit of asking not just “will this work?” but “how could this be broken?” Before deploying any system that handles sensitive data, the security-trained practitioner asks: what happens if an attacker controls the inputs? What if an authenticated user tries to access another user’s data? What if the database is compromised? These questions are not hypothetical; they are anticipated design constraints. Systems designed with these questions from the beginning are more secure than systems to which security is retrofitted.
An explicit trust model identifies which inputs and components can influence a protected action. Validation, authentication, authorization, and privilege separation address different parts of that path. Trace a request across those boundaries and check whether a compromise would be contained under the stated assumptions.
The third change is cryptographic literacy. The practitioner who understands which cryptographic primitives provide which guarantees can evaluate whether a system’s cryptographic design is sound: is confidentiality provided by authenticated encryption, or only by encryption without integrity? Is the key exchange using forward secrecy? Is the password storage using a slow hash with a per-user salt? These questions have specific, verifiable answers, and getting them wrong has severe consequences.
To practice, draw the trust boundaries of a small service and follow one request from identity validation to object-level authorization and storage. For each claimed protection, name the mechanism and its assumptions. This turns a review finding into a question that can be checked, such as whether every account read verifies that the caller may access that account.
Resources
Books and Texts
Anderson’s Security Engineering connects technical mechanisms to people, institutions, and incentives. Katz and Lindell’s Introduction to Modern Cryptography develops formal definitions and proofs; Aumasson’s Serious Cryptography offers an implementation-oriented route. OWASP’s testing and verification materials organize application checks. The Web Application Hacker’s Handbook and The Tangled Web provide historical web-security depth, with browser and protocol details to check against newer documentation. NIST publishes the normative post-quantum standards.
| Book | Role | Type |
|---|---|---|
| Anderson, Security Engineering (3rd ed., free) | Comprehensive foundational reference | Reference |
| Katz & Lindell, Introduction to Modern Cryptography (3rd ed.) | Cryptographic theory | Depth |
| Aumasson, Serious Cryptography | Accessible cryptographic practice | Entry |
| Crypto 101 (free) | Friendly practical cryptography supplement | Auxiliary |
| Boneh & Shoup, A Graduate Course in Applied Cryptography (free) | Graduate cryptographic theory | Depth |
| OWASP Testing Guide (free) | Web application security | Reference |
| OWASP ASVS (free) | Application security verification | Reference |
| Stuttard & Pinto, The Web Application Hacker’s Handbook (2nd ed.) | Web security attack perspective | Depth |
| Zalewski, The Tangled Web | Web security depth | Depth |
| Saltzer & Schroeder, “The Protection of Information in Computer Systems” (1975, free) | Foundational secure design paper | Depth |
Courses and Lectures
Stanford CS255 and Boneh’s cryptography lectures develop security definitions and constructions. MIT 6.858 connects system mechanisms to concrete vulnerabilities. WebGoat, PortSwigger Web Security Academy, HackTheBox, and Cryptopals provide different practice environments. For each exercise, explain the violated property, the preconditions, and why the repair addresses the cause; completing a challenge alone does not establish the security of a different system.
| Course | Platform | Type |
|---|---|---|
| Stanford CS255 / Dan Boneh Coursera Cryptography (free) | Stanford / Coursera | Entry |
| MIT 6.858 Computer Systems Security (free) | MIT OCW | Entry |
| PortSwigger Web Security Academy (free) | portswigger.net/web-security | Practice |
| Cryptopals (free) | cryptopals.com | Practice |
| OWASP WebGoat / HackTheBox (free tiers) | Various | Practice |
| pwn.college (free) | pwn.college | Practice |
Practice, Tools, and Current Sources
Burp Suite exposes HTTP exchanges for application testing; Wireshark exposes visible network behavior. libsodium documents particular cryptographic interfaces, not a universal solution for every protocol. AFL++ and libFuzzer support fuzzing, whose results depend on the harness, inputs, and failure oracle. CVE records identify disclosed vulnerabilities; NVD and vendor advisories add analysis and remediation context. Check the affected versions and actual deployment before inferring exposure.
| Resource | Platform | Type |
|---|---|---|
| Burp Suite Community Edition (free) | portswigger.net | Practice |
| libsodium documentation (free) | libsodium.org | Practice |
| Wireshark for security traffic analysis (free) | wireshark.org | Practice |
| AFL++ / libFuzzer (free) | GitHub | Practice |
| CVE / NVD databases (free) | cve.mitre.org / nvd.nist.gov | Reference |
| Google Project Zero blog (free) | googleprojectzero.blogspot.com | Reference |
| USENIX Security / ACM CCS / IEEE S&P proceedings (access varies) | Current security research venues | Reference |
Traps
| Trap | Why it misleads | Better response |
|---|---|---|
| Designing a protocol by combining algorithm names | Secure primitives can be composed into an insecure protocol. | Use a maintained protocol implementation and understand its inputs, key lifecycle, and guarantee. |
| Treating a checklist as a complete model | A checklist may omit application-specific assets, trust boundaries, or abuse paths. | Define the adversary and trace how controlled inputs reach protected operations. |
| Relying on hidden design alone | Design details may become known without exposing the actual secret keys. | Evaluate protection assuming the protocol and code are known, while managing secrets explicitly. |
| Fixing a finding without examining its reach | One weakness can expose credentials or privileges that enable further actions. | Trace the accessible assets and restrict the permissions that allow damage to spread. |
| Ignoring preconditions or treating all findings equally | Practical risk depends on reachability, attacker capability, impact, and exposure. | Evaluate those factors against the threat model and prioritize concrete fixes. |
| Treating a new cryptographic standard as a complete migration | Protocol integration, keys, compatibility, and long-lived data still need analysis. | Inventory cryptographic dependencies and plan migration using the relevant standards and implementations. |
中文
安全工程研究系统怎样针对指定对手保持明确性质。机密性限制泄露,完整性限制未经授权的改变,可用性关注能否使用服务。应先说明资产、攻击者能力与要保护的性质。漏洞通过攻击路径产生后果,存在一个漏洞并不表示所有资产和边界都已失守。
密码学为保密、认证等任务提供精确定义的构造。安全证明在指定假设下,用数学界约束对手成功的可能性。访问控制、信息流与经过验证的实现也可以具有形式保证,并非只有密码学如此。密码学证明与系统安全主张覆盖不同事物。密钥处理、协议状态、实现行为和恢复流程,需要把构造连接到应用。
密码学在数学假设下研究明确保证,安全工程跨系统整合机制,漏洞分析则检查这些性质可能怎样失败。这些活动相互提供信息。不同角色需要不同深度,但都应识别所声称保护的假设与边界。
前置知识:计算机网络(§4.3)——协议、TLS 和网络层攻击。操作系统(§4.2)——特权隔离、内存管理和 system calls。离散数学(§2.2)——密码学所需的模运算、数论和概率。复杂性理论(§3.2–§3.3)——密码学安全建立在计算困难性之上。
从军事密码到数学证明
古典替换密码说明,隐藏后的消息仍可能暴露结构。凯撒移位保留字母频率,重复密钥的多表密码掩盖频率,却引入分析可以利用的重复关系。因此,密码分析询问构造泄露什么信息,而不只是文本看起来是否难以阅读。现代定义把攻击者可以观察什么、怎样才算成功明确化。
战时密码分析结合数学见解、操作情报与机器。对 Enigma 的分析建立在战前波兰工作,以及后来 Turing、Welchman 与 Bletchley Park 等地许多同事的努力之上。机器设计重要,操作流程、可获得通信和操作者错误同样重要。历史说明,密码部署在人与实践构成的系统中,仅凭标称密钥空间不能确定安全性。
Shannon 在 1949 年的 Communication Theory of Secrecy Systems 中用概率形式化保密性。一次一密使用均匀随机、独立、与编码消息等长且不重复使用的密钥,实现完美保密;在模型中,密文不改变对手对消息的概率分布。这不提供完整性:修改密文可以改变恢复的消息。密钥分发和仅使用一次仍是操作义务。后来的计算安全性放宽无限能力对手模型,以便使用较短密钥。
Diffie 与 Hellman 在 1976 年的论文中介绍了公钥思想和具体的密钥协商构造。在计算假设下,双方无需预先共享秘密,就能通过可被公开观察的信道得到共享值。但未经认证的协商仍可能受到主动中间人替换交换值的攻击。随后出现的 RSA 提供了另一种公钥构造。这些发展使协商、加密和签名成为可区分的任务;认证公钥或交换过程,仍是所需安全主张的必要部分。
SSL 及后来的 TLS,推动受保护的网页通信广泛部署。它们的演进处理协议设计、协商、密码构造与实现缺陷。2018 年标准化的 TLS 1.3 改变握手,并移除了许多旧选择。不同历史攻击针对不同层次和版本;仅凭协议名称,不能确定部署是否具有适当配置并得到维护。
1988 年的 Morris Worm 展示了漏洞与网络连接怎样结合成大范围服务中断。它利用了包括 Unix 网络服务在内的多处弱点,反复传播使受影响机器过载。后来的公开缓冲区溢出分析进一步明确了一项反复出现的系统问题:把攻击者控制的字节当成可信内存内容或控制信息,可能使局部编码错误成为入侵路径。
内存破坏防御说明,机制需要明确范围。栈金丝雀可以检测某些覆盖,ASLR 使地址更难预测,不可执行映射限制注入数据的执行。代码复用攻击可以使用已有指令,因此阻止注入代码执行,不等于阻止控制流劫持。内存安全语言与经过检查的接口,处理许多内存破坏错误的原因;不安全代码与外部接口仍是需要检查的边界。
公钥系统使较大规模的安全通信更容易组织,但每种方案依赖特定假设与协议规则。Diffie–Hellman 协商、基于 RSA 的方案和椭圆曲线签名,不是可互换的操作,也不存在通常所说的“RSA 的椭圆曲线版本”。计算假设讨论在指定资源下解决特定攻击问题的困难程度,不能仅凭某个相关问题具有最坏情形 NP 困难性来建立。
Spectre、Meltdown 等瞬态执行攻击,把安全分析连接到微架构行为(§4.1)。被丢弃的计算仍能影响时序或缓存状态。分析这些失败需要区分架构访问检查、推测执行,以及其他参与者能够作出的观察。不同攻击需要不同缓解方法,仅有指令最终结果的功能正确性,不能建立执行过程中的机密性。
如果具备足够能力的容错量子计算机出现,Shor 算法会威胁基于因数分解与离散对数的方案。2024 年,NIST 完成首批三个后量子标准:用于密钥封装的 ML-KEM、用于签名的 ML-DSA,以及基于哈希的签名方案 SLH-DSA。密钥封装机制建立共享秘密,供后续对称保护使用,本身不是任意消息加密。迁移还涉及协议兼容性、密钥和签名大小、实现保证,以及已截获信息需要保密多久。这不要求声称已经知道何时会出现足以破坏密码的量子计算机。
密码学原语、系统安全与对抗性心智
应问每种机制建立什么:加密隐藏内容,认证检查声称的来源或凭据,授权决定该身份可以执行什么操作,完整性则在指定威胁模型下检测未经授权的改变。这些保证可以组合,但一种不会自动推出其他保证。
密码学构件
对称加密使用共享秘密密钥。AES 是块大小为 128 位、支持若干密钥长度的分组密码,模式规定它怎样处理消息。AES-GCM、ChaCha20-Poly1305 等认证加密,在其规则下保护机密性并检测修改。必须按照构造要求管理 nonce 与密钥;同一密钥下复用 nonce 可能使安全保证失效。没有认证的加密不能代替认证加密。
密码学哈希把数据概括为固定大小输出。原像、第二原像和碰撞抗性是计算要求,并不声称不存在碰撞。除非预期哈希通过经认证的路径获得,否则攻击者可以同时替换下载文件及其哈希。HMAC 使用秘密密钥认证消息;数字签名允许使用公钥验证,但公钥与身份的绑定本身也需要信任依据。
密码存储需要不同于通用哈希的成本模型。攻击者窃取密码数据库后,快速摘要允许大量猜测。密码哈希使用逐密码的盐,以及 Argon2id 等有意增加成本的构造,并为部署选择参数。盐避免相同密码自动产生相同存储值,并阻止广泛复用预计算,却不会使弱密码难以猜中。OWASP 的密码存储说明解释了盐与工作因子的作用。
公钥加密、密钥协商、密钥封装与签名具有不同接口。ECDH 是密钥协商,ML-KEM 是密钥封装,ECDSA 与 Ed25519 是签名方案。签名在方案假设下证明消息与密钥之间的关系,不证明消息真实,也不证明作者获准执行某操作。不能普遍把签名称为“用私钥加密”。
使用适合任务、持续维护的协议与库,并学习所需输入和失败行为。TLS 保护其端点之间的连接,端到端消息设计可能具有不同端点和密钥管理要求。密钥生成、保存、轮换、撤销与恢复都是系统的一部分。选择一个有名称的算法,只是建立所需性质的一步。
安全工程心智
安全工程区别于普通软件工程之处,在于它要求对抗性视角。构建可靠系统的工程师会问:什么可能意外出错?安全工程师还要问:如果对手完全知道系统设计,他能故意做什么?Kerckhoffs’s principle 于 1883 年为军事密码学提出,它认为一个密码系统即使除 key 以外的所有内容都公开,也应当保持安全。现代解释更宽:系统安全不应依赖于别人不知道系统如何工作。
Threat modeling 是系统性识别对抗性失败可能性的实践。STRIDE framework(Microsoft Research,1990 年代后期)把威胁分为 Spoofing(冒充)、Tampering(篡改)、Repudiation(否认行为)、Information Disclosure、Denial of Service 和 Elevation of Privilege。对任何系统组件应用 STRIDE,都可以生成一组系统性威胁类别。其输出不是 checklist,而是一组问题:哪些威胁相关,哪些缓解措施适用,以及还剩下什么 residual risk。
Least privilege 是一条设计原则:每个组件都应只拥有它所需的能力。一个只需要读取静态文件的 Web server process 不应以 root 身份运行;一个用于读取的 database connection 不应拥有写权限;一个只需要调用某个 API 的 microservice 不应拥有另一个 API 的 credentials。违反 least privilege 会使被攻破组件造成超出其预期范围的损害。Defense in depth 是互补原则:每条安全边界都可能失败,因此系统应当被设计成,只有多条边界同时失败时,最重要性质才会被破坏。
OWASP Top 10 等应用安全类别提供起始问题,并非完整或适用于所有系统的风险排名。参数化查询把 SQL 语法与输入值分开;输出编码必须匹配 HTML、脚本或 URL 上下文;授权检查需要把已认证身份连接到所请求对象和操作。例如,认证了一个用户,不表示允许其改变请求中的账户标识并读取他人记录。即使所有连接都使用 TLS,也需要明确检查这些性质。
发现漏洞:Fuzzing、渗透测试与代码审查
攻击性安全是在对手之前发现漏洞的实践。要足够理解攻击以便预防,就必须学习像攻击者一样思考。
覆盖率引导的模糊测试变异输入,利用执行反馈探索新行为。测试入口规定测试什么,判定标准规定什么算失败。检测器、断言、差分比较与领域不变式,可以发现不同类别的缺陷,包括部分逻辑错误。只观察崩溃会漏掉不崩溃的失败,过浅的测试入口则漏掉从未到达的行为。实验质量与工具名称同样重要。
静态分析不运行每种情况,而是检查代码及其建模的数据流或控制流。CodeQL、Semgrep 等分析器提供不同规则语言与取舍。误报和漏报依赖规则、模型与代码库,没有统一比例。应检查所报告路径与假设,再修复原因;当回归检查确实验证预期安全性质时,保留这种检查。
渗透测试在约定授权与范围内检查指定系统。人工分析可以连接业务规则、部署细节与自动扫描未覆盖的操作序列。报告应说明受影响性质、证据、前提与修复方法。测试在其时间和访问限制下抽查攻击路径;一次未发现问题的测试,或很大的发现数量,都不能单独衡量整个系统的安全性。
学习这一部分会改变什么
安全会改变实践者设计和评估系统的方式。
第一个变化,是对抗性心智:习惯于不只问“这能不能工作?”,还问“它会如何被打破?” 在部署任何处理敏感数据的系统之前,受过安全训练的实践者会问:如果攻击者控制输入会怎样?如果一个已认证用户试图访问另一个用户的数据会怎样?如果数据库被攻破会怎样?这些问题不是假想,而是预期设计约束。从一开始就围绕这些问题设计的系统,比事后补安全的系统更安全。
明确的信任模型识别哪些输入与组件可以影响受保护动作。验证输入、身份认证、授权与权限分离,处理这条路径的不同部分。应跨这些边界跟踪请求,检查在所规定假设下,失陷是否会被限制在相应范围内。
第三个变化,是密码学素养。理解哪些 cryptographic primitives 提供哪些保证的实践者,能够评估一个系统的密码学设计是否可靠:机密性是由 authenticated encryption 提供,还是只有没有完整性的 encryption?Key exchange 是否使用 forward secrecy?Password storage 是否使用带 per-user salt 的 slow hash?这些问题有具体、可验证的答案,而答错会产生严重后果。
可以画出一个小服务的信任边界,跟踪请求从身份验证到对象级授权再到存储的过程。对每项声称的保护,说明机制与假设。这样,审查发现就变成可检查的问题,例如每次读取账户时,是否都验证调用者有权访问该账户。
资源
书籍与文本
Anderson 的 Security Engineering 把技术机制连接到人员、组织与激励。Katz 与 Lindell 的 Introduction to Modern Cryptography 展开形式定义与证明,Aumasson 的 Serious Cryptography 提供面向实现的路径。OWASP 测试与验证材料组织应用检查。The Web Application Hacker’s Handbook 与 The Tangled Web 提供较早的网页安全深度,其中浏览器和协议细节需要对照较新文档。后量子密码的规范性标准由 NIST 发布。
| 书籍 | 作用 | 类型 |
|---|---|---|
| Anderson, Security Engineering(第 3 版,免费) | 综合基础参考 | 参考 |
| Katz & Lindell, Introduction to Modern Cryptography(第 3 版) | 密码学理论 | 深入 |
| Aumasson, Serious Cryptography | 易读的密码学实践 | 入门 |
| Crypto 101(免费) | 友好的实践密码学补充 | 辅助 |
| Boneh & Shoup, A Graduate Course in Applied Cryptography(免费) | 研究生密码学理论 | 深入 |
| OWASP Testing Guide(免费) | Web 应用安全 | 参考 |
| OWASP ASVS(免费) | 应用安全验证 | 参考 |
| Stuttard & Pinto, The Web Application Hacker’s Handbook(第 2 版) | Web 安全攻击视角 | 深入 |
| Zalewski, The Tangled Web | Web 安全深度 | 深入 |
| Saltzer & Schroeder, “The Protection of Information in Computer Systems”(1975,免费) | 安全设计奠基论文 | 深入 |
课程与讲座
Stanford CS255 与 Boneh 的密码学课程展开安全定义和构造,MIT 6.858 把系统机制连接到具体漏洞。WebGoat、PortSwigger Web Security Academy、HackTheBox 与 Cryptopals 提供不同练习环境。每次练习应解释被破坏的性质、前提,以及修复为什么针对原因;完成一道挑战,不建立另一个系统的安全性。
| 课程 | 平台 | 类型 |
|---|---|---|
| Stanford CS255 / Dan Boneh Coursera Cryptography(免费) | Stanford / Coursera | 入门 |
| MIT 6.858 Computer Systems Security(免费) | MIT OCW | 入门 |
| PortSwigger Web Security Academy(免费) | portswigger.net/web-security | 实践 |
| Cryptopals(免费) | cryptopals.com | 实践 |
| OWASP WebGoat / HackTheBox(免费层) | Various | 实践 |
| pwn.college(免费) | pwn.college | 实践 |
实践、工具与当前资料
Burp Suite 展示用于应用测试的 HTTP 交换,Wireshark 展示可见网络行为。libsodium 文档介绍具体密码学接口,并非所有协议的通用方案。AFL++ 与 libFuzzer 支持模糊测试,结果依赖测试入口、输入与失败判定标准。CVE 记录标识已披露漏洞,NVD 与厂商公告补充分析和修复背景。推断暴露之前,应检查受影响版本与实际部署。
| 资源 | 平台 | 类型 |
|---|---|---|
| Burp Suite Community Edition(免费) | portswigger.net | 实践 |
| libsodium documentation(免费) | libsodium.org | 实践 |
| Wireshark for security traffic analysis(免费) | wireshark.org | 实践 |
| AFL++ / libFuzzer(免费) | GitHub | 实践 |
| CVE / NVD databases(免费) | cve.mitre.org / nvd.nist.gov | 参考 |
| Google Project Zero blog(免费) | googleprojectzero.blogspot.com | 参考 |
| USENIX Security / ACM CCS / IEEE S&P 论文集(获取方式不一) | 当前安全研究会议 | 参考 |
陷阱
| 误区 | 为什么会误导 | 更好的做法 |
|---|---|---|
| 靠组合算法名称设计协议 | 安全原语可能被组合成不安全协议。 | 使用维护中的协议实现,理解其输入、密钥生命周期与保证。 |
| 把清单当作完整模型 | 清单可能遗漏应用特定资产、信任边界或滥用路径。 | 定义对手,跟踪受控输入怎样到达受保护操作。 |
| 只依赖隐藏设计 | 设计细节可能在实际秘密密钥未泄露时被获知。 | 在协议与代码已知的假设下评估保护,并明确管理秘密。 |
| 修复发现却不检查影响范围 | 一个弱点可能暴露凭据或权限,允许进一步行动。 | 跟踪可访问资产,限制允许损害扩大的权限。 |
| 忽略前提或把所有发现等同处理 | 实际风险依赖可达性、对手能力、影响与暴露。 | 按威胁模型评估这些因素,为具体修复排序。 |
| 把新密码标准当作完整迁移方案 | 协议整合、密钥、兼容性与长期数据仍需分析。 | 清点密码学依赖,依据相关标准与实现规划迁移。 |