Creating Semgrep Rules to Catch AI-Prompted API Misuse

AI-generated code often introduces subtle API misuse (wrong parameter order, missing authentication, incorrect HTTP methods, unchecked return values). This article shows a pragmatic workflow for writing Semgrep rules to surface those mistakes, validate them in CI, and keep rules maintainable as your prompts and libraries evolve.

1. Identify repeatable misuse patterns

Collect examples from PRs, code-gen runs, and incidents. Look for concrete, repeatable signals such as:

  • Calling a sensitive API with the wrong method (e.g., GET instead of POST).
  • Using a high-privilege parameter (e.g., admin=true) set from untrusted input.
  • Missing authorization header or using deprecated auth functions.
  • Assuming a function returns non-null without checking (leading to crashes).

2. Choose rule mode and scope

Start narrow: pick one language and one concrete anti-pattern. Use experimental/monitor mode in CI first to measure noise, then escalate to blocking when precision is high.

3. Write the Semgrep rule (basic pattern)

Use a YAML rule with a focused pattern and a clear message. Example: detect fetch/requests using GET when body is provided (JavaScript):

<pre>rules:
– id: fetch-get-with-body
message: “Avoid sending a body with GET requests; use POST/PUT instead.”
severity: MEDIUM
languages: [javascript,typescript]
patterns:
– pattern: fetch($URL, { method: “GET”, body: $BODY })
metadata:
category: api-misuse
</pre>

Keep patterns conservative (match concrete literals or well-scoped metavariables) to reduce false positives.

4. Add dataflow or metavariable checks for context

When misuse depends on how a value is constructed, use Semgrep’s metavariable-analysis or dataflow features. Example: flag when an auth token is read from an environment variable but later overwritten with user input.

5. Test rules locally and with unit tests

Use the Semgrep CLI and the Editor playground. Create test cases for true positives, false positives, and benign code. Put tests beside the rule YAML so CI can run them automatically.

6. Validate with live scans and measure signal

Run rules in monitor mode across recent branches and main. Triage findings to determine precision and recall. Track counts and common false-positive patterns to iteratively refine rules.

7. Integrate into CI and PR workflows

Start by commenting findings on PRs or opening issues. Once precision is acceptable, add the rule to blocking policies in CI. Example GitHub Actions step:

<pre>- uses: semgrep/semgrep-action@v1
with:
config: ./rules/ai-misuse.yml
</pre>

8. Maintain rules as prompts and libraries change

  • Review rules quarterly or after prompt/template changes.
  • Keep a short changelog and tests for each rule.
  • Use rule metadata to tag rules by prompt family or API library.

9. Handle exceptions and reduce developer friction

Provide clear remediation text in rule messages (what to change and why). Offer an easy path to mark a finding as a false positive (e.g., code comment or policy override) and feed those cases back into rule refinement.

10. When to escalate to CodeQL or hybrid checks

Use Semgrep for fast syntactic and light semantic checks; escalate to CodeQL or taint-tracking SAST when you need deeper interprocedural analysis (e.g., verifying auth flows end-to-end). Consider running both in CI for complementary coverage.

Following this practical lifecycle—identify, author, test, monitor, and maintain—lets teams catch the common API misuses introduced by AI-generated code while keeping noise low and developer velocity high.

Sources

Українська