trim-safe 1.0.0 → 1.0.2
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 +14 -1
- package/package.json +26 -3
- package/scripts/migrate-check.js +47 -0
- package/.github/workflows/test.yml +0 -20
- package/SECURITY.md +0 -22
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ Safe, drop-in replacement for the abandoned [`trim`](https://www.npmjs.com/packa
|
|
|
6
6
|
|
|
7
7
|
The `trim` package (1M+ weekly downloads) has been effectively abandoned since 2013. Its canonical GitHub repo is dormant, the patch fork was archived in 2023, and the original source was never updated with the CVE fix.
|
|
8
8
|
|
|
9
|
-
The package contains **CVE-2020-7753** — a ReDoS vulnerability in the regex `/^\s*|\s*$/g`. An attacker can craft an input string that causes catastrophic regex backtracking, consuming all CPU and hanging your process.
|
|
9
|
+
The package contains **CVE-2020-7753** / **GHSA-cmr6-74hv-c9fg** — a ReDoS vulnerability (CVSS 7.5 HIGH) in the regex `/^\s*|\s*$/g`. An attacker can craft an input string that causes catastrophic regex backtracking, consuming all CPU and hanging your process.
|
|
10
10
|
|
|
11
11
|
`trim-safe` fixes the vulnerability using a loop-based approach with no regex backtracking. Same API, zero security debt.
|
|
12
12
|
|
|
@@ -16,6 +16,19 @@ The package contains **CVE-2020-7753** — a ReDoS vulnerability in the regex `/
|
|
|
16
16
|
npm install trim-safe
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
+
When installed into a project, `trim-safe` automatically checks your dependency tree. If it finds the vulnerable `trim` package, it prints a migration prompt:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
⚠ VULNERABLE: trim (CVE-2020-7753) found in dependency tree
|
|
23
|
+
3 packages still depend on the vulnerable trim package.
|
|
24
|
+
|
|
25
|
+
Migrate:
|
|
26
|
+
npm install trim-safe
|
|
27
|
+
# in your code: require('trim-safe') instead of require('trim')
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
No extra setup needed.
|
|
31
|
+
|
|
19
32
|
## Usage
|
|
20
33
|
|
|
21
34
|
```js
|
package/package.json
CHANGED
|
@@ -1,24 +1,47 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "trim-safe",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Safe, drop-in replacement for the abandoned trim package. Fixed ReDoS vulnerability (CVE-2020-7753).",
|
|
5
5
|
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"index.js",
|
|
9
|
+
"index.d.ts",
|
|
10
|
+
"README.md",
|
|
11
|
+
"test.js",
|
|
12
|
+
"scripts"
|
|
13
|
+
],
|
|
6
14
|
"scripts": {
|
|
7
|
-
"test": "node test.js"
|
|
15
|
+
"test": "node test.js",
|
|
16
|
+
"postinstall": "node scripts/migrate-check.js",
|
|
17
|
+
"prepare": "npm run test",
|
|
18
|
+
"prepublishOnly": "npm run test"
|
|
8
19
|
},
|
|
9
20
|
"keywords": [
|
|
21
|
+
"trim-safe",
|
|
10
22
|
"trim",
|
|
11
23
|
"string",
|
|
12
24
|
"whitespace",
|
|
13
25
|
"safe",
|
|
14
26
|
"regex",
|
|
15
|
-
"redos"
|
|
27
|
+
"redos",
|
|
28
|
+
"cve",
|
|
29
|
+
"security",
|
|
30
|
+
"javascript",
|
|
31
|
+
"typescript",
|
|
32
|
+
"nodejs",
|
|
33
|
+
"utility"
|
|
16
34
|
],
|
|
35
|
+
"author": "Jay Suryawanshi",
|
|
17
36
|
"license": "MIT",
|
|
18
37
|
"repository": {
|
|
19
38
|
"type": "git",
|
|
20
39
|
"url": "git+https://github.com/Jay-Suryawansh7/trim-safe.git"
|
|
21
40
|
},
|
|
41
|
+
"bugs": {
|
|
42
|
+
"url": "https://github.com/Jay-Suryawansh7/trim-safe/issues"
|
|
43
|
+
},
|
|
44
|
+
"homepage": "https://github.com/Jay-Suryawansh7/trim-safe#readme",
|
|
22
45
|
"engines": {
|
|
23
46
|
"node": ">=0.10.0"
|
|
24
47
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
var execSync = require('child_process').execSync;
|
|
4
|
+
|
|
5
|
+
function log(msg) { console.log(msg); }
|
|
6
|
+
function red(s) { return '\x1b[31m' + s + '\x1b[0m'; }
|
|
7
|
+
function green(s) { return '\x1b[32m' + s + '\x1b[0m'; }
|
|
8
|
+
function yellow(s){ return '\x1b[33m' + s + '\x1b[0m'; }
|
|
9
|
+
function cyan(s) { return '\x1b[36m' + s + '\x1b[0m'; }
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
var out = execSync('npm ls trim --all --parseable 2>/dev/null', { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] });
|
|
13
|
+
var lines = out.trim().split('\n').filter(Boolean);
|
|
14
|
+
|
|
15
|
+
if (lines.length === 0) {
|
|
16
|
+
log('\n ' + green('\u2713') + ' trim-safe OK — no vulnerable trim found in your dependency tree.');
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
log('\n ' + red('\u26A0') + ' ' + red('VULNERABLE: trim (CVE-2020-7753) found in dependency tree'));
|
|
21
|
+
log(' ' + lines.length + ' package' + (lines.length === 1 ? '' : 's') + ' still depend on the vulnerable trim package.\n');
|
|
22
|
+
|
|
23
|
+
var unique = {};
|
|
24
|
+
lines.forEach(function(l) {
|
|
25
|
+
var parts = l.split('node_modules/');
|
|
26
|
+
var pkg = parts[parts.length - 1];
|
|
27
|
+
if (pkg && pkg !== 'trim') unique[pkg] = true;
|
|
28
|
+
});
|
|
29
|
+
var names = Object.keys(unique).filter(Boolean);
|
|
30
|
+
|
|
31
|
+
if (names.length > 0 && names.length <= 20) {
|
|
32
|
+
log(' Direct dependents: ' + names.join(', '));
|
|
33
|
+
log('');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
log(' ' + cyan('Migrate:'));
|
|
37
|
+
log(' npm install trim-safe');
|
|
38
|
+
log(' # in your code: require(\'trim-safe\') instead of require(\'trim\')');
|
|
39
|
+
log('');
|
|
40
|
+
} catch (e) {
|
|
41
|
+
try {
|
|
42
|
+
var out2 = execSync('npm ls trim 2>/dev/null', { encoding: 'utf8' });
|
|
43
|
+
if (out2 && out2.includes('trim@')) {
|
|
44
|
+
log(yellow('\n trim found in dependency tree — run "npm install trim-safe" to migrate.\n'));
|
|
45
|
+
}
|
|
46
|
+
} catch (e2) {}
|
|
47
|
+
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
name: Test
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [main]
|
|
6
|
-
pull_request:
|
|
7
|
-
branches: [main]
|
|
8
|
-
|
|
9
|
-
jobs:
|
|
10
|
-
test:
|
|
11
|
-
runs-on: ubuntu-latest
|
|
12
|
-
strategy:
|
|
13
|
-
matrix:
|
|
14
|
-
node-version: [18, 20, 22]
|
|
15
|
-
steps:
|
|
16
|
-
- uses: actions/checkout@v4
|
|
17
|
-
- uses: actions/setup-node@v4
|
|
18
|
-
with:
|
|
19
|
-
node-version: ${{ matrix.node-version }}
|
|
20
|
-
- run: npm test
|
package/SECURITY.md
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# Security Policy
|
|
2
|
-
|
|
3
|
-
## Supported Versions
|
|
4
|
-
|
|
5
|
-
| Version | Supported |
|
|
6
|
-
| ------- | ------------------ |
|
|
7
|
-
| 1.x | :white_check_mark: |
|
|
8
|
-
|
|
9
|
-
## Reporting a Vulnerability
|
|
10
|
-
|
|
11
|
-
If you discover a security vulnerability in `trim-safe`, please report it via:
|
|
12
|
-
|
|
13
|
-
1. **GitHub Issues** (preferred for non-critical issues)
|
|
14
|
-
2. **Email** — open an issue first and we'll respond within 48 hours
|
|
15
|
-
|
|
16
|
-
Please do not disclose security vulnerabilities publicly until a fix is available.
|
|
17
|
-
|
|
18
|
-
## Security Model
|
|
19
|
-
|
|
20
|
-
`trim-safe` intentionally contains **no external dependencies** — only stdlib JavaScript. The attack surface is zero network calls, zero file reads, and no dynamic code execution.
|
|
21
|
-
|
|
22
|
-
The package has no `postinstall`, `preinstall`, `prepare`, or any other lifecycle hooks.
|