Explore our comprehensive resources on behavioral AI monitoring, compliance frameworks, and policy templates.
Start your compliance journey with HAIEC. Free assessment, automated evidence, audit-ready documentation.
Explore compliance frameworks:
Developer tools & integrations:
How AI AppSec uses Semgrep to detect prompt injection sinks, tool abuse, and AI-specific vulnerabilities in source code. 122 detectors, 79 security checks, with code examples.
How @haiec/openai and @haiec/anthropic wrap the official SDKs to capture model usage, token counts, and costs automatically. The instrumentation pattern and privacy considerations.
Learn what AI vendor public security disclosures entail and how they impact AI security and compliance professionals.
When I started building AI AppSec, I had a choice: write a custom AST parser for AI framework patterns, or use an existing static analysis engine. I spent a week prototyping both. The custom parser could detect a LangChain tool abuse pattern in 200 lines of Python. The Semgrep rule could detect the same pattern in 15 lines of YAML. The Semgrep rule also worked for TypeScript, JavaScript, JSX, and TSX without any changes. The custom parser worked for Python only.
I chose Semgrep. This article explains why, what the tradeoffs are, and when you might choose differently.
Custom AST parser: you write code that parses source files into an abstract syntax tree, traverses the tree, and matches patterns. You control every step. You support exactly the languages and frameworks you write parsers for.
Semgrep: you write rules in a declarative pattern language. Semgrep parses the source code, matches your patterns, and reports findings. Semgrep supports 30+ languages. You write rules, not parsers.
AI AppSec uses Semgrep 1.173.0 as its execution engine with a bundled rulepack of 122 detectors and 79 security checks. The rules are written in Semgrep's pattern language. The package installs Semgrep as an external dependency and runs the rules against your source code.
AI applications are not single-language. A typical AI project has Python for model training, TypeScript for the API server, JavaScript for the frontend, and maybe some Go for infrastructure. A custom parser needs a separate implementation for each language. Semgrep supports all of them with the same rule syntax.
AI AppSec supports Python, TypeScript, JavaScript, JSX, and TSX. If I had written custom parsers, that would be five parser implementations. With Semgrep, it is one rulepack.
Semgrep's pattern language is designed for security rules. It supports:
Writing these features from scratch in a custom parser would take months. Semgrep has had them for years.
Semgrep runs in GitHub Actions, GitLab CI, CircleCI, Jenkins, and any CI system that can run a CLI tool. It outputs SARIF 2.1.0 for GitHub Code Scanning integration. It has a GitHub App for pull request comments.
AI AppSec inherits all of this. You run ai-appsec scan ./src --format sarif --output results.sarif in your CI pipeline and the results show up in GitHub Security tab.
Semgrep has a community registry of thousands of rules. AI AppSec's rulepack is separate (it is a bundled Public Core rulepack focused on AI patterns), but the ecosystem means the engine is well-maintained, well-documented, and well-tested.
AI AppSec requires Semgrep 1.173.0 installed separately. The exact version is enforced because Semgrep rule syntax can change between versions. This means:
npm install -g ai-appsec
pip install semgrep==1.173.0
Two install commands instead of one. The Semgrep binary is approximately 50 MB. For CI pipelines, this adds about 10 seconds to the setup time.
A custom parser would be a single install with no external dependency. The tradeoff is that you maintain the parser.
Semgrep's pattern language is powerful but not Turing-complete. There are patterns it cannot express:
OpenAIClient calling chat.completions.create", Semgrep can do it, but it may produce false positives if the variable name matches but the type does notFor AI AppSec's use case (matching AI framework patterns, detecting prompt injection sinks, finding tool abuse), Semgrep's expressiveness is sufficient. The 122 detectors and 79 checks are all expressible as Semgrep rules.
AI AppSec enforces Semgrep 1.173.0. If you already use Semgrep in your CI pipeline at a different version, you have a conflict. You need to either upgrade your existing Semgrep to 1.173.0 or run AI AppSec in a separate CI step with its own Semgrep version.
This is a real inconvenience. The version enforcement exists because Semgrep rule syntax has changed between versions in ways that break existing rules. Pinning the version ensures the rulepack works as tested.
Here is how you would write a Semgrep rule for the LangChain SSRF pattern I described in the AI AppSec article. The vulnerability: a LangChain tool that fetches a URL from user input without validation.
rules:
- id: langchain-ssrf-via-tool-argument
pattern: |
@$DECORATOR
def $FUNC($URL: str) -> str:
...
requests.get($URL)
...
message: "LangChain tool accepts URL from input and fetches without validation. SSRF risk."
languages: [python]
severity: ERROR
metadata:
category: ssrf
cwe: "CWE-918"
framework: langchain
This rule matches any Python function decorated with @tool (or any decorator) that accepts a string parameter named $URL and calls requests.get($URL). The ... is Semgrep's wildcard — it matches any code between the function signature and the requests.get call.
When AI AppSec runs, it includes rules like this one (the actual rulepack has 122 detectors with more sophisticated patterns). The finding includes the rule ID, file path, line number, and the message.
Semgrep is the right choice for AI AppSec because:
A custom parser would be the right choice if:
For most AI security use cases, Semgrep is the pragmatic choice. The time you save by not writing parsers is time you spend writing rules — and rules are where the security knowledge lives.
AI AppSec's bundled rulepack covers these concern families:
| Family | Detectors | What it checks | |---|---|---| | Prompt injection | 18 | User input flowing into LLM context without sanitization | | Tool abuse | 24 | Tools with broad permissions, missing validation, command execution | | SSRF | 12 | Fetch tools without private IP filtering | | Secrets exposure | 15 | API keys in prompts, credentials in tool arguments | | Data leakage | 14 | Sensitive data flowing into LLM context or model output | | Insecure output handling | 11 | Model output used in dangerous sinks | | Missing input validation | 16 | AI endpoints without input validation | | Insecure deserialization | 12 | Model output parsed as executable code or SQL |
The rulepack is bundled with the package. You do not write your own rules or configure anything. If you want to write custom rules for application-specific patterns, you can add them as a separate Semgrep configuration alongside the AI AppSec rulepack.
AI AppSec is the SOURCE layer in the Developer Security family. It uses Semgrep to scan source code. It does not check tenant boundaries (that is MCP Tenant Isolation) or runtime model I/O (that is LLMVerify).
The choice of Semgrep as the engine is an implementation detail. The value is in the 122 detectors and 79 checks that catch AI-specific vulnerability patterns. Whether those patterns are implemented as Semgrep rules or custom parser logic does not change what they find.