eslint-plugin-vercel-ai-security 1.2.0 โ 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +110 -126
- package/package.json +9 -5
- package/src/rules/no-dynamic-system-prompt/index.d.ts +3 -1
- package/src/rules/no-hardcoded-api-keys/index.d.ts +3 -1
- package/src/rules/no-sensitive-in-prompt/index.d.ts +3 -1
- package/src/rules/no-system-prompt-leak/index.d.ts +3 -1
- package/src/rules/no-training-data-exposure/index.d.ts +3 -1
- package/src/rules/no-training-data-exposure/index.js +0 -1
- package/src/rules/no-unsafe-output-handling/index.d.ts +3 -1
- package/src/rules/require-abort-signal/index.d.ts +3 -1
- package/src/rules/require-audit-logging/index.d.ts +3 -1
- package/src/rules/require-embedding-validation/index.d.ts +3 -1
- package/src/rules/require-error-handling/index.d.ts +3 -1
- package/src/rules/require-max-steps/index.d.ts +3 -1
- package/src/rules/require-max-tokens/index.d.ts +3 -1
- package/src/rules/require-output-filtering/index.d.ts +3 -1
- package/src/rules/require-output-validation/index.d.ts +3 -1
- package/src/rules/require-rag-content-validation/index.d.ts +3 -1
- package/src/rules/require-request-timeout/index.d.ts +3 -1
- package/src/rules/require-tool-confirmation/index.d.ts +3 -1
- package/src/rules/require-tool-schema/index.d.ts +3 -1
- package/src/rules/require-validated-prompt/index.d.ts +3 -1
package/README.md
CHANGED
|
@@ -1,116 +1,40 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://eslint.interlace.tools" target="blank"><img src="https://eslint.interlace.tools/eslint-interlace-logo-light.svg" alt="ESLint Interlace Logo" width="120" /></a>
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
</
|
|
5
|
+
<p align="center">
|
|
6
|
+
Security rules for Vercel AI SDK usage (prompt injection, data handling).
|
|
7
|
+
</p>
|
|
6
8
|
|
|
7
|
-
>
|
|
9
|
+
<p align="center">
|
|
10
|
+
<a href="https://www.npmjs.com/package/eslint-plugin-vercel-ai-security" target="_blank"><img src="https://img.shields.io/npm/v/eslint-plugin-vercel-ai-security.svg" alt="NPM Version" /></a>
|
|
11
|
+
<a href="https://www.npmjs.com/package/eslint-plugin-vercel-ai-security" target="_blank"><img src="https://img.shields.io/npm/dm/eslint-plugin-vercel-ai-security.svg" alt="NPM Downloads" /></a>
|
|
12
|
+
<a href="https://opensource.org/licenses/MIT" target="_blank"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="Package License" /></a>
|
|
13
|
+
<a href="https://app.codecov.io/gh/ofri-peretz/eslint/components?components%5B0%5D=vercel-ai-security" target="_blank"><img src="https://codecov.io/gh/ofri-peretz/eslint/graph/badge.svg?component=vercel-ai-security" alt="Codecov" /></a>
|
|
14
|
+
<a href="https://github.com/ofri-peretz/eslint" target="_blank"><img src="https://img.shields.io/badge/Since-Dec_2025-blue?logo=rocket&logoColor=white" alt="Since Dec 2025" /></a>
|
|
15
|
+
</p>
|
|
8
16
|
|
|
9
|
-
|
|
17
|
+
## Description
|
|
10
18
|
|
|
11
|
-
|
|
12
|
-
[](https://www.npmjs.com/package/eslint-plugin-vercel-ai-security)
|
|
13
|
-
[](https://opensource.org/licenses/MIT)
|
|
14
|
-
[](https://app.codecov.io/gh/ofri-peretz/eslint/components?components%5B0%5D=vercel_ai_security)
|
|
15
|
-
[](https://owasp.org/www-project-top-10-for-large-language-model-applications/)
|
|
16
|
-
[](https://owasp.org)
|
|
17
|
-
[](https://github.com/ofri-peretz/eslint)
|
|
19
|
+
This plugin enforces security best practices for applications using the Vercel AI SDK, specifically targeting prompt injection and data handling vulnerabilities. It ensures that your AI integrations remain secure by validating inputs, outputs, and preventing common pitfalls associated with Large Language Models. By adopting these rules, you can confidently build AI-powered features while maintaining a robust security posture.
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
## ๐ก What you get
|
|
21
|
+
## Philosophy
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
- **LLM-optimized & MCP-ready:** Structured 2-line messages with CWE + OWASP + CVSS + concrete fixes so humans _and_ AI auto-fixers stay aligned.
|
|
25
|
-
- **Complete OWASP coverage:** 100% of OWASP LLM Top 10 2025 + 90% of OWASP Agentic Top 10 2026.
|
|
26
|
-
- **Tiered presets:** `recommended`, `strict`, `minimal` for fast policy rollout.
|
|
27
|
-
- **Zero false positives:** SDK-specific detection eliminates generic pattern matching noise.
|
|
28
|
-
|
|
29
|
-
---
|
|
23
|
+
**Interlace** fosters **strength through integration**. Instead of stacking isolated rules, we **interlace** security directly into your workflow to create a resilient fabric of code. We believe tools should **guide rather than gatekeep**, providing educational feedback that strengthens the developer with every interaction.
|
|
30
24
|
|
|
31
|
-
##
|
|
25
|
+
## Getting Started
|
|
32
26
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
---
|
|
41
|
-
|
|
42
|
-
## ๐ฆ Installation
|
|
27
|
+
- To check out the [guide](https://eslint.interlace.tools/docs/vercel-ai-security), visit [eslint.interlace.tools](https://eslint.interlace.tools). ๐
|
|
28
|
+
- ่ฆๆฅ็ไธญๆ [ๆๅ](https://eslint.interlace.tools/docs/vercel-ai-security), ่ฏท่ฎฟ้ฎ [eslint.interlace.tools](https://eslint.interlace.tools). ๐
|
|
29
|
+
- [๊ฐ์ด๋](https://eslint.interlace.tools/docs/vercel-ai-security) ๋ฌธ์๋ [eslint.interlace.tools](https://eslint.interlace.tools)์์ ํ์ธํ์ค ์ ์์ต๋๋ค. ๐
|
|
30
|
+
- [ใฌใคใ](https://eslint.interlace.tools/docs/vercel-ai-security)ใฏ [eslint.interlace.tools](https://eslint.interlace.tools)ใงใ็ขบ่ชใใ ใใใ ๐
|
|
31
|
+
- Para ver la [guรญa](https://eslint.interlace.tools/docs/vercel-ai-security), visita [eslint.interlace.tools](https://eslint.interlace.tools). ๐
|
|
32
|
+
- ููุงุทูุงุน ุนูู [ุงูุฏููู](https://eslint.interlace.tools/docs/vercel-ai-security)ุ ูู
ุจุฒูุงุฑุฉ [eslint.interlace.tools](https://eslint.interlace.tools). ๐
|
|
43
33
|
|
|
44
34
|
```bash
|
|
45
|
-
# npm
|
|
46
35
|
npm install eslint-plugin-vercel-ai-security --save-dev
|
|
47
|
-
|
|
48
|
-
# pnpm
|
|
49
|
-
pnpm add -D eslint-plugin-vercel-ai-security
|
|
50
|
-
|
|
51
|
-
# yarn
|
|
52
|
-
yarn add -D eslint-plugin-vercel-ai-security
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
---
|
|
56
|
-
|
|
57
|
-
## ๐ Quick Start
|
|
58
|
-
|
|
59
|
-
### ESLint Flat Config (Recommended)
|
|
60
|
-
|
|
61
|
-
```javascript
|
|
62
|
-
// eslint.config.js
|
|
63
|
-
import vercelAISecurity from 'eslint-plugin-vercel-ai-security';
|
|
64
|
-
|
|
65
|
-
export default [vercelAISecurity.configs.recommended];
|
|
66
36
|
```
|
|
67
37
|
|
|
68
|
-
### Available Presets
|
|
69
|
-
|
|
70
|
-
| Preset | Description |
|
|
71
|
-
| ----------------- | ----------------------------------------------------------------------- |
|
|
72
|
-
| **`recommended`** | Balanced security: Critical rules as errors, high-priority as warnings. |
|
|
73
|
-
| **`strict`** | Maximum security: All rules enabled as errors for production. |
|
|
74
|
-
| **`minimal`** | Gradual adoption: Only the 2 most critical rules. |
|
|
75
|
-
|
|
76
|
-
---
|
|
77
|
-
|
|
78
|
-
## ๐ Complete Rules Reference (19 Rules)
|
|
79
|
-
|
|
80
|
-
๐ผ = Set in `recommended` | โ ๏ธ = Warns in `recommended` | ๐ก = Suggestions
|
|
81
|
-
|
|
82
|
-
### ๐ก๏ธ OWASP LLM Top 10 2025 (10/10 โ
)
|
|
83
|
-
|
|
84
|
-
| Rule | CWE | OWASP | CVSS | Description | ๐ผ | โ ๏ธ | ๐ง | ๐ก | ๐ซ |
|
|
85
|
-
| :--- | :---: | :---: | :---: | :--- | :---: | :---: | :---: | :---: | :---: |
|
|
86
|
-
| [require-validated-prompt](./docs/rules/require-validated-prompt.md) | CWE-74 | LLM01 | 9.0 | Prevent prompt injection via input validation | ๐ผ | | | | |
|
|
87
|
-
| [no-sensitive-in-prompt](./docs/rules/no-sensitive-in-prompt.md) | CWE-200 | LLM02 | 8.0 | Prevent sensitive data (secrets, PII) in prompts | ๐ผ | | | | |
|
|
88
|
-
| [no-training-data-exposure](./docs/rules/no-training-data-exposure.md) | CWE-359 | LLM03 | 7.0 | Prevent user data exposure to training endpoints | | โ ๏ธ | | | |
|
|
89
|
-
| [require-request-timeout](./docs/rules/require-request-timeout.md) | CWE-400 | LLM04 | 5.0 | Require timeouts for AI calls to prevent DoS | | โ ๏ธ | | | |
|
|
90
|
-
| [no-unsafe-output-handling](./docs/rules/no-unsafe-output-handling.md) | CWE-94 | LLM05 | 9.8 | Prevent unsafe use of AI output (eval, SQL, HTML) | ๐ผ | | | | |
|
|
91
|
-
| [require-tool-confirmation](./docs/rules/require-tool-confirmation.md) | CWE-862 | LLM06 | 7.0 | Require confirmation for destructive tool usage | ๐ผ | | | | |
|
|
92
|
-
| [no-system-prompt-leak](./docs/rules/no-system-prompt-leak.md) | CWE-200 | LLM07 | 7.5 | Prevent system prompt leakage in responses | ๐ผ | | | | |
|
|
93
|
-
| [require-embedding-validation](./docs/rules/require-embedding-validation.md) | CWE-20 | LLM08 | 5.5 | Validate embeddings before storage/search | | | | ๐ก | |
|
|
94
|
-
| [require-output-validation](./docs/rules/require-output-validation.md) | CWE-707 | LLM09 | 5.0 | Validate AI output before display to prevent misinformation | | | | ๐ก | |
|
|
95
|
-
| [require-max-tokens](./docs/rules/require-max-tokens.md) | CWE-770 | LLM10 | 6.5 | Require `maxTokens` limit to prevent exhaustion | | โ ๏ธ | | | |
|
|
96
|
-
| [require-max-steps](./docs/rules/require-max-steps.md) | CWE-834 | LLM10 | 6.5 | Require `maxSteps` for multi-step tools | | โ ๏ธ | | | |
|
|
97
|
-
| [require-abort-signal](./docs/rules/require-abort-signal.md) | CWE-404 | LLM10 | 4.0 | Require `abortSignal` for cancellable streams | | | | ๐ก | |
|
|
98
|
-
### ๐ค OWASP Agentic Top 10 2026 (9/10 โ
)
|
|
99
|
-
|
|
100
|
-
| Rule | CWE | OWASP | CVSS | Description | ๐ผ | โ ๏ธ | ๐ง | ๐ก | ๐ซ |
|
|
101
|
-
| :--- | :---: | :---: | :---: | :--- | :---: | :---: | :---: | :---: | :---: |
|
|
102
|
-
| [no-dynamic-system-prompt](./docs/rules/no-dynamic-system-prompt.md) | CWE-74 | ASI01 | 8.0 | Prevent dynamic system prompts (Agent Confusion) | ๐ผ | | | | |
|
|
103
|
-
| [require-tool-schema](./docs/rules/require-tool-schema.md) | CWE-20 | ASI02 | 7.5 | Require Zod schemas for all tool parameters | | โ ๏ธ | | | |
|
|
104
|
-
| [no-hardcoded-api-keys](./docs/rules/no-hardcoded-api-keys.md) | CWE-798 | ASI03 | 8.5 | Prevent hardcoded API keys in configuration | ๐ผ | | | | |
|
|
105
|
-
| [require-output-filtering](./docs/rules/require-output-filtering.md) | CWE-200 | ASI04 | 6.5 | Filter sensitive data returned by tools | | โ ๏ธ | | | |
|
|
106
|
-
| [no-unsafe-output-handling](./docs/rules/no-unsafe-output-handling.md) | CWE-94 | ASI05 | 9.8 | Prevent unexpected code execution from AI output | ๐ผ | | | | |
|
|
107
|
-
| **ASI06: Memory Corruption** | - | ASI06 | - | _N/A (TypeScript/JS is memory-safe)_ | - | - | | - | |
|
|
108
|
-
| [require-rag-content-validation](./docs/rules/require-rag-content-validation.md) | CWE-74 | ASI07 | 6.0 | Validate RAG content before use in prompts | | โ ๏ธ | | | |
|
|
109
|
-
| [require-error-handling](./docs/rules/require-error-handling.md) | CWE-755 | ASI08 | 5.0 | Require error handling to prevent cascading failures | | | | ๐ก | |
|
|
110
|
-
| [require-tool-confirmation](./docs/rules/require-tool-confirmation.md) | CWE-862 | ASI09 | 7.0 | Require human-in-the-loop for sensitive actions | ๐ผ | | | | |
|
|
111
|
-
| [require-audit-logging](./docs/rules/require-audit-logging.md) | CWE-778 | ASI10 | 4.0 | Suggest audit logging for AI operations | | | | ๐ก | |
|
|
112
|
-
---
|
|
113
|
-
|
|
114
38
|
## ๐ง Supported AI SDK Functions
|
|
115
39
|
|
|
116
40
|
| Function | Full Coverage |
|
|
@@ -124,6 +48,16 @@ export default [vercelAISecurity.configs.recommended];
|
|
|
124
48
|
|
|
125
49
|
---
|
|
126
50
|
|
|
51
|
+
## โ๏ธ Configuration Presets
|
|
52
|
+
|
|
53
|
+
| Preset | Description |
|
|
54
|
+
| :------------ | :--------------------------------------- |
|
|
55
|
+
| `recommended` | Balanced security (7 errors, 7 warnings) |
|
|
56
|
+
| `strict` | Maximum security (17 errors, 2 warnings) |
|
|
57
|
+
| `minimal` | Minimal config |
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
127
61
|
## ๐ Test Coverage
|
|
128
62
|
|
|
129
63
|
| Metric | Coverage |
|
|
@@ -144,36 +78,51 @@ All rule messages follow a structured format optimized for AI coding assistants:
|
|
|
144
78
|
Fix: Validate input before use | https://owasp.org/...
|
|
145
79
|
```
|
|
146
80
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
##
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
|
154
|
-
|
|
|
155
|
-
|
|
|
81
|
+
By providing this structured context (CWE, OWASP, Fix), we enable AI tools to **reason** about the security flaw rather than hallucinating. This allows Copilot/Cursor to suggest the _exact_ correct fix immediately.
|
|
82
|
+
|
|
83
|
+
## Rules
|
|
84
|
+
|
|
85
|
+
**Legend**
|
|
86
|
+
|
|
87
|
+
| Icon | Description |
|
|
88
|
+
| :--: | :----------------------------------------------------------------- |
|
|
89
|
+
| ๐ผ | **Recommended**: Included in the recommended preset. |
|
|
90
|
+
| โ ๏ธ | **Warns**: Set towarn in recommended preset. |
|
|
91
|
+
| ๐ง | **Auto-fixable**: Automatically fixable by the `--fix` CLI option. |
|
|
92
|
+
| ๐ก | **Suggestions**: Providing code suggestions in IDE. |
|
|
93
|
+
| ๐ซ | **Deprecated**: This rule is deprecated. |
|
|
94
|
+
|
|
95
|
+
| Rule | CWE | OWASP | CVSS | Description | ๐ผ | โ ๏ธ | ๐ง | ๐ก | ๐ซ |
|
|
96
|
+
| :---------------------------------------------------------------------------------------------------------------------------- | :-----: | :---: | :--: | :------------------------------------------------------------------------------- | :-: | :-: | :-: | :-: | :-: |
|
|
97
|
+
| [require-validated-prompt](https://eslint.interlace.tools/docs/vercel-ai-security/rules/require-validated-prompt) | CWE-74 | | 9.0 | [require-validated-prompt](./docs/rules/require-validated-prompt.md) | ๐ผ | | | | |
|
|
98
|
+
| [no-sensitive-in-prompt](https://eslint.interlace.tools/docs/vercel-ai-security/rules/no-sensitive-in-prompt) | CWE-200 | | 8.0 | [no-sensitive-in-prompt](./docs/rules/no-sensitive-in-prompt.md) | ๐ผ | | | | |
|
|
99
|
+
| [no-training-data-exposure](https://eslint.interlace.tools/docs/vercel-ai-security/rules/no-training-data-exposure) | CWE-359 | | 7.0 | [no-training-data-exposure](./docs/rules/no-training-data-exposure.md) | ๐ผ | โ ๏ธ | | | |
|
|
100
|
+
| [require-request-timeout](https://eslint.interlace.tools/docs/vercel-ai-security/rules/require-request-timeout) | CWE-400 | | 5.0 | [require-request-timeout](./docs/rules/require-request-timeout.md) | ๐ผ | โ ๏ธ | | | |
|
|
101
|
+
| [no-unsafe-output-handling](https://eslint.interlace.tools/docs/vercel-ai-security/rules/no-unsafe-output-handling) | CWE-94 | | 9.8 | [no-unsafe-output-handling](./docs/rules/no-unsafe-output-handling.md) | ๐ผ | | | | |
|
|
102
|
+
| [require-tool-confirmation](https://eslint.interlace.tools/docs/vercel-ai-security/rules/require-tool-confirmation) | CWE-862 | | 7.0 | [require-tool-confirmation](./docs/rules/require-tool-confirmation.md) | ๐ผ | | | | |
|
|
103
|
+
| [no-system-prompt-leak](https://eslint.interlace.tools/docs/vercel-ai-security/rules/no-system-prompt-leak) | CWE-200 | | 7.5 | [no-system-prompt-leak](./docs/rules/no-system-prompt-leak.md) | ๐ผ | | | | |
|
|
104
|
+
| [require-embedding-validation](https://eslint.interlace.tools/docs/vercel-ai-security/rules/require-embedding-validation) | CWE-20 | | 5.5 | [require-embedding-validation](./docs/rules/require-embedding-validation.md) | | | | ๐ก | |
|
|
105
|
+
| [require-output-validation](https://eslint.interlace.tools/docs/vercel-ai-security/rules/require-output-validation) | CWE-707 | | 5.0 | [require-output-validation](./docs/rules/require-output-validation.md) | | | | ๐ก | |
|
|
106
|
+
| [require-max-tokens](https://eslint.interlace.tools/docs/vercel-ai-security/rules/require-max-tokens) | CWE-770 | | 6.5 | [require-max-tokens](./docs/rules/require-max-tokens.md) | ๐ผ | โ ๏ธ | | | |
|
|
107
|
+
| [require-max-steps](https://eslint.interlace.tools/docs/vercel-ai-security/rules/require-max-steps) | CWE-834 | | 6.5 | [require-max-steps](./docs/rules/require-max-steps.md) | ๐ผ | โ ๏ธ | | | |
|
|
108
|
+
| [require-abort-signal](https://eslint.interlace.tools/docs/vercel-ai-security/rules/require-abort-signal) | CWE-404 | | 4.0 | [require-abort-signal](./docs/rules/require-abort-signal.md) | | | | ๐ก | |
|
|
109
|
+
| [no-dynamic-system-prompt](https://eslint.interlace.tools/docs/vercel-ai-security/rules/no-dynamic-system-prompt) | CWE-74 | | 8.0 | [no-dynamic-system-prompt](./docs/rules/no-dynamic-system-prompt.md) | ๐ผ | | | | |
|
|
110
|
+
| [require-tool-schema](https://eslint.interlace.tools/docs/vercel-ai-security/rules/require-tool-schema) | CWE-20 | | 7.5 | [require-tool-schema](./docs/rules/require-tool-schema.md) | ๐ผ | โ ๏ธ | | | |
|
|
111
|
+
| [no-hardcoded-api-keys](https://eslint.interlace.tools/docs/vercel-ai-security/rules/no-hardcoded-api-keys) | CWE-798 | | 8.5 | [no-hardcoded-api-keys](./docs/rules/no-hardcoded-api-keys.md) | ๐ผ | | | | |
|
|
112
|
+
| [require-output-filtering](https://eslint.interlace.tools/docs/vercel-ai-security/rules/require-output-filtering) | CWE-200 | | 6.5 | [require-output-filtering](./docs/rules/require-output-filtering.md) | ๐ผ | โ ๏ธ | | | |
|
|
113
|
+
| [require-rag-content-validation](https://eslint.interlace.tools/docs/vercel-ai-security/rules/require-rag-content-validation) | CWE-74 | | 6.0 | [require-rag-content-validation](./docs/rules/require-rag-content-validation.md) | ๐ผ | โ ๏ธ | | | |
|
|
114
|
+
| [require-error-handling](https://eslint.interlace.tools/docs/vercel-ai-security/rules/require-error-handling) | CWE-755 | | 5.0 | [require-error-handling](./docs/rules/require-error-handling.md) | | | | ๐ก | |
|
|
115
|
+
| [require-audit-logging](https://eslint.interlace.tools/docs/vercel-ai-security/rules/require-audit-logging) | CWE-778 | | 4.0 | [require-audit-logging](./docs/rules/require-audit-logging.md) | | | | ๐ก | |
|
|
156
116
|
|
|
157
117
|
---
|
|
158
118
|
|
|
159
|
-
##
|
|
160
|
-
|
|
161
|
-
Part of the **Interlace ESLint Ecosystem** โ AI-native security plugins with LLM-optimized error messages:
|
|
162
|
-
|
|
163
|
-
| Plugin | Downloads | Description | Rule | CWE | OWASP | CVSS | Description | ๐ผ | โ ๏ธ | ๐ง | ๐ก | ๐ซ |
|
|
164
|
-
| :--- | :---: | :---: | :---: | :--- | :---: | :---: | :---: | :---: | :---: |
|
|
165
|
-
| [`eslint-plugin-secure-coding`](https://www.npmjs.com/package/eslint-plugin-secure-coding) | | | | | | | | | |
|
|
166
|
-
| [`eslint-plugin-jwt`](https://www.npmjs.com/package/eslint-plugin-jwt) | | | | | | | | | |
|
|
167
|
-
| [`eslint-plugin-crypto`](https://www.npmjs.com/package/eslint-plugin-crypto) | | | | | | | | | |
|
|
168
|
-
| [`eslint-plugin-pg`](https://www.npmjs.com/package/eslint-plugin-pg) | | | | | | | | | |
|
|
169
|
-
| [`eslint-plugin-express-security`](https://www.npmjs.com/package/eslint-plugin-express-security) | | | | | | | | | |
|
|
170
|
-
| [`eslint-plugin-nestjs-security`](https://www.npmjs.com/package/eslint-plugin-nestjs-security) | | | | | | | | | |
|
|
171
|
-
| [`eslint-plugin-lambda-security`](https://www.npmjs.com/package/eslint-plugin-lambda-security) | | | | | | | | | |
|
|
172
|
-
| [`eslint-plugin-browser-security`](https://www.npmjs.com/package/eslint-plugin-browser-security) | | | | | | | | | |
|
|
173
|
-
| [`eslint-plugin-import-next`](https://www.npmjs.com/package/eslint-plugin-import-next) | | | | | | | | | |
|
|
174
|
-
## ๐ License
|
|
119
|
+
## ๐ฆ Compatibility
|
|
175
120
|
|
|
176
|
-
|
|
121
|
+
| Package | Version |
|
|
122
|
+
| -------------------- | --------------------------------------------------------------------------------------------------------- |
|
|
123
|
+
| `ai` (Vercel AI SDK) | [](https://www.npmjs.com/package/ai) |
|
|
124
|
+
| ESLint | [](https://www.npmjs.com/package/eslint) |
|
|
125
|
+
| Node.js | [](https://nodejs.org/) |
|
|
177
126
|
|
|
178
127
|
---
|
|
179
128
|
|
|
@@ -197,3 +146,38 @@ await generateText({ prompt: internalPrompt });
|
|
|
197
146
|
### Why is ASI06 (Memory Corruption) not covered?
|
|
198
147
|
|
|
199
148
|
TypeScript/JavaScript are memory-safe languages. Memory corruption vulnerabilities (buffer overflows, use-after-free, etc.) are not possible in these environments.
|
|
149
|
+
|
|
150
|
+
## ๐ Supported Libraries
|
|
151
|
+
|
|
152
|
+
| Library | npm | Downloads | Detection |
|
|
153
|
+
| -------------------- | ------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------ |
|
|
154
|
+
| `ai` (Vercel AI SDK) | [](https://www.npmjs.com/package/ai) | [](https://www.npmjs.com/package/ai) | Prompt Injection, Data Leakage |
|
|
155
|
+
|
|
156
|
+
## ๐ Related ESLint Plugins
|
|
157
|
+
|
|
158
|
+
Part of the **Interlace ESLint Ecosystem** โ AI-native security plugins with LLM-optimized error messages:
|
|
159
|
+
|
|
160
|
+
| Plugin | Downloads | Description |
|
|
161
|
+
| :--------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------ |
|
|
162
|
+
| [`eslint-plugin-secure-coding`](https://www.npmjs.com/package/eslint-plugin-secure-coding) | [](https://www.npmjs.com/package/eslint-plugin-secure-coding) | General security rules & OWASP guidelines. |
|
|
163
|
+
| [`eslint-plugin-pg`](https://www.npmjs.com/package/eslint-plugin-pg) | [](https://www.npmjs.com/package/eslint-plugin-pg) | PostgreSQL security & best practices. |
|
|
164
|
+
| [`eslint-plugin-crypto`](https://www.npmjs.com/package/eslint-plugin-crypto) | [](https://www.npmjs.com/package/eslint-plugin-crypto) | NodeJS Cryptography security rules. |
|
|
165
|
+
| [`eslint-plugin-jwt`](https://www.npmjs.com/package/eslint-plugin-jwt) | [](https://www.npmjs.com/package/eslint-plugin-jwt) | JWT security & best practices. |
|
|
166
|
+
| [`eslint-plugin-browser-security`](https://www.npmjs.com/package/eslint-plugin-browser-security) | [](https://www.npmjs.com/package/eslint-plugin-browser-security) | Browser-specific security & XSS prevention. |
|
|
167
|
+
| [`eslint-plugin-vercel-ai-security`](https://www.npmjs.com/package/eslint-plugin-vercel-ai-security) | [](https://www.npmjs.com/package/eslint-plugin-vercel-ai-security) | Vercel AI SDK security rules. |
|
|
168
|
+
| [`eslint-plugin-express-security`](https://www.npmjs.com/package/eslint-plugin-express-security) | [](https://www.npmjs.com/package/eslint-plugin-express-security) | Express.js security hardening rules. |
|
|
169
|
+
| [`eslint-plugin-lambda-security`](https://www.npmjs.com/package/eslint-plugin-lambda-security) | [](https://www.npmjs.com/package/eslint-plugin-lambda-security) | AWS Lambda security best practices. |
|
|
170
|
+
| [`eslint-plugin-nestjs-security`](https://www.npmjs.com/package/eslint-plugin-nestjs-security) | [](https://www.npmjs.com/package/eslint-plugin-nestjs-security) | NestJS security rules & patterns. |
|
|
171
|
+
| [`eslint-plugin-import-next`](https://www.npmjs.com/package/eslint-plugin-import-next) | [](https://www.npmjs.com/package/eslint-plugin-import-next) | Next-gen import sorting & architecture. |
|
|
172
|
+
|
|
173
|
+
## ๐ License
|
|
174
|
+
|
|
175
|
+
MIT ยฉ [Ofri Peretz](https://github.com/ofri-peretz)
|
|
176
|
+
|
|
177
|
+
<p align="center">
|
|
178
|
+
<a href="https://eslint.interlace.tools/docs/vercel-ai-security"><img src="https://eslint.interlace.tools/images/og-ai-security.png" alt="ESLint Interlace Plugin" width="300" /></a>
|
|
179
|
+
</p>
|
|
180
|
+
|
|
181
|
+
<p align="center">
|
|
182
|
+
<a href="https://eslint.interlace.tools/docs/vercel-ai-security"><img src="https://eslint.interlace.tools/images/og-vercel-ai-security.png" alt="ESLint Interlace Plugin" width="300" /></a>
|
|
183
|
+
</p>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-vercel-ai-security",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Security-focused ESLint plugin for Vercel AI SDK. SDK-aware rules for generateText, streamText, tools, and streaming patterns with full type knowledge.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"eslint",
|
|
42
42
|
"eslint-plugin",
|
|
43
43
|
"eslintplugin",
|
|
44
|
+
"interlace-security",
|
|
44
45
|
"security",
|
|
45
46
|
"vercel",
|
|
46
47
|
"vercel-ai",
|
|
@@ -63,12 +64,15 @@
|
|
|
63
64
|
"engines": {
|
|
64
65
|
"node": ">=18.0.0"
|
|
65
66
|
},
|
|
66
|
-
"peerDependencies": {
|
|
67
|
-
|
|
67
|
+
"peerDependencies": {},
|
|
68
|
+
"peerDependenciesMeta": {
|
|
69
|
+
"ai": {
|
|
70
|
+
"optional": true
|
|
71
|
+
}
|
|
68
72
|
},
|
|
69
73
|
"dependencies": {
|
|
70
|
-
"
|
|
71
|
-
"
|
|
74
|
+
"tslib": "^2.3.0",
|
|
75
|
+
"@interlace/eslint-devkit": "^1.2.1"
|
|
72
76
|
},
|
|
73
77
|
"devDependencies": {
|
|
74
78
|
"@ai-sdk/openai": "^2.0.86",
|
|
@@ -8,5 +8,7 @@ export interface Options {
|
|
|
8
8
|
allowStaticTemplates?: boolean;
|
|
9
9
|
}
|
|
10
10
|
type RuleOptions = [Options?];
|
|
11
|
-
export declare const noDynamicSystemPrompt: import("@typescript-eslint/utils/ts-eslint").RuleModule<"dynamicSystemPrompt", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener
|
|
11
|
+
export declare const noDynamicSystemPrompt: import("@typescript-eslint/utils/ts-eslint").RuleModule<"dynamicSystemPrompt", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
12
|
+
name: string;
|
|
13
|
+
};
|
|
12
14
|
export {};
|
|
@@ -8,5 +8,7 @@ export interface Options {
|
|
|
8
8
|
apiKeyPatterns?: string[];
|
|
9
9
|
}
|
|
10
10
|
type RuleOptions = [Options?];
|
|
11
|
-
export declare const noHardcodedApiKeys: import("@typescript-eslint/utils/ts-eslint").RuleModule<"hardcodedApiKey", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener
|
|
11
|
+
export declare const noHardcodedApiKeys: import("@typescript-eslint/utils/ts-eslint").RuleModule<"hardcodedApiKey", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
12
|
+
name: string;
|
|
13
|
+
};
|
|
12
14
|
export {};
|
|
@@ -8,5 +8,7 @@ export interface Options {
|
|
|
8
8
|
sensitivePatterns?: string[];
|
|
9
9
|
}
|
|
10
10
|
type RuleOptions = [Options?];
|
|
11
|
-
export declare const noSensitiveInPrompt: import("@typescript-eslint/utils/ts-eslint").RuleModule<"sensitiveInPrompt", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener
|
|
11
|
+
export declare const noSensitiveInPrompt: import("@typescript-eslint/utils/ts-eslint").RuleModule<"sensitiveInPrompt", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
12
|
+
name: string;
|
|
13
|
+
};
|
|
12
14
|
export {};
|
|
@@ -8,5 +8,7 @@ export interface Options {
|
|
|
8
8
|
systemPromptPatterns?: string[];
|
|
9
9
|
}
|
|
10
10
|
type RuleOptions = [Options?];
|
|
11
|
-
export declare const noSystemPromptLeak: import("@typescript-eslint/utils/ts-eslint").RuleModule<"systemPromptLeak", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener
|
|
11
|
+
export declare const noSystemPromptLeak: import("@typescript-eslint/utils/ts-eslint").RuleModule<"systemPromptLeak", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
12
|
+
name: string;
|
|
13
|
+
};
|
|
12
14
|
export {};
|
|
@@ -8,5 +8,7 @@ export interface Options {
|
|
|
8
8
|
trainingPatterns?: string[];
|
|
9
9
|
}
|
|
10
10
|
type RuleOptions = [Options?];
|
|
11
|
-
export declare const noTrainingDataExposure: import("@typescript-eslint/utils/ts-eslint").RuleModule<"trainingDataExposure", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener
|
|
11
|
+
export declare const noTrainingDataExposure: import("@typescript-eslint/utils/ts-eslint").RuleModule<"trainingDataExposure", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
12
|
+
name: string;
|
|
13
|
+
};
|
|
12
14
|
export {};
|
|
@@ -60,7 +60,6 @@ exports.noTrainingDataExposure = (0, eslint_devkit_1.createRule)({
|
|
|
60
60
|
const trainingPatterns = options.trainingPatterns ?? [
|
|
61
61
|
'train', 'training', 'finetune', 'feedback',
|
|
62
62
|
];
|
|
63
|
-
const sourceCode = context.sourceCode || context.getSourceCode();
|
|
64
63
|
/**
|
|
65
64
|
* Check if identifier suggests training
|
|
66
65
|
*/
|
|
@@ -9,5 +9,7 @@ export interface Options {
|
|
|
9
9
|
aiOutputPatterns?: string[];
|
|
10
10
|
}
|
|
11
11
|
type RuleOptions = [Options?];
|
|
12
|
-
export declare const noUnsafeOutputHandling: import("@typescript-eslint/utils/ts-eslint").RuleModule<MessageIds, RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener
|
|
12
|
+
export declare const noUnsafeOutputHandling: import("@typescript-eslint/utils/ts-eslint").RuleModule<MessageIds, RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
13
|
+
name: string;
|
|
14
|
+
};
|
|
13
15
|
export {};
|
|
@@ -8,5 +8,7 @@ export interface Options {
|
|
|
8
8
|
targetFunctions?: string[];
|
|
9
9
|
}
|
|
10
10
|
type RuleOptions = [Options?];
|
|
11
|
-
export declare const requireAbortSignal: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingAbortSignal", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener
|
|
11
|
+
export declare const requireAbortSignal: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingAbortSignal", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
12
|
+
name: string;
|
|
13
|
+
};
|
|
12
14
|
export {};
|
|
@@ -8,5 +8,7 @@ export interface Options {
|
|
|
8
8
|
allowInTests?: boolean;
|
|
9
9
|
}
|
|
10
10
|
type RuleOptions = [Options?];
|
|
11
|
-
export declare const requireAuditLogging: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingAuditLogging", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener
|
|
11
|
+
export declare const requireAuditLogging: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingAuditLogging", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
12
|
+
name: string;
|
|
13
|
+
};
|
|
12
14
|
export {};
|
|
@@ -10,5 +10,7 @@ export interface Options {
|
|
|
10
10
|
validatorFunctions?: string[];
|
|
11
11
|
}
|
|
12
12
|
type RuleOptions = [Options?];
|
|
13
|
-
export declare const requireEmbeddingValidation: import("@typescript-eslint/utils/ts-eslint").RuleModule<"unvalidatedEmbedding", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener
|
|
13
|
+
export declare const requireEmbeddingValidation: import("@typescript-eslint/utils/ts-eslint").RuleModule<"unvalidatedEmbedding", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
14
|
+
name: string;
|
|
15
|
+
};
|
|
14
16
|
export {};
|
|
@@ -8,5 +8,7 @@ export interface Options {
|
|
|
8
8
|
allowInTests?: boolean;
|
|
9
9
|
}
|
|
10
10
|
type RuleOptions = [Options?];
|
|
11
|
-
export declare const requireErrorHandling: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingErrorHandling", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener
|
|
11
|
+
export declare const requireErrorHandling: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingErrorHandling", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
12
|
+
name: string;
|
|
13
|
+
};
|
|
12
14
|
export {};
|
|
@@ -8,5 +8,7 @@ export interface Options {
|
|
|
8
8
|
suggestedMaxSteps?: number;
|
|
9
9
|
}
|
|
10
10
|
type RuleOptions = [Options?];
|
|
11
|
-
export declare const requireMaxSteps: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingMaxSteps", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener
|
|
11
|
+
export declare const requireMaxSteps: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingMaxSteps", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
12
|
+
name: string;
|
|
13
|
+
};
|
|
12
14
|
export {};
|
|
@@ -10,5 +10,7 @@ export interface Options {
|
|
|
10
10
|
targetFunctions?: string[];
|
|
11
11
|
}
|
|
12
12
|
type RuleOptions = [Options?];
|
|
13
|
-
export declare const requireMaxTokens: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingMaxTokens", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener
|
|
13
|
+
export declare const requireMaxTokens: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingMaxTokens", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
14
|
+
name: string;
|
|
15
|
+
};
|
|
14
16
|
export {};
|
|
@@ -10,5 +10,7 @@ export interface Options {
|
|
|
10
10
|
filterFunctions?: string[];
|
|
11
11
|
}
|
|
12
12
|
type RuleOptions = [Options?];
|
|
13
|
-
export declare const requireOutputFiltering: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingOutputFilter", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener
|
|
13
|
+
export declare const requireOutputFiltering: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingOutputFilter", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
14
|
+
name: string;
|
|
15
|
+
};
|
|
14
16
|
export {};
|
|
@@ -10,5 +10,7 @@ export interface Options {
|
|
|
10
10
|
validatorFunctions?: string[];
|
|
11
11
|
}
|
|
12
12
|
type RuleOptions = [Options?];
|
|
13
|
-
export declare const requireOutputValidation: import("@typescript-eslint/utils/ts-eslint").RuleModule<"unvalidatedOutput", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener
|
|
13
|
+
export declare const requireOutputValidation: import("@typescript-eslint/utils/ts-eslint").RuleModule<"unvalidatedOutput", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
14
|
+
name: string;
|
|
15
|
+
};
|
|
14
16
|
export {};
|
|
@@ -10,5 +10,7 @@ export interface Options {
|
|
|
10
10
|
validatorFunctions?: string[];
|
|
11
11
|
}
|
|
12
12
|
type RuleOptions = [Options?];
|
|
13
|
-
export declare const requireRagContentValidation: import("@typescript-eslint/utils/ts-eslint").RuleModule<"unsanitizedRagContent", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener
|
|
13
|
+
export declare const requireRagContentValidation: import("@typescript-eslint/utils/ts-eslint").RuleModule<"unsanitizedRagContent", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
14
|
+
name: string;
|
|
15
|
+
};
|
|
14
16
|
export {};
|
|
@@ -8,5 +8,7 @@ export interface Options {
|
|
|
8
8
|
allowInTests?: boolean;
|
|
9
9
|
}
|
|
10
10
|
type RuleOptions = [Options?];
|
|
11
|
-
export declare const requireRequestTimeout: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingTimeout", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener
|
|
11
|
+
export declare const requireRequestTimeout: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingTimeout", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
12
|
+
name: string;
|
|
13
|
+
};
|
|
12
14
|
export {};
|
|
@@ -8,5 +8,7 @@ export interface Options {
|
|
|
8
8
|
destructivePatterns?: string[];
|
|
9
9
|
}
|
|
10
10
|
type RuleOptions = [Options?];
|
|
11
|
-
export declare const requireToolConfirmation: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingConfirmation", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener
|
|
11
|
+
export declare const requireToolConfirmation: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingConfirmation", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
12
|
+
name: string;
|
|
13
|
+
};
|
|
12
14
|
export {};
|
|
@@ -9,5 +9,7 @@ export interface Options {
|
|
|
9
9
|
allowInTests?: boolean;
|
|
10
10
|
}
|
|
11
11
|
type RuleOptions = [Options?];
|
|
12
|
-
export declare const requireToolSchema: import("@typescript-eslint/utils/ts-eslint").RuleModule<MessageIds, RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener
|
|
12
|
+
export declare const requireToolSchema: import("@typescript-eslint/utils/ts-eslint").RuleModule<MessageIds, RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
13
|
+
name: string;
|
|
14
|
+
};
|
|
13
15
|
export {};
|
|
@@ -13,5 +13,7 @@ export interface Options {
|
|
|
13
13
|
allowInTests?: boolean;
|
|
14
14
|
}
|
|
15
15
|
type RuleOptions = [Options?];
|
|
16
|
-
export declare const requireValidatedPrompt: import("@typescript-eslint/utils/ts-eslint").RuleModule<MessageIds, RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener
|
|
16
|
+
export declare const requireValidatedPrompt: import("@typescript-eslint/utils/ts-eslint").RuleModule<MessageIds, RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
17
|
+
name: string;
|
|
18
|
+
};
|
|
17
19
|
export {};
|