@nodesecure/scanner 5.1.0 → 5.2.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 +2 -1
- package/package.json +5 -5
- package/src/depWalker.js +8 -1
- package/src/manifest.js +3 -1
- package/src/npmRegistry.js +9 -2
- package/src/tarball.js +15 -0
- package/src/utils/getLinks.js +31 -0
- package/src/utils/index.js +1 -0
- package/types/scanner.d.ts +10 -0
package/README.md
CHANGED
|
@@ -78,7 +78,7 @@ interface Options {
|
|
|
78
78
|
## Contributors ✨
|
|
79
79
|
|
|
80
80
|
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
|
81
|
-
[](#contributors-)
|
|
82
82
|
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
|
83
83
|
|
|
84
84
|
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
|
|
@@ -102,6 +102,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|
|
102
102
|
<td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/ange-tekeu-a155811b4/"><img src="https://avatars.githubusercontent.com/u/35274201?v=4?s=100" width="100px;" alt="Ange TEKEU"/><br /><sub><b>Ange TEKEU</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=tekeuange23" title="Code">💻</a></td>
|
|
103
103
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Kawacrepe"><img src="https://avatars.githubusercontent.com/u/40260517?v=4?s=100" width="100px;" alt="Vincent Dhennin"/><br /><sub><b>Vincent Dhennin</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=Kawacrepe" title="Code">💻</a></td>
|
|
104
104
|
<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></td>
|
|
105
|
+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/PierreDemailly"><img src="https://avatars.githubusercontent.com/u/39910767?v=4?s=100" width="100px;" alt="PierreDemailly"/><br /><sub><b>PierreDemailly</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=PierreDemailly" title="Code">💻</a> <a href="https://github.com/NodeSecure/scanner/pulls?q=is%3Apr+reviewed-by%3APierreDemailly" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/NodeSecure/scanner/issues?q=author%3APierreDemailly" title="Bug reports">🐛</a> <a href="https://github.com/NodeSecure/scanner/commits?author=PierreDemailly" title="Tests">⚠️</a></td>
|
|
105
106
|
</tr>
|
|
106
107
|
</tbody>
|
|
107
108
|
</table>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nodesecure/scanner",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.2.0",
|
|
4
4
|
"description": "A package API to run a static analysis of your module's dependencies.",
|
|
5
5
|
"exports": "./index.js",
|
|
6
6
|
"engines": {
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"@types/node": "^20.10.0",
|
|
56
56
|
"c8": "^8.0.1",
|
|
57
57
|
"dotenv": "^16.3.1",
|
|
58
|
-
"eslint": "
|
|
58
|
+
"eslint": "8.37.0",
|
|
59
59
|
"get-folder-size": "^4.0.0",
|
|
60
60
|
"glob": "^10.3.10",
|
|
61
61
|
"pkg-ok": "^3.0.0",
|
|
@@ -66,9 +66,9 @@
|
|
|
66
66
|
"@nodesecure/authors": "^1.0.2",
|
|
67
67
|
"@nodesecure/flags": "^2.4.0",
|
|
68
68
|
"@nodesecure/fs-walk": "^1.0.0",
|
|
69
|
-
"@nodesecure/i18n": "^3.
|
|
70
|
-
"@nodesecure/js-x-ray": "^6.
|
|
71
|
-
"@nodesecure/npm-registry-sdk": "^
|
|
69
|
+
"@nodesecure/i18n": "^3.5.0",
|
|
70
|
+
"@nodesecure/js-x-ray": "^6.3.0",
|
|
71
|
+
"@nodesecure/npm-registry-sdk": "^2.0.0",
|
|
72
72
|
"@nodesecure/ntlp": "^2.2.1",
|
|
73
73
|
"@nodesecure/vuln": "^1.7.0",
|
|
74
74
|
"@npm/types": "^1.0.2",
|
package/src/depWalker.js
CHANGED
|
@@ -293,7 +293,7 @@ export async function depWalker(manifest, options = {}, logger = new Logger()) {
|
|
|
293
293
|
logger.tick(ScannerLoggerEvents.analysis.tree);
|
|
294
294
|
|
|
295
295
|
// There is no need to fetch 'N' times the npm metadata for the same package.
|
|
296
|
-
if (fetchedMetadataPackages.has(name)) {
|
|
296
|
+
if (fetchedMetadataPackages.has(name) || !current.versions[version].existOnRemoteRegistry) {
|
|
297
297
|
logger.tick(ScannerLoggerEvents.analysis.registry);
|
|
298
298
|
}
|
|
299
299
|
else {
|
|
@@ -340,6 +340,13 @@ export async function depWalker(manifest, options = {}, logger = new Logger()) {
|
|
|
340
340
|
|
|
341
341
|
for (const [version, integrity] of Object.entries(metadataIntegrities)) {
|
|
342
342
|
const dependencyVer = dependency.versions[version];
|
|
343
|
+
|
|
344
|
+
const isEmptyPackage = dependencyVer.warnings
|
|
345
|
+
.some((warning) => warning.kind === "empty-package");
|
|
346
|
+
if (isEmptyPackage) {
|
|
347
|
+
globalWarnings.push(`${packageName}@${version} only contain a package.json file!`);
|
|
348
|
+
}
|
|
349
|
+
|
|
343
350
|
if (!("integrity" in dependencyVer) || dependencyVer.flags.includes("isGit")) {
|
|
344
351
|
continue;
|
|
345
352
|
}
|
package/src/manifest.js
CHANGED
|
@@ -54,7 +54,9 @@ export async function readAnalyze(location) {
|
|
|
54
54
|
} = await read(location);
|
|
55
55
|
|
|
56
56
|
for (const [scriptName, scriptValue] of Object.entries(scripts)) {
|
|
57
|
-
|
|
57
|
+
if (scriptValue.startsWith(kNodemodulesBinPrefix)) {
|
|
58
|
+
scripts[scriptName] = scriptValue.replaceAll(kNodemodulesBinPrefix, "");
|
|
59
|
+
}
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
const integrityObj = {
|
package/src/npmRegistry.js
CHANGED
|
@@ -6,7 +6,7 @@ import semver from "semver";
|
|
|
6
6
|
import { packument, packumentVersion } from "@nodesecure/npm-registry-sdk";
|
|
7
7
|
|
|
8
8
|
// Import Internal Dependencies
|
|
9
|
-
import { parseAuthor } from "./utils/index.js";
|
|
9
|
+
import { parseAuthor, getLinks } from "./utils/index.js";
|
|
10
10
|
|
|
11
11
|
export async function manifestMetadata(name, version, metadata) {
|
|
12
12
|
try {
|
|
@@ -45,8 +45,9 @@ export async function packageMetadata(name, version, options) {
|
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
const isOutdated = semver.neq(version, lastVersion);
|
|
48
|
+
const flags = ref.versions[version].flags;
|
|
48
49
|
if (isOutdated) {
|
|
49
|
-
|
|
50
|
+
flags.push("isOutdated");
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
const publishers = new Set();
|
|
@@ -54,12 +55,17 @@ export async function packageMetadata(name, version, options) {
|
|
|
54
55
|
for (const ver of Object.values(pkg.versions).reverse()) {
|
|
55
56
|
const versionSpec = `${ver.name}:${ver.version}`;
|
|
56
57
|
if (packageSpec === versionSpec) {
|
|
58
|
+
if (ver.deprecated && !flags.includes("isDeprecated")) {
|
|
59
|
+
flags.push("isDeprecated");
|
|
60
|
+
}
|
|
61
|
+
|
|
57
62
|
metadata.integrity[ver.version] = getPackumentVersionIntegrity(
|
|
58
63
|
ver
|
|
59
64
|
);
|
|
60
65
|
}
|
|
61
66
|
|
|
62
67
|
const { _npmUser: npmUser, version, maintainers = [] } = ver;
|
|
68
|
+
|
|
63
69
|
const isNullOrUndefined = typeof npmUser === "undefined" || npmUser === null;
|
|
64
70
|
if (isNullOrUndefined || !("name" in npmUser) || typeof npmUser.name !== "string") {
|
|
65
71
|
continue;
|
|
@@ -85,6 +91,7 @@ export async function packageMetadata(name, version, options) {
|
|
|
85
91
|
}
|
|
86
92
|
}
|
|
87
93
|
|
|
94
|
+
Object.assign(ref.versions[version], { links: getLinks(pkg.versions[version]) });
|
|
88
95
|
Object.assign(ref.metadata, metadata);
|
|
89
96
|
}
|
|
90
97
|
catch {
|
package/src/tarball.js
CHANGED
|
@@ -67,6 +67,10 @@ export async function scanDirOrArchive(name, version, options) {
|
|
|
67
67
|
});
|
|
68
68
|
await timers.setImmediate();
|
|
69
69
|
}
|
|
70
|
+
else {
|
|
71
|
+
// Set links to an empty object because theses are generated only for NPM tarballs
|
|
72
|
+
Object.assign(ref, { links: {} });
|
|
73
|
+
}
|
|
70
74
|
|
|
71
75
|
// Read the package.json at the root of the directory or archive.
|
|
72
76
|
const {
|
|
@@ -88,6 +92,17 @@ export async function scanDirOrArchive(name, version, options) {
|
|
|
88
92
|
|
|
89
93
|
// Get the composition of the (extracted) directory
|
|
90
94
|
const { ext, files, size } = await getTarballComposition(dest);
|
|
95
|
+
if (files.length === 1 && files.includes("package.json")) {
|
|
96
|
+
ref.warnings.push({
|
|
97
|
+
kind: "empty-package",
|
|
98
|
+
location: null,
|
|
99
|
+
i18n: "sast_warnings.emptyPackage",
|
|
100
|
+
severity: "Critical",
|
|
101
|
+
source: "Scanner",
|
|
102
|
+
experimental: false
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
91
106
|
ref.size = size;
|
|
92
107
|
ref.composition.extensions.push(...ext);
|
|
93
108
|
ref.composition.files.push(...files);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// CONSTANTS
|
|
2
|
+
const kVCSHosts = new Set(["github.com", "gitlab.com"]);
|
|
3
|
+
|
|
4
|
+
function getVCSRepositoryURL(link) {
|
|
5
|
+
try {
|
|
6
|
+
const url = new URL(link);
|
|
7
|
+
const { hostname, pathname } = url;
|
|
8
|
+
|
|
9
|
+
if (kVCSHosts.has(hostname) === false) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const [owner, repo] = pathname.split("/").filter(Boolean).map((curr) => curr.replace(".git", ""));
|
|
14
|
+
|
|
15
|
+
return `https://${hostname}/${owner}/${repo}`;
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function getLinks(pkg) {
|
|
23
|
+
const homepage = pkg.homepage || null;
|
|
24
|
+
const repositoryUrl = pkg.repository?.url || null;
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
npm: `https://www.npmjs.com/package/${pkg.name}/v/${pkg.version}`,
|
|
28
|
+
homepage,
|
|
29
|
+
repository: getVCSRepositoryURL(homepage) ?? getVCSRepositoryURL(repositoryUrl)
|
|
30
|
+
};
|
|
31
|
+
}
|
package/src/utils/index.js
CHANGED
|
@@ -11,6 +11,7 @@ export * from "./analyzeDependencies.js";
|
|
|
11
11
|
export * from "./booleanToFlags.js";
|
|
12
12
|
export * from "./addMissingVersionFlags.js";
|
|
13
13
|
export * from "./parseManifestAuthor.js";
|
|
14
|
+
export * from "./getLinks.js";
|
|
14
15
|
|
|
15
16
|
export const NPM_TOKEN = typeof process.env.NODE_SECURE_TOKEN === "string" ?
|
|
16
17
|
{ token: process.env.NODE_SECURE_TOKEN } :
|
package/types/scanner.d.ts
CHANGED
|
@@ -40,6 +40,15 @@ declare namespace Scanner {
|
|
|
40
40
|
at: string;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
export interface DependencyLinks {
|
|
44
|
+
/** NPM Registry page */
|
|
45
|
+
npm: string;
|
|
46
|
+
/** Homepage URL */
|
|
47
|
+
homepage?: string;
|
|
48
|
+
/** VCS repository URL */
|
|
49
|
+
repository?: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
43
52
|
export interface DependencyVersion {
|
|
44
53
|
/** Id of the package (useful for usedBy relation) */
|
|
45
54
|
id: number;
|
|
@@ -111,6 +120,7 @@ declare namespace Scanner {
|
|
|
111
120
|
* (Not supported on GIT dependency)
|
|
112
121
|
*/
|
|
113
122
|
integrity?: string;
|
|
123
|
+
links: DependencyLinks;
|
|
114
124
|
}
|
|
115
125
|
|
|
116
126
|
export interface Dependency {
|