npq 3.15.2 → 3.15.4
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/lib/marshalls/author.marshall.js +45 -25
- package/package.json +2 -2
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Author Marshall - Package Publisher Security Checks
|
|
5
|
+
*
|
|
6
|
+
* This marshall performs two distinct security checks related to package publishing:
|
|
7
|
+
*
|
|
8
|
+
* 1. NEW AUTHOR CHECK (lines 65-80)
|
|
9
|
+
* Detects if this is the first version ever published by this user for this package.
|
|
10
|
+
* - Condition: No prior versions exist from this user, OR the current version is their first.
|
|
11
|
+
* - Only flags if the version was published recently (≤21 days ago).
|
|
12
|
+
* - Rationale: A brand new publisher on an established package could indicate account
|
|
13
|
+
* compromise or malicious takeover. However, if the "first" version is old (e.g., 10 years),
|
|
14
|
+
* it's not a current risk.
|
|
15
|
+
*
|
|
16
|
+
* 2. VERSION RECENCY CHECK (lines 91-106)
|
|
17
|
+
* Detects if the current version being installed was published very recently.
|
|
18
|
+
* - ≤7 days: Throws an Error (high risk)
|
|
19
|
+
* - ≤30 days: Throws a Warning (moderate risk)
|
|
20
|
+
* - Only applies if version is ≤45 days old.
|
|
21
|
+
* - Rationale: Very recently published versions haven't had time for community review
|
|
22
|
+
* and could contain undiscovered malicious code. This is independent of author history.
|
|
23
|
+
*
|
|
24
|
+
* These two checks are complementary:
|
|
25
|
+
* - Check 1 focuses on WHO published (author trustworthiness)
|
|
26
|
+
* - Check 2 focuses on WHEN it was published (version maturity)
|
|
27
|
+
*/
|
|
28
|
+
|
|
3
29
|
const BaseMarshall = require('./baseMarshall')
|
|
4
30
|
const Warning = require('../helpers/warning')
|
|
5
31
|
const { marshallCategories } = require('./constants')
|
|
@@ -18,16 +44,19 @@ class Marshall extends BaseMarshall {
|
|
|
18
44
|
}
|
|
19
45
|
|
|
20
46
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* @
|
|
47
|
+
* Validates package author and version recency for security risks.
|
|
48
|
+
*
|
|
49
|
+
* Performs two checks:
|
|
50
|
+
* 1. New Author Check: Flags if this is the user's first publish of this package
|
|
51
|
+
* AND the version was published within the last 21 days.
|
|
52
|
+
* 2. Version Recency Check: Flags recently published versions regardless of author:
|
|
53
|
+
* - Error if ≤7 days old
|
|
54
|
+
* - Warning if ≤30 days old
|
|
55
|
+
*
|
|
56
|
+
* @param {Object} pkg - Package info with packageName and packageVersion
|
|
57
|
+
* @returns {string} The version's publish date string if all checks pass
|
|
58
|
+
* @throws {Error} If security risk is detected (new author or very recent version)
|
|
59
|
+
* @throws {Warning} If moderate risk is detected (version 8-30 days old)
|
|
31
60
|
*/
|
|
32
61
|
async validate(pkg) {
|
|
33
62
|
// @TODO move some of these utility functions about first package version
|
|
@@ -40,7 +69,7 @@ class Marshall extends BaseMarshall {
|
|
|
40
69
|
)
|
|
41
70
|
|
|
42
71
|
// @TODO fix to work for both explicit versions (1.0.0) and also
|
|
43
|
-
// for
|
|
72
|
+
// for dist-tags (latest)
|
|
44
73
|
const npmUser = pakument.versions[packageVersion]._npmUser
|
|
45
74
|
if (!npmUser || !npmUser.email) {
|
|
46
75
|
throw new Error('Could not determine publishing user for this package version')
|
|
@@ -88,32 +117,23 @@ class Marshall extends BaseMarshall {
|
|
|
88
117
|
// )
|
|
89
118
|
}
|
|
90
119
|
|
|
91
|
-
const firstPublishedDateString = pakument.time[firstVersionForUser.version]
|
|
92
|
-
|
|
93
120
|
// get date in ms
|
|
94
|
-
const
|
|
95
|
-
const dateDiffInMsVersionPublished = currentDate - new Date(versionPublishedDateString)
|
|
121
|
+
const dateDiffInMsVersionPublished = new Date() - new Date(versionPublishedDateString)
|
|
96
122
|
let dateDiffVersionPublished = 0
|
|
97
123
|
if (dateDiffInMsVersionPublished > 0) {
|
|
98
124
|
dateDiffVersionPublished = Math.round(dateDiffInMsVersionPublished / (1000 * 60 * 60 * 24))
|
|
99
125
|
}
|
|
100
126
|
|
|
101
127
|
if (dateDiffVersionPublished <= 45) {
|
|
102
|
-
|
|
103
|
-
let dateDiffInDays = 0
|
|
104
|
-
if (dateDiffInMs > 0) {
|
|
105
|
-
dateDiffInDays = Math.round(dateDiffInMs / (1000 * 60 * 60 * 24))
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if (dateDiffInDays <= 7) {
|
|
128
|
+
if (dateDiffVersionPublished <= 7) {
|
|
109
129
|
throw new Error(
|
|
110
|
-
`
|
|
130
|
+
`This version was published only ${dateDiffVersionPublished} days ago by ${npmUser.name} <${npmUser.email}>`
|
|
111
131
|
)
|
|
112
132
|
}
|
|
113
133
|
|
|
114
|
-
if (
|
|
134
|
+
if (dateDiffVersionPublished <= 30) {
|
|
115
135
|
throw new Warning(
|
|
116
|
-
`
|
|
136
|
+
`This version was published only ${dateDiffVersionPublished} days ago by ${npmUser.name} <${npmUser.email}>`
|
|
117
137
|
)
|
|
118
138
|
}
|
|
119
139
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "npq",
|
|
3
|
-
"version": "3.15.
|
|
3
|
+
"version": "3.15.4",
|
|
4
4
|
"description": "marshall your npm/npm package installs with high quality and class 🎖",
|
|
5
5
|
"bin": {
|
|
6
6
|
"npq": "./bin/npq.js",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"fastest-levenshtein": "^1.0.16",
|
|
47
|
-
"npm-package-arg": "^13.0.
|
|
47
|
+
"npm-package-arg": "^13.0.2",
|
|
48
48
|
"semver": "^7.7.3",
|
|
49
49
|
"sigstore": "^3.1.0",
|
|
50
50
|
"ssri": "^12.0.0"
|