mobbdev 1.0.200 → 1.0.201

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.
@@ -3837,6 +3837,11 @@ var xss3 = {
3837
3837
  content: ({ expression }) => `Is the expression \`${expression}\` supposed to be not sanitized in this context?`,
3838
3838
  description: () => "You are using unsafe string substitution in the template. This means that if the expression can contain maliciously crafted data, it may lead to XSS injection. To apply the fix, you have to make sure the expression is not sanitized on the backend already, and it does not represent an HTML code block.",
3839
3839
  guidance: () => ""
3840
+ },
3841
+ isServerSideCode: {
3842
+ content: () => "Is this code running on the server side (a NodeJS application)",
3843
+ description: () => "The fix to this vulnerability is different is the code runs in the client (browser) or the server side (NodeJs)",
3844
+ guidance: () => ""
3840
3845
  }
3841
3846
  };
3842
3847
 
@@ -0,0 +1,10 @@
1
+ import { Buffer } from 'node:buffer';
2
+
3
+ declare class HashSearchError extends Error {
4
+ constructor(message: string);
5
+ }
6
+
7
+ declare function createIndex(originalText: string, windowSize?: number): Promise<Buffer>;
8
+ declare function searchIndex(searchText: string, index: Buffer): Promise<number[]>;
9
+
10
+ export { HashSearchError, createIndex, searchIndex };
@@ -0,0 +1,112 @@
1
+ // src/hash_search/index.ts
2
+ import { Buffer } from "buffer";
3
+ import { randomBytes } from "crypto";
4
+ import { blake3 } from "hash-wasm";
5
+
6
+ // src/hash_search/errors.ts
7
+ var HashSearchError = class _HashSearchError extends Error {
8
+ constructor(message) {
9
+ super(message);
10
+ this.name = "HashSearchError";
11
+ Object.setPrototypeOf(this, _HashSearchError.prototype);
12
+ }
13
+ };
14
+
15
+ // src/hash_search/index.ts
16
+ var MIN_WINDOW_SIZE = 8;
17
+ var DEFAULT_WINDOW_SIZE = 30;
18
+ async function createIndex(originalText, windowSize = DEFAULT_WINDOW_SIZE) {
19
+ if (!originalText || typeof originalText !== "string") {
20
+ throw new HashSearchError("Original text must be a non-empty string");
21
+ }
22
+ if (windowSize < MIN_WINDOW_SIZE) {
23
+ throw new HashSearchError(`Window size must be at least ${MIN_WINDOW_SIZE}`);
24
+ }
25
+ if (originalText.length < windowSize) {
26
+ throw new HashSearchError(
27
+ `Text length must be at least ${windowSize} characters (window size)`
28
+ );
29
+ }
30
+ const originalLength = originalText.length;
31
+ const paddingNeeded = (windowSize - originalLength % windowSize) % windowSize;
32
+ const paddedText = originalText + "\0".repeat(paddingNeeded);
33
+ const numChunks = paddedText.length - windowSize + 1;
34
+ const bufferSize = 12 + numChunks * 24;
35
+ const buffer = Buffer.alloc(bufferSize);
36
+ buffer.writeUInt8(114, 0);
37
+ buffer.writeUInt8(131, 1);
38
+ buffer.writeUInt8(0, 2);
39
+ buffer.writeUInt8(1, 3);
40
+ buffer.writeUInt32BE(originalLength, 4);
41
+ buffer.writeUInt32BE(windowSize, 8);
42
+ for (let i = 0; i < numChunks; i++) {
43
+ const chunk = paddedText.slice(i, i + windowSize);
44
+ const salt = randomBytes(8);
45
+ const dataToHash = Buffer.concat([salt, Buffer.from(chunk, "utf-8")]);
46
+ const hashHex = await blake3(dataToHash, 128);
47
+ const hash = Buffer.from(hashHex, "hex");
48
+ const offset = 12 + i * 24;
49
+ salt.copy(buffer, offset);
50
+ hash.copy(buffer, offset + 8);
51
+ }
52
+ return buffer;
53
+ }
54
+ async function searchIndex(searchText, index) {
55
+ if (!searchText || typeof searchText !== "string") {
56
+ throw new HashSearchError("Search text must be a non-empty string");
57
+ }
58
+ if (!Buffer.isBuffer(index)) {
59
+ throw new HashSearchError("Index must be a Buffer");
60
+ }
61
+ if (index.length < 12) {
62
+ throw new HashSearchError("Invalid index buffer: too small");
63
+ }
64
+ if ((index.length - 12) % 24 !== 0) {
65
+ throw new HashSearchError("Invalid index buffer: incorrect structure");
66
+ }
67
+ if (index.readUInt8(0) !== 114 || index.readUInt8(1) !== 131 || index.readUInt8(2) !== 0 || index.readUInt8(3) !== 1) {
68
+ throw new HashSearchError("Invalid magic number in index buffer");
69
+ }
70
+ const windowSize = index.readUInt32BE(8);
71
+ if (searchText.length < windowSize) {
72
+ throw new HashSearchError(
73
+ `Search text must be at least ${windowSize} characters (window size)`
74
+ );
75
+ }
76
+ const originalTextLength = index.readUInt32BE(4);
77
+ const searchLength = searchText.length;
78
+ const paddingNeeded = (windowSize - searchLength % windowSize) % windowSize;
79
+ const paddedSearch = searchText + "\0".repeat(paddingNeeded);
80
+ const numPositions = (index.length - 12) / 24;
81
+ const searchChunks = searchLength - windowSize + 1;
82
+ const results = [];
83
+ for (let startPos = 0; startPos <= numPositions - searchChunks; startPos++) {
84
+ let match = true;
85
+ for (let j = 0; j < searchChunks; j++) {
86
+ const searchChunk = paddedSearch.slice(j, j + windowSize);
87
+ const saltOffset = 12 + (startPos + j) * 24;
88
+ const salt = index.subarray(saltOffset, saltOffset + 8);
89
+ const dataToHash = Buffer.concat([
90
+ salt,
91
+ Buffer.from(searchChunk, "utf-8")
92
+ ]);
93
+ const expectedHashHex = await blake3(dataToHash, 128);
94
+ const expectedHash = Buffer.from(expectedHashHex, "hex");
95
+ const hashOffset = saltOffset + 8;
96
+ const actualHash = index.subarray(hashOffset, hashOffset + 16);
97
+ if (!expectedHash.equals(actualHash)) {
98
+ match = false;
99
+ break;
100
+ }
101
+ }
102
+ if (match && startPos + searchLength <= originalTextLength) {
103
+ results.push(startPos);
104
+ }
105
+ }
106
+ return results;
107
+ }
108
+ export {
109
+ HashSearchError,
110
+ createIndex,
111
+ searchIndex
112
+ };
package/dist/index.mjs CHANGED
@@ -4564,6 +4564,11 @@ var xss3 = {
4564
4564
  content: ({ expression }) => `Is the expression \`${expression}\` supposed to be not sanitized in this context?`,
4565
4565
  description: () => "You are using unsafe string substitution in the template. This means that if the expression can contain maliciously crafted data, it may lead to XSS injection. To apply the fix, you have to make sure the expression is not sanitized on the backend already, and it does not represent an HTML code block.",
4566
4566
  guidance: () => ""
4567
+ },
4568
+ isServerSideCode: {
4569
+ content: () => "Is this code running on the server side (a NodeJS application)",
4570
+ description: () => "The fix to this vulnerability is different is the code runs in the client (browser) or the server side (NodeJs)",
4571
+ guidance: () => ""
4567
4572
  }
4568
4573
  };
4569
4574
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mobbdev",
3
- "version": "1.0.200",
3
+ "version": "1.0.201",
4
4
  "description": "Automated secure code remediation tool",
5
5
  "repository": "git+https://github.com/mobb-dev/bugsy.git",
6
6
  "main": "dist/index.mjs",
@@ -71,6 +71,7 @@
71
71
  "graphql": "16.11.0",
72
72
  "graphql-request": "6.1.0",
73
73
  "graphql-ws": "5.16.2",
74
+ "hash-wasm": "4.12.0",
74
75
  "http-proxy-agent": "7.0.2",
75
76
  "https-proxy-agent": "7.0.6",
76
77
  "ignore": "7.0.5",