InfoSec Taiwan 2026 · Private Preview
Hundreds of billions of lines of code are being written by AI. AI now generates code faster than any of us can review it. The tooling to catch what it gets wrong has existed for twenty years, yet almost no one wired it up to the machine writing a million lines a week.
Two minutes, and it feeds the research. Scan the code, or open the link below.
AI became a general-purpose technology. You describe what you want in plain English, and the tooling writes the code. The entire open-source software development lifecycle, from build to deployment to operations, collapses into the work of a single operator. One person now owns what used to take a team, and no one is reading the millions of lines in between.
"These days I don't read much code anymore. I watch the stream and sometimes look at key parts, but I gotta be honest - most code I don't read. I do know where which components are and how things are structured and how the overall system is designed, and that's usually all that's needed."
Peter Steinberger, creator of OpenClaw
Source: Shipping at Inference-Speed, Peter Steinberger
How a decade of tooling led us to writing English instead of code.
VS Code, Sublime Text, Eclipse. You wrote every line yourself. The IDE highlighted syntax and little else.
A parallel path was already open. Robotic process automation and enterprise no-code platforms like TIBCO let teams stand up microservices and apps with little hand-written code, just basic data design. The first taste of "describe it, don't code it."
Andrew Ng's Python courses put a generation into Jupyter Notebooks:
markdown, pip install, anaconda, IPython. Programming got a much
wider front door.
The editor becomes the default surface for millions of developers, and the canvas that AI would later paint on.
Catches hardcoded API keys, tokens, and credentials before they reach the repo, exactly what AI agents tend to copy or invent.
Security review reads a code path and reasons about whether it is actually exploitable, not just pattern matching.
Source: GitHub Advisory Database (query: OpenClaw) and CVE.org, counts as of July 2026
Signals from GitHub, 2025 to 2026: who reviews the code, who opens the pull requests, and who pushes to build.
AI coding assistants now perform 60% of bot PR reviews on GitHub, up from about 20% a year earlier.
Top PR authors · Q2 2025
The real number is higher, think Claude Code or Cursor authored commits.
Top pushes · Q2 2025
Make coding cheaper and you don't get less code, you get vastly more of it. Economists have a name for this: Jevons paradox.
The tools multiplied, and each one lowered the cost of producing code by another order of magnitude.
Source: Architecture Overview
The program lets user input become part of a system command, and the attacker can sneak in extra commands.
CWE-78: Improper Neutralization of Special Elements used in an OS Command
Scope: Confidentiality, Integrity, Availability, Non-Repudiation
The impact: Execute Unauthorized Code or Commands; DoS: Crash, Exit, or Restart; Read Files or Directories; Modify Files or Directories; Read Application Data; Modify Application Data; Hide Activities.
Attackers could execute unauthorized operating system commands, which could then be used to disable the product, or read and modify data for which the attacker does not have permissions to access directly. Since the targeted application is directly executing the commands instead of the attacker, any malicious activities may appear to come from the application or the application's owner.
#include <stdio.h> #include <stdlib.h> void list_home(char *user) { char cmd[256]; sprintf(cmd, "ls /home/%s", user); system(cmd); } int main() { list_home("alice"); // runs: ls /home/alice }
#include <stdio.h> #include <stdlib.h> void list_home(char *user) { char cmd[256]; sprintf(cmd, "ls /home/%s", user); system(cmd); } int main() { list_home("alice; rm -rf /home"); // runs: ls /home/alice; rm -rf /home // lists, then deletes ☠ }
Researchers asked GitHub Copilot to write three ordinary programs. Each one takes something the user types and hands it to the system.
The majority of Copilot's suggestions were vulnerable. For Test 1, the exact program above, every option it generated was vulnerable, and it was most confident in the insecure code.
We surveyed AI practitioners, developers, security engineers, engineering managers, and students. The marketing and the experience on the ground are two different things.
The tool that catches AI's command injection is not new. It is static analysis, and it has run for twenty years. This section is one narrow, provable claim: static analysis plus taint analysis plus a current sink list catches this class of bug. The baby was never broken, teams just stopped pointing it at the code.
Static analysis reads code without running it, for anything from types to bugs to security. The security slice of it is SAST, Static Application Security Testing. Inside SAST, taint analysis follows the data, and a rule pack extends what it catches. That chain is the rest of this section.
SAST reads code without running it and flags risky patterns. Two engines dominate the field:
Both Semgrep and CodeQL are Static Application Security Testing (SAST) tools, and both feature taint analysis capabilities.
A taint engine models the code as a data-flow graph and control-flow graph over its abstract syntax tree (AST), then traces whether user input can reach a sink. It runs in either direction:
Either direction, it only reports a flow that reaches a sink on its list. The quality of that sink list decides what gets found. Miss the sink, miss the bug.
_execvp was missing, so the injection shipped. A rule pack adds it, no change to the engine, and the same injection is caught._execvp was not on the listCodeQL's command-execution sinks live in one hand-maintained library,
CommandExecution.qll. It enumerates the POSIX exec* family and the
Windows _spawn* / _wexec* variants. _execvp was not
among them, so data flowing into it was invisible to the analysis. Reported and fixed in
GitHub discussion #15963.
If a sink is not on the list, the engine cannot find it. The engine was never broken, the list was incomplete.
// known command-execution functions, hand-maintained // cpp/ql/lib/.../security/CommandExecution.qll ["execl", "execle", "execlp", "_spawnl", "_wexecl", "_wspawnl", ...] ["execv", "execvp", "execve", "fexecve", "_execvp", "_spawnv", "_wexecv", ...] // ^ _execvp: missing before, added after #15963
A rule pack extends a scanner past its defaults to what is dangerous in your environment. With LLMs you can add sinks you spot in the wild, on the fly. Semgrep uses YAML patterns, CodeQL adds a query, Fortify ships XML Rulepacks, and a sink can be extended with a one-line JSON entry.
rules: - id: raptor-command-injection languages: [c, cpp] severity: ERROR message: OS command built from externally-influenced input. patterns: - pattern-either: - pattern: system(...) - pattern: popen(...) - pattern: p2open(...) - pattern: wordexp(...) - pattern-not: $_("...", ...)
{
"type": "Sink",
"fn_list": [
{
"fn_name": "^(execv)$",
"is_regex": 1,
"match_type": [
"find_param_0",
"find_param_1"
]
}
]
}
In 2019 the research team ran a known SAST scanner on NGINX 1.4.0 for CVE-2013-2028 with no custom rule pack. It found nothing. We modeled the taint flow, added a custom rule pack, and the same scanner found it. The engine wasn't broken, the rule pack was empty. Along the way we also hit real limits in the engine itself.
Maintained custom rule packs and academic work on rule-pack design:
CodeQL's command-execution sinks are enumerated by name in
CommandExecution.qll. The complete POSIX exec* family plus Windows
variants. If a name is not on these lists, no flow into it is ever reported.
["execl", "execle", "execlp", // Windows "_execl", "_execle", "_execlp", "_execlpe", "_spawnl", "_spawnle", "_spawnlp", "_spawnlpe", "_wexecl", "_wexecle", "_wexeclp", "_wexeclpe", "_wspawnl", "_wspawnle", "_wspawnlp", "_wspawnlpe"]
["execv", "execvp", "execvpe", "execve", "fexecve", // Windows variants "_execv", "_execve", "_execvp", "_execvpe", "_spawnv", "_spawnve", "_spawnvp", "_spawnvpe", "_wexecv", "_wexecve", "_wexecvp", "_wexecvpe", "_wspawnv", "_wspawnve", "_wspawnvp", "_wspawnvpe"] // ^ _execvp was absent until #15963
// the sink lives in the reusable library, not the query predicate isSinkImpl(DataFlow::Node sink, Expr command, string callChain) { command = sink.asIndirectArgument() and shellCommand(command, callChain) // <- CommandExecution.qll }
predicate extendedShellCommand(Expr cmd, string callChain) { shellCommand(cmd, callChain) // original sinks or exists(FunctionCall fc | // + _execvp fc.getTarget().getName() = "_execvp" and fc.getArgument(0) = cmd and callChain = "_execvp" ) or exists(FunctionCall fc | // + your own sink fc.getTarget().getName() = "myDangerousExec" and fc.getArgument(1) = cmd and callChain = "myDangerousExec" ) }
No one wired these up to the AI tool that just wrote a million lines of code. Most teams still haven't.
Most SCA tools stop at the first level: a dependency matches a known CVE. The gap between "a CVE exists" and "this CVE can hurt you" is a maturity curve of its own:
AISLE is a working example at Levels 2 and 3: it traces the dependency chain into first-party code and synthesizes exploitability signals instead of guessing.
Source: How AISLE Unifies Detection and Remediation at Scale
Even among people who use these tools every day, some didn't know the security capabilities existed at all. (Preliminary research.)
The Claude Code plugin runs security analysis right inside the CLI: SAST checks applied to code as the agent writes it, not months later in a pen test.
AI continues to write more code. If you are the single operator, you are also the security team, and it now has to cover the autonomous agents writing and shipping your code. Here is where to start, without slowing down.
Encode your team's institutional knowledge, the sinks and patterns that are dangerous in your environment, and apply it to every line the agent emits.
Audit what security capability your AI coding stack actually ships with. Built-in? Third-party? Or not there at all? Assume nothing from the marketing.
SAST. SCA. Taint analysis. Custom rules. The baby.
Wire it into the agent that writes your code, so it checks what you don't read.
Don't throw the baby out because AI is writing the code now. That's exactly when you need it most.