eslint-plugin-vercel-ai-security 1.3.8 β 1.3.9
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/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## 1.3.9
|
|
2
|
+
|
|
3
|
+
### Patch Changes
|
|
4
|
+
|
|
5
|
+
- [#277](https://github.com/ofri-peretz/eslint/pull/277) [`d1ad332`](https://github.com/ofri-peretz/eslint/commit/d1ad332cc7366887482b288bcf65098d425501d0) Thanks [@ofri-peretz](https://github.com/ofri-peretz)! - Accept AI SDK v5+ idioms: `stopWhen` (e.g. `stopWhen: stepCountIs(5)`) now satisfies require-max-steps, and `maxOutputTokens` (v5 rename of `maxTokens`) satisfies require-max-tokens β fixing false positives on v5/v7 code.
|
|
6
|
+
|
|
1
7
|
## 1.3.8
|
|
2
8
|
|
|
3
9
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -136,8 +136,8 @@ See the [ESLint Version Support Policy](../../docs/ESLINT_VERSION_SUPPORT.md) fo
|
|
|
136
136
|
| [require-audit-logging](https://eslint.interlace.tools/docs/security/plugin-vercel-ai-security/rules/require-audit-logging?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-vercel-ai-security) | CWE-778 | | | This rule identifies AI SDK calls that aren't preceded by logging statements | π’ | | | | | |
|
|
137
137
|
| [require-embedding-validation](https://eslint.interlace.tools/docs/security/plugin-vercel-ai-security/rules/require-embedding-validation?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-vercel-ai-security) | CWE-20 | | | This rule identifies code patterns where embeddings are stored in vector databases without validation. | π’ | | | | | |
|
|
138
138
|
| [require-error-handling](https://eslint.interlace.tools/docs/security/plugin-vercel-ai-security/rules/require-error-handling?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-vercel-ai-security) | CWE-755 | | | This rule identifies AI SDK calls that aren't wrapped in try-catch blocks | π’ | | | | | |
|
|
139
|
-
| [require-max-steps](https://eslint.interlace.tools/docs/security/plugin-vercel-ai-security/rules/require-max-steps?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-vercel-ai-security) | CWE-834 | | | This rule identifies AI SDK calls that use tools but don't specify a
|
|
140
|
-
| [require-max-tokens](https://eslint.interlace.tools/docs/security/plugin-vercel-ai-security/rules/require-max-tokens?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-vercel-ai-security) | CWE-770 | | | This rule identifies AI SDK calls that don't specify a
|
|
139
|
+
| [require-max-steps](https://eslint.interlace.tools/docs/security/plugin-vercel-ai-security/rules/require-max-steps?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-vercel-ai-security) | CWE-834 | | | This rule identifies AI SDK calls that use tools but don't specify a step limit (maxSteps or stopWhen) | π’ | | | | | |
|
|
140
|
+
| [require-max-tokens](https://eslint.interlace.tools/docs/security/plugin-vercel-ai-security/rules/require-max-tokens?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-vercel-ai-security) | CWE-770 | | | This rule identifies AI SDK calls that don't specify a token limit (maxTokens or maxOutputTokens) | π’ | | | | | |
|
|
141
141
|
| [require-output-filtering](https://eslint.interlace.tools/docs/security/plugin-vercel-ai-security/rules/require-output-filtering?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-vercel-ai-security) | CWE-200 | | | This rule identifies tool execute functions that return raw data from data sources (databases, APIs, file sβ¦ | π’ | | | | | |
|
|
142
142
|
| [require-output-validation](https://eslint.interlace.tools/docs/security/plugin-vercel-ai-security/rules/require-output-validation?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-vercel-ai-security) | CWE-707 | | | This rule identifies code patterns where AI-generated output is displayed to users without validation or faβ¦ | π’ | | | | | |
|
|
143
143
|
| [require-rag-content-validation](https://eslint.interlace.tools/docs/security/plugin-vercel-ai-security/rules/require-rag-content-validation?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-vercel-ai-security) | CWE-74 | | | This rule identifies code patterns where content retrieved from vector stores or document retrieval systemsβ¦ | π’ | | | | | |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-vercel-ai-security",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.9",
|
|
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",
|
package/src/index.js
CHANGED
|
@@ -30,10 +30,10 @@ exports.requireMaxSteps = (0, eslint_devkit_1.createRule)({
|
|
|
30
30
|
cwe: 'CWE-834',
|
|
31
31
|
owasp: 'A05:2021',
|
|
32
32
|
cvss: 6.5,
|
|
33
|
-
description: '{{function}} with tools is missing
|
|
33
|
+
description: '{{function}} with tools is missing a step limit. Without a limit, tool calls can loop indefinitely.',
|
|
34
34
|
severity: 'MEDIUM',
|
|
35
35
|
compliance: ['SOC2'],
|
|
36
|
-
fix: 'Add
|
|
36
|
+
fix: 'Add a step limit: {{function}}({ ..., stopWhen: stepCountIs(5) }) (v5+) or maxSteps: 5 (v4)',
|
|
37
37
|
documentationLink: 'https://sdk.vercel.ai/docs/ai-sdk-core/tools-and-tool-calling#multi-step-calls-using-stopwhen',
|
|
38
38
|
}),
|
|
39
39
|
},
|
|
@@ -81,7 +81,7 @@ exports.requireMaxSteps = (0, eslint_devkit_1.createRule)({
|
|
|
81
81
|
// Only check for maxSteps if tools are present
|
|
82
82
|
if (!hasTools)
|
|
83
83
|
return;
|
|
84
|
-
// Check if
|
|
84
|
+
// Check if a step limit is present: maxSteps (v4) or stopWhen (v5+, e.g. stopWhen: stepCountIs(5))
|
|
85
85
|
const hasMaxSteps = optionsArg.properties.some(prop => {
|
|
86
86
|
if (prop.type !== 'Property')
|
|
87
87
|
return false;
|
|
@@ -90,7 +90,8 @@ exports.requireMaxSteps = (0, eslint_devkit_1.createRule)({
|
|
|
90
90
|
: prop.key.type === 'Literal'
|
|
91
91
|
? String(prop.key.value)
|
|
92
92
|
: null;
|
|
93
|
-
|
|
93
|
+
// ponytail: any stopWhen counts β statically proving it bounds steps (arrays, custom conditions) isn't worth it; documented FN
|
|
94
|
+
return keyName === 'maxSteps' || keyName === 'max_steps' || keyName === 'stopWhen';
|
|
94
95
|
});
|
|
95
96
|
if (!hasMaxSteps) {
|
|
96
97
|
context.report({
|
|
@@ -30,10 +30,10 @@ exports.requireMaxTokens = (0, eslint_devkit_1.createRule)({
|
|
|
30
30
|
cwe: 'CWE-770',
|
|
31
31
|
owasp: 'A05:2021',
|
|
32
32
|
cvss: 6.5,
|
|
33
|
-
description: '{{function}} call without
|
|
33
|
+
description: '{{function}} call without a token limit can lead to excessive resource consumption',
|
|
34
34
|
severity: 'MEDIUM',
|
|
35
35
|
compliance: ['SOC2'],
|
|
36
|
-
fix: 'Add
|
|
36
|
+
fix: 'Add a token limit: {{function}}({ maxOutputTokens: 4096, ... }) (v5+) or maxTokens (v4)',
|
|
37
37
|
documentationLink: 'https://sdk.vercel.ai/docs/ai-sdk-core/generating-text',
|
|
38
38
|
}),
|
|
39
39
|
},
|
|
@@ -81,7 +81,7 @@ exports.requireMaxTokens = (0, eslint_devkit_1.createRule)({
|
|
|
81
81
|
if (!optionsArg || optionsArg.type !== 'ObjectExpression') {
|
|
82
82
|
return;
|
|
83
83
|
}
|
|
84
|
-
// Check if
|
|
84
|
+
// Check if a token limit is present: maxTokens (v4) or maxOutputTokens (v5+ rename)
|
|
85
85
|
const hasMaxTokens = optionsArg.properties.some(prop => {
|
|
86
86
|
if (prop.type !== 'Property')
|
|
87
87
|
return false;
|
|
@@ -90,7 +90,7 @@ exports.requireMaxTokens = (0, eslint_devkit_1.createRule)({
|
|
|
90
90
|
: prop.key.type === 'Literal'
|
|
91
91
|
? String(prop.key.value)
|
|
92
92
|
: null;
|
|
93
|
-
return keyName === 'maxTokens' || keyName === 'max_tokens';
|
|
93
|
+
return keyName === 'maxTokens' || keyName === 'max_tokens' || keyName === 'maxOutputTokens';
|
|
94
94
|
});
|
|
95
95
|
if (!hasMaxTokens) {
|
|
96
96
|
context.report({
|