Skip to content

How To Find And Prevent Entire Classes Of Security Vulnerabilities

Sam Lanning

AppSecOWASP Foundation34 minOpen on YouTube ↗

Sam Lanning examines How To Find And Prevent Entire Classes Of Security Vulnerabilities.

Summary

### Overview In this talk, Sam, a developer advocate formerly at Semmle (recently acquired by GitHub), discusses how software projects repeatedly suffer from identical or closely related security bugs due to incomplete patching and shared architectural patterns. Rather than treating each reported vulnerability as an isolated incident, security teams need to practice variant analysis—a methodology used by organizations like Google and Microsoft to discover, investigate, and simultaneously fix all variations of a vulnerability across codebases before releasing patches publicly.

### Key Topics - **Recurring Bug Patterns and Incomplete Fixes**: Real-world examples illustrate the systemic failure of one-off patching. In the Spring Framework (September 2017), user data concatenated into Spring Expression Language strings allowed remote code execution (RCE); pivotal patches were repeatedly bypassed until a major architectural refactor eliminated the vulnerability. Similarly, Apache Struts 2 suffered dozens of RCE vulnerabilities spanning multiple years (such as in 2013, 2016, and 2017) due to untrusted user input flowing into OGNL expressions. Even Apple's macOS/OS X XNU kernel packet mangler saw an initial RCE fix by Kevin Backhouse that left an exploitable bug in the exact same block of code. - **The Shift from Manual to Automated Variant Analysis**: Historically, variant analysis relied heavily on manual data flow analysis, following call graphs in IDEs or Sourcegraph, and text searching with grep and awk. This manual approach is tedious, error-prone, and cannot scale as codebases grow and developer headcount dwarfs security staffing. Automating variant analysis allows security teams to query code syntactically and semantically (leveraging control flow, data flow, and call graphs) across entire repositories and multiple projects. - **Ecosystem Knowledge Sharing**: When a vulnerability stems from standard library misuses or framework patterns—such as the "Zip Slip" path traversal vulnerability documented by Snyk—rules can be shared publicly. Microsoft and Semmle authored and open-sourced rules in languages like C# and Java to detect Zip Slip patterns where archive paths are concatenated to target directories without proper sanitization.

### Technical Details - **ChakraCore Query Example**: Referencing a blog post by Microsoft's Stephen Hunter, Sam highlights a critical vulnerability in Microsoft's ChakraCore JavaScript engine. In C++ code exposed to JavaScript, a pointer and size to an ArrayBuffer (`pBuffer` and `bufferSize`) were extracted before calling `v8::ToPrimitive` / `valueOf`. Overriding `valueOf` in JavaScript allowed an attacker to free the buffer, leaving `pBuffer` as a dangling pointer leading to potential memory corruption or RCE. Microsoft modeled this pattern using a declarative SQL-like query language: selecting variables, ArrayBuffer pointer assignments, function calls, and variable accesses; filtering for calls that transitively reach `MethodCallToPrimitive`; and verifying that the call occurs after the assignment but before the variable use. This automated query identified the seed bug and four additional critical variants. - **Integrating into Development Lifecycles**: A standard response workflow integrates variant analysis immediately following root cause diagnosis. Engineers write a semantic query, iteratively refine it against false positives, triage findings, and patch all variants simultaneously prior to public disclosure. These queries can then be integrated into continuous integration (CI), nightly builds, or code review tools (similar to Mozilla using Clang-Tidy on Phabricator for Firefox patches).

### Takeaways - **Automate and Continuous Testing**: Variant analysis should be automated and run continuously against pull requests or nightly builds to prevent regressions and catch repeat mistakes. - **Defense in Depth**: Variant analysis complements rather than replaces other disciplines. It does not replace sound software architecture (e.g., migrating to Rust for memory safety, avoiding raw expression languages, or using auto-escaping SQL libraries), exploit mitigations (ASLR, stack canaries), or practices like fuzzing, penetration testing, bug bounties, and red teaming.

Related talks