@juspay/neurolink 8.20.0 → 8.20.1
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
|
+
## [8.20.1](https://github.com/juspay/neurolink/compare/v8.20.0...v8.20.1) (2025-12-22)
|
|
2
|
+
|
|
3
|
+
### Bug Fixes
|
|
4
|
+
|
|
5
|
+
- **(Validation):** implement secure base64 validation with fail-fast checks ([f1b9b9c](https://github.com/juspay/neurolink/commit/f1b9b9c105db38ce439a5e69ff343b77b12be174)), closes [#277](https://github.com/juspay/neurolink/issues/277)
|
|
6
|
+
|
|
1
7
|
## [8.20.0](https://github.com/juspay/neurolink/compare/v8.19.1...v8.20.0) (2025-12-22)
|
|
2
8
|
|
|
3
9
|
### Features
|
|
@@ -157,6 +157,7 @@ export declare const imageUtils: {
|
|
|
157
157
|
createDataUri: (base64: string, mimeType?: string) => string;
|
|
158
158
|
/**
|
|
159
159
|
* Validate base64 string format
|
|
160
|
+
* Validates format BEFORE buffer allocation to prevent memory exhaustion
|
|
160
161
|
*/
|
|
161
162
|
isValidBase64: (str: string) => boolean;
|
|
162
163
|
/**
|
|
@@ -622,12 +622,40 @@ export const imageUtils = {
|
|
|
622
622
|
},
|
|
623
623
|
/**
|
|
624
624
|
* Validate base64 string format
|
|
625
|
+
* Validates format BEFORE buffer allocation to prevent memory exhaustion
|
|
625
626
|
*/
|
|
626
627
|
isValidBase64: (str) => {
|
|
627
628
|
try {
|
|
628
629
|
// Remove data URI prefix if present
|
|
629
630
|
const cleanBase64 = str.includes(",") ? str.split(",")[1] : str;
|
|
630
|
-
//
|
|
631
|
+
// Empty string check
|
|
632
|
+
if (!cleanBase64 || cleanBase64.length === 0) {
|
|
633
|
+
return false;
|
|
634
|
+
}
|
|
635
|
+
// 1. Validate character set FIRST (A-Z, a-z, 0-9, +, /, =)
|
|
636
|
+
// This prevents memory allocation for invalid input like "hello world"
|
|
637
|
+
const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/;
|
|
638
|
+
if (!base64Regex.test(cleanBase64)) {
|
|
639
|
+
return false;
|
|
640
|
+
}
|
|
641
|
+
// 2. Check length is multiple of 4
|
|
642
|
+
if (cleanBase64.length % 4 !== 0) {
|
|
643
|
+
return false;
|
|
644
|
+
}
|
|
645
|
+
// 3. Validate padding position (max 2 equals at end only)
|
|
646
|
+
const paddingIndex = cleanBase64.indexOf("=");
|
|
647
|
+
if (paddingIndex !== -1) {
|
|
648
|
+
// Padding must be at the end
|
|
649
|
+
if (paddingIndex < cleanBase64.length - 2) {
|
|
650
|
+
return false;
|
|
651
|
+
}
|
|
652
|
+
// No characters after padding
|
|
653
|
+
const afterPadding = cleanBase64.slice(paddingIndex);
|
|
654
|
+
if (!/^=+$/.test(afterPadding)) {
|
|
655
|
+
return false;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
// 4. ONLY NOW decode if format is valid
|
|
631
659
|
const decoded = Buffer.from(cleanBase64, "base64");
|
|
632
660
|
const reencoded = decoded.toString("base64");
|
|
633
661
|
// Remove padding for comparison (base64 can have different padding)
|
|
@@ -157,6 +157,7 @@ export declare const imageUtils: {
|
|
|
157
157
|
createDataUri: (base64: string, mimeType?: string) => string;
|
|
158
158
|
/**
|
|
159
159
|
* Validate base64 string format
|
|
160
|
+
* Validates format BEFORE buffer allocation to prevent memory exhaustion
|
|
160
161
|
*/
|
|
161
162
|
isValidBase64: (str: string) => boolean;
|
|
162
163
|
/**
|
|
@@ -622,12 +622,40 @@ export const imageUtils = {
|
|
|
622
622
|
},
|
|
623
623
|
/**
|
|
624
624
|
* Validate base64 string format
|
|
625
|
+
* Validates format BEFORE buffer allocation to prevent memory exhaustion
|
|
625
626
|
*/
|
|
626
627
|
isValidBase64: (str) => {
|
|
627
628
|
try {
|
|
628
629
|
// Remove data URI prefix if present
|
|
629
630
|
const cleanBase64 = str.includes(",") ? str.split(",")[1] : str;
|
|
630
|
-
//
|
|
631
|
+
// Empty string check
|
|
632
|
+
if (!cleanBase64 || cleanBase64.length === 0) {
|
|
633
|
+
return false;
|
|
634
|
+
}
|
|
635
|
+
// 1. Validate character set FIRST (A-Z, a-z, 0-9, +, /, =)
|
|
636
|
+
// This prevents memory allocation for invalid input like "hello world"
|
|
637
|
+
const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/;
|
|
638
|
+
if (!base64Regex.test(cleanBase64)) {
|
|
639
|
+
return false;
|
|
640
|
+
}
|
|
641
|
+
// 2. Check length is multiple of 4
|
|
642
|
+
if (cleanBase64.length % 4 !== 0) {
|
|
643
|
+
return false;
|
|
644
|
+
}
|
|
645
|
+
// 3. Validate padding position (max 2 equals at end only)
|
|
646
|
+
const paddingIndex = cleanBase64.indexOf("=");
|
|
647
|
+
if (paddingIndex !== -1) {
|
|
648
|
+
// Padding must be at the end
|
|
649
|
+
if (paddingIndex < cleanBase64.length - 2) {
|
|
650
|
+
return false;
|
|
651
|
+
}
|
|
652
|
+
// No characters after padding
|
|
653
|
+
const afterPadding = cleanBase64.slice(paddingIndex);
|
|
654
|
+
if (!/^=+$/.test(afterPadding)) {
|
|
655
|
+
return false;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
// 4. ONLY NOW decode if format is valid
|
|
631
659
|
const decoded = Buffer.from(cleanBase64, "base64");
|
|
632
660
|
const reencoded = decoded.toString("base64");
|
|
633
661
|
// Remove padding for comparison (base64 can have different padding)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juspay/neurolink",
|
|
3
|
-
"version": "8.20.
|
|
3
|
+
"version": "8.20.1",
|
|
4
4
|
"description": "Universal AI Development Platform with working MCP integration, multi-provider support, and professional CLI. Built-in tools operational, 58+ external MCP servers discoverable. Connect to filesystem, GitHub, database operations, and more. Build, test, and deploy AI applications with 9 major providers: OpenAI, Anthropic, Google AI, AWS Bedrock, Azure, Hugging Face, Ollama, and Mistral AI.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Juspay Technologies",
|