@nodesecure/js-x-ray 6.1.1 → 6.2.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/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  <img src="https://img.shields.io/badge/dynamic/json.svg?style=for-the-badge&url=https://raw.githubusercontent.com/NodeSecure/js-x-ray/master/package.json&query=$.version&label=Version" alt="npm version">
8
8
  </a>
9
9
  <a href="https://github.com/NodeSecure/js-x-ray/blob/master/LICENSE">
10
- <img src="https://img.shields.io/github/license/Naereen/StrapDown.js.svg?style=for-the-badge" alt="license">
10
+ <img src="https://img.shields.io/github/license/NodeSecure/js-x-ray.svg?style=for-the-badge" alt="license">
11
11
  </a>
12
12
  <a href="https://api.securityscorecards.dev/projects/github.com/NodeSecure/js-x-ray">
13
13
  <img src="https://api.securityscorecards.dev/projects/github.com/NodeSecure/js-x-ray/badge?style=for-the-badge" alt="ossf scorecard">
@@ -198,7 +198,7 @@ export type ReportOnFile = {
198
198
  ## Contributors ✨
199
199
 
200
200
  <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
201
- [![All Contributors](https://img.shields.io/badge/all_contributors-10-orange.svg?style=flat-square)](#contributors-)
201
+ [![All Contributors](https://img.shields.io/badge/all_contributors-11-orange.svg?style=flat-square)](#contributors-)
202
202
  <!-- ALL-CONTRIBUTORS-BADGE:END -->
203
203
 
204
204
  Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
@@ -221,6 +221,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
221
221
  <td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/franck-hallaert/"><img src="https://avatars.githubusercontent.com/u/110826655?v=4?s=100" width="100px;" alt="Franck Hallaert"/><br /><sub><b>Franck Hallaert</b></sub></a><br /><a href="https://github.com/NodeSecure/js-x-ray/commits?author=Aekk0" title="Code">💻</a></td>
222
222
  <td align="center" valign="top" width="14.28%"><a href="https://maji.kiwi"><img src="https://avatars.githubusercontent.com/u/33150916?v=4?s=100" width="100px;" alt="Maji"/><br /><sub><b>Maji</b></sub></a><br /><a href="https://github.com/NodeSecure/js-x-ray/commits?author=M4gie" title="Code">💻</a></td>
223
223
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/targos"><img src="https://avatars.githubusercontent.com/u/2352663?v=4?s=100" width="100px;" alt="Michaël Zasso"/><br /><sub><b>Michaël Zasso</b></sub></a><br /><a href="https://github.com/NodeSecure/js-x-ray/commits?author=targos" title="Code">💻</a> <a href="https://github.com/NodeSecure/js-x-ray/issues?q=author%3Atargos" title="Bug reports">🐛</a></td>
224
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/fabnguess"><img src="https://avatars.githubusercontent.com/u/72697416?v=4?s=100" width="100px;" alt="Kouadio Fabrice Nguessan"/><br /><sub><b>Kouadio Fabrice Nguessan</b></sub></a><br /><a href="#maintenance-fabnguess" title="Maintenance">🚧</a> <a href="https://github.com/NodeSecure/js-x-ray/commits?author=fabnguess" title="Code">💻</a></td>
224
225
  </tr>
225
226
  </tbody>
226
227
  </table>
package/index.js CHANGED
@@ -122,15 +122,19 @@ function parseScriptExtended(strToAnalyze, options = {}) {
122
122
  return body;
123
123
  }
124
124
  catch (error) {
125
+ const isIllegalReturn = error.description.includes("Illegal return statement");
126
+
125
127
  if (error.name === "SyntaxError" && (
126
128
  error.description.includes("The import keyword") ||
127
- error.description.includes("The export keyword")
129
+ error.description.includes("The export keyword") ||
130
+ isIllegalReturn
128
131
  )) {
129
132
  const { body } = meriyah.parseScript(
130
133
  cleanedStrToAnalyze,
131
134
  {
132
135
  ...kMeriyahDefaultOptions,
133
- module: true
136
+ module: true,
137
+ globalReturn: isIllegalReturn
134
138
  }
135
139
  );
136
140
 
package/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@nodesecure/js-x-ray",
3
- "version": "6.1.1",
3
+ "version": "6.2.1",
4
4
  "description": "JavaScript AST XRay analysis",
5
5
  "type": "module",
6
6
  "exports": "./index.js",
7
7
  "engines": {
8
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
8
+ "node": ">=18.0.0"
9
9
  },
10
10
  "scripts": {
11
11
  "lint": "eslint src test",
12
12
  "prepublishOnly": "pkg-ok",
13
- "test-only": "cross-env esm-tape-runner 'test/**/*.spec.js' | tap-monkey",
14
- "test": "c8 --all --src ./src --reporter=lcov npm run test-only",
15
- "check": "cross-env npm run lint && npm run test-only"
13
+ "test-only": "glob -c \"node --test-reporter=spec --test\" \"./test/**/*.spec.js\"",
14
+ "test": "c8 --all --src ./src -r html npm run test-only",
15
+ "check": "npm run lint && npm run test-only"
16
16
  },
17
17
  "repository": {
18
18
  "type": "git",
@@ -48,14 +48,10 @@
48
48
  },
49
49
  "devDependencies": {
50
50
  "@nodesecure/eslint-config": "^1.6.0",
51
- "@slimio/is": "^2.0.0",
52
- "@small-tech/esm-tape-runner": "^2.0.0",
53
- "@small-tech/tap-monkey": "^1.4.0",
54
- "@types/node": "^20.3.0",
55
- "c8": "^8.0.0",
56
- "cross-env": "^7.0.3",
51
+ "@types/node": "^20.6.2",
52
+ "c8": "^8.0.1",
57
53
  "eslint": "^8.31.0",
58
- "pkg-ok": "^3.0.0",
59
- "tape": "^5.6.1"
54
+ "glob": "^10.3.4",
55
+ "pkg-ok": "^3.0.0"
60
56
  }
61
57
  }
package/src/Analysis.js CHANGED
@@ -88,7 +88,7 @@ export default class Analysis {
88
88
  }
89
89
 
90
90
  // Searching for morse string like "--.- --.--."
91
- if (Utils.stringCharDiversity(str, ["\n"]) >= 3 && Utils.isMorse(str)) {
91
+ if (Utils.isMorse(str)) {
92
92
  this.counter.morseLiteral++;
93
93
  }
94
94
  }
@@ -37,11 +37,6 @@ export function isObfuscatedCode(analysis) {
37
37
  if (analysis.counter.identifiers > kMinimumIdsCount && uPrefixNames.size > 0) {
38
38
  analysis.hasPrefixedIdentifiers = calcAvgPrefixedIdentifiers(analysis, prefix) > 80;
39
39
  }
40
- // console.log(prefix);
41
- // console.log(oneTimeOccurence);
42
- // console.log(analysis.hasPrefixedIdentifiers);
43
- // console.log(analysis.counter.identifiers);
44
- // console.log(analysis.counter.encodedArrayValue);
45
40
 
46
41
  if (uPrefixNames.size === 1 && freejsobfuscator.verify(analysis, prefix)) {
47
42
  encoderName = "freejsobfuscator";
@@ -7,7 +7,8 @@ import {
7
7
  concatBinaryExpression,
8
8
  arrayExpressionToString,
9
9
  getMemberExpressionIdentifier,
10
- getCallExpressionIdentifier
10
+ getCallExpressionIdentifier,
11
+ getCallExpressionArguments
11
12
  } from "@nodesecure/estree-ast-utils";
12
13
 
13
14
  function validateNode(node, { tracer }) {
@@ -89,7 +90,7 @@ function main(node, options) {
89
90
 
90
91
  // require(Buffer.from("...", "hex").toString());
91
92
  case "CallExpression": {
92
- walkRequireCallExpression(arg)
93
+ walkRequireCallExpression(arg, tracer)
93
94
  .forEach((depName) => analysis.dependencies.add(depName, node.loc, true));
94
95
 
95
96
  analysis.addWarning("unsafe-import", null, node.loc);
@@ -103,7 +104,7 @@ function main(node, options) {
103
104
  }
104
105
  }
105
106
 
106
- function walkRequireCallExpression(nodeToWalk) {
107
+ function walkRequireCallExpression(nodeToWalk, tracer) {
107
108
  const dependencies = new Set();
108
109
 
109
110
  walk(nodeToWalk, {
@@ -122,8 +123,19 @@ function walkRequireCallExpression(nodeToWalk) {
122
123
  const fullName = node.callee.type === "MemberExpression" ?
123
124
  [...getMemberExpressionIdentifier(node.callee)].join(".") :
124
125
  node.callee.name;
126
+ const tracedFullName = tracer.getDataFromIdentifier(fullName)?.identifierOrMemberExpr ?? fullName;
127
+
128
+ switch (tracedFullName) {
129
+ case "atob": {
130
+ const nodeArguments = getCallExpressionArguments(node, { tracer });
131
+ if (nodeArguments !== null) {
132
+ dependencies.add(
133
+ Buffer.from(nodeArguments.at(0), "base64").toString()
134
+ );
135
+ }
125
136
 
126
- switch (fullName) {
137
+ break;
138
+ }
127
139
  case "Buffer.from": {
128
140
  const [element] = node.arguments;
129
141
 
package/src/warnings.js CHANGED
@@ -54,16 +54,16 @@ export const warnings = Object.freeze({
54
54
  });
55
55
 
56
56
  export function generateWarning(kind, options) {
57
- const { location, file = null, value = null } = options;
57
+ const { location, file = null, value = null, source = "JS-X-Ray" } = options;
58
58
 
59
59
  if (kind === "encoded-literal") {
60
60
  return Object.assign(
61
- { kind, value, location: [utils.toArrayLocation(location)] },
61
+ { kind, value, location: [utils.toArrayLocation(location)], source },
62
62
  warnings[kind]
63
63
  );
64
64
  }
65
65
 
66
- const result = { kind, location: utils.toArrayLocation(location) };
66
+ const result = { kind, location: utils.toArrayLocation(location), source };
67
67
  if (utils.notNullOrUndefined(file)) {
68
68
  result.file = file;
69
69
  }
@@ -25,6 +25,7 @@ interface WarningDefault {
25
25
  kind: WarningName;
26
26
  file?: string;
27
27
  value: string;
28
+ source: string;
28
29
  location: WarningLocation | WarningLocation[];
29
30
  i18n: string;
30
31
  severity: "Information" | "Warning" | "Critical";