sanitize-contents 1.0.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 +40 -0
- package/dist/index.d.mts +17 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +2 -0
- package/dist/index.mjs +2 -0
- package/package.json +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# sanitize-content
|
|
2
|
+
|
|
3
|
+
A robust, lightweight library to sanitize sensitive information (passwords, tokens, connection strings, etc.) from strings and HTML content.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Connection Strings**: Redacts user:pass from `mongodb://`, `postgres://`, `redis://`, etc.
|
|
8
|
+
- **Query Parameters**: Redacts sensitive keys like `api_key`, `access_token`, `secret`, `password` from URLs.
|
|
9
|
+
- **Authorization Headers**: Sanitizes `Bearer` and `Basic` auth tokens.
|
|
10
|
+
- **Credential Labels**: Identifies and redacts common patterns like `Password: ...`, `API Key: ...`.
|
|
11
|
+
- **CURL Auth**: Sanitizes `-u user:pass` flags in curl commands.
|
|
12
|
+
- **Lightweight**: Zero dependencies.
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install sanitize-content
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
```javascript
|
|
23
|
+
import { sanitizeContent } from 'sanitize-content';
|
|
24
|
+
|
|
25
|
+
const rawContent = 'Connecting to mongodb://user:pass123@localhost:27017/db';
|
|
26
|
+
const cleanContent = sanitizeContent(rawContent);
|
|
27
|
+
// Connecting to mongodb://[REDACTED]@localhost:27017/db
|
|
28
|
+
|
|
29
|
+
const url = 'https://api.example.com?api_key=sk-123456789';
|
|
30
|
+
console.log(sanitizeContent(url));
|
|
31
|
+
// https://api.example.com?api_key=[REDACTED]
|
|
32
|
+
|
|
33
|
+
const header = 'Authorization: Bearer my-secret-token';
|
|
34
|
+
console.log(sanitizeContent(header));
|
|
35
|
+
// Authorization: Bearer [REDACTED]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## License
|
|
39
|
+
|
|
40
|
+
ISC
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sanitizes sensitive information from content.
|
|
3
|
+
* Redacts passwords, connection strings, API keys, etc.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Sanitizes a string by redacting sensitive patterns.
|
|
7
|
+
*/
|
|
8
|
+
declare function sanitizeContent(content: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Sanitizes HTML content by processing only text nodes.
|
|
11
|
+
* Matches the API of the user's legacy script.
|
|
12
|
+
*/
|
|
13
|
+
declare function sanitizeDescription(html: string): {
|
|
14
|
+
sanitized_text: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export { sanitizeContent as default, sanitizeContent, sanitizeDescription };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sanitizes sensitive information from content.
|
|
3
|
+
* Redacts passwords, connection strings, API keys, etc.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Sanitizes a string by redacting sensitive patterns.
|
|
7
|
+
*/
|
|
8
|
+
declare function sanitizeContent(content: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Sanitizes HTML content by processing only text nodes.
|
|
11
|
+
* Matches the API of the user's legacy script.
|
|
12
|
+
*/
|
|
13
|
+
declare function sanitizeDescription(html: string): {
|
|
14
|
+
sanitized_text: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export { sanitizeContent as default, sanitizeContent, sanitizeDescription };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var g=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var R=Object.prototype.hasOwnProperty;var b=(r,e)=>{for(var o in e)g(r,o,{get:e[o],enumerable:!0})},C=(r,e,o,_)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of S(e))!R.call(r,a)&&a!==o&&g(r,a,{get:()=>e[a],enumerable:!(_=A(e,a))||_.enumerable});return r};var N=r=>C(g({},"__esModule",{value:!0}),r);var D={};b(D,{default:()=>O,sanitizeContent:()=>T,sanitizeDescription:()=>I});module.exports=N(D);var f=require("jsdom"),d={CONNECTION_STRING:/([a-z0-9+.-]+:\/\/)([^:@\s]+):([^:@\s]+)@/gi,SQL_INSERT:/\bINSERT\s+INTO\b.*?\((?:[^)]*,\s*)?\b(password|pwd|pass|passcode)\b.*?\)\s*VALUES\s*\((?:[^,']*,|[^,"]*,)*\s*['"]([^'"]+)['"]/gi,HTML_INPUT:/<input[^>]+(?:type=["']password["'](?:\s+[^>]*?)?value=["']([^"']*)["']|value=["']([^"']*)["'](?:\s+[^>]*?)?type=["']password["'])/gi,QUERY_PARAM:/([?&])(api[_-]?key|access[_-]?token|secret|password|pass|passwrod|psswrd|pw|pwd|token|key|auth[_-]?token|u|p|user|username|passcode|wifi[_-]?password|p_?w_?d|confirm[_-]?password|confirm[_-]?pwd)=([^&\s<"']+)/gi,AUTH_TOKEN:/\b(authorization|auth[_-]?token)\s*[:=]\s*(bearer|basic|token)?\s*([a-zA-Z0-9.\-_~+/]{8,})|(?:\b(bearer|basic|token)\s+([a-zA-Z0-9.\-_~+/]{8,}))/gi,JWT:/\beyJ[a-zA-Z0-9._-]{10,}\b/gi,BASE64_PASS:/cGFzc3dvcmQ9[a-zA-Z0-9+/=]+/g,USER_PASS:/\b(user(?:name)?|login)\b\s*[:=\s/]\s*([^"'\s,]+)\s*(?:and\s+)?\b(pass(?:word)?|pwd|p|p_?w_?d)\b\s*[:=\s]\s*([^"'\s<,]+)/gi,SLASH_CRED:/\b(admin|user|root|api_?user)\/([^"'\s,;]{3,})\b/gi,CURL_AUTH:/(^|\s)(-u\s+)([^:\s]+):([^:\s\\]+)/gi,ASSIGNMENT:/\b(DB[_-]?PASSWORD|JWT[_-]?SECRET|SECRET[_-]?KEY|AUTH[_-]?PASSWORD|PASSWORD|SECRET|KEY|WIFI[_-]?PASSWORD|PASSCODE|API[_-]?KEY|CONFIRM[_-]?PASSWORD|PASSWROD)\s*[:=]\s*(?:["']?)([^"'\s;<>]{3,})(?:["']?)/gi,XML_TAG:/<([^>]*password|pass|secret|token|key)>([^<]+)<\/\1>/gi,LABEL_HINT:/(?:\b|["'<])(password|pass|passwrod|psswrd|pw|pwd|api[_-]?key|access[_-]?token|auth[_-]?token|credentials|creds|secret|token|key|passcode|wifi[_-]?password|p_?w_?d|u|p|confirm[_-]?password|confirm[_-]?pwd|actual|temp|temporary|new\s+one|old\s+one|new\s+password|old\s+password)(?:\b|["'>])[^a-zA-Z0-9\s]*\s*(?:[:=\s]|was\s+something\s+like|it\s+was\s+something\s+like|was|is|like|should\s+be|actual\s+was|could\s+be|might\s+be|set\s+to|entered)(?:\s+it)?\s*[:=]?\s*(?:["']?)([^"'\s<>&,;?]+)(?:["']?)(?:\s+or\s+([^"'\s<>&,;?]+))?/gi,URL:/\bhttps?:\/\/[^\s"'<>]+/gi,EMAIL:/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g,MENTION:/(^|\s|[(\[])(@([a-zA-Z0-9._-]+))/g},p="[REDACTED]",w=/^(value|type|name|id|class|and|or|was|is|it|the|set|to|values|into|select|from|where|union|join|table|input|button|form|label|div|span|script|style|html|body|head|meta|link|header|footer|auth|login|signin|signout|logout|session|cookie|token|true|false|null|undefined|error|success|failed|warn|info|debug|trace|admin|user|root|for|test|testing|staging|placeholder|password|pass|pwd|psswrd|passwrod|token|key|api[_-]?key|secret|hidden|entered|shown|verified)$/i;function l(r,e,o){if(!o||o===p||o.length<1||o.includes(p)||o.includes("__PROTECTED_"))return r;let _=o.replace(/["']/g,"").trim();if(_.length<2||w.test(_)||_.toLowerCase()===e.toLowerCase())return r;let a=r.toLowerCase().indexOf(e.toLowerCase());if(a===-1)return r;let t=r.substring(a+e.length).indexOf(o);if(t===-1)return r;let n=a+e.length+t;return r.substring(0,n)+p+r.substring(n+o.length)}function L(r){return r.replace(/(?<!\w)([A-Za-z\d@$!%*#?&^()_\-+=]{7,64})(?!\w)/g,e=>{if(/^__PROTECTED_/.test(e)||e.includes(p)||w.test(e))return e;let o=/[A-Z]/.test(e),_=/[a-z]/.test(e),a=/\d/.test(e),s=/[@$!%*#?&^()_\-+=]/.test(e);return[o,_,a,s].filter(Boolean).length>=3?p:e})}function T(r){if(!r||typeof r!="string")return r;let e=r;e=e.replace(d.CONNECTION_STRING,"$1"+p+"@"),e=e.replace(d.QUERY_PARAM,"$1$2="+p),e=e.replace(d.XML_TAG,(s,t,n)=>`<${t}>${p}</${t}>`);let o=[];e=e.replace(d.URL,s=>{let t=`__PROTECTED_URL_${o.length}__`;return o.push(s),t});let _=[];e=e.replace(d.EMAIL,s=>{let t=`__PROTECTED_EMAIL_${_.length}__`;return _.push(s),t});let a=[];if(e=e.replace(d.MENTION,(s,t,n)=>{let i=`__PROTECTED_MENTION_${a.length}__`;return a.push(n),t+i}),e=e.replace(d.SQL_INSERT,(s,t,n)=>s.replace(n,p)),e=e.replace(d.HTML_INPUT,(s,t,n)=>{let i=t||n;return i?l(s,"password",i):s}),e=e.replace(d.AUTH_TOKEN,(s,t,n,i,c,u)=>{if(c&&u)return`${c} ${p}`;let E=n?`${n} `:"";return`${t}: ${E}${p}`}),e=e.replace(d.JWT,p),e=e.replace(d.BASE64_PASS,"cGFzc3dvcmQ9W1JFREFDVEVEX1BBU1NXT1JEXQ=="),e=e.replace(d.USER_PASS,(s,t,n,i,c)=>l(s,i,c)),e=e.replace(d.CURL_AUTH,"$1$2$3:"+p),e=e.replace(d.ASSIGNMENT,(s,t,n)=>l(s,t,n)),e=e.replace(d.SLASH_CRED,"$1/"+p),e=e.replace(d.LABEL_HINT,(s,t,n,i)=>{let c=l(s,t,n);return i&&(c=l(c,p,i)),c}),e.toLowerCase().includes("password")&&e.includes(",")){let s=e.split(/\r?\n/),t=-1,n=-1;for(let i=0;i<s.length;i++)if(s[i].includes(",")&&!s[i].toUpperCase().includes("VALUES")){let u=s[i].toLowerCase().split(",").findIndex(E=>E.includes("password")||E.trim()==="pwd");if(u!==-1){t=i,n=u;break}}if(t!==-1){for(let i=t+1;i<s.length;i++){let c=s[i].split(",");c.length>n&&c[n].trim().length>0&&(w.test(c[n].trim())||(c[n]=p,s[i]=c.join(",")))}e=s.join(`
|
|
2
|
+
`)}}return e=L(e),e=e.replace(/(\[REDACTED\]\s*){2,}/g,p+" "),o.forEach((s,t)=>{e=e.replace(`__PROTECTED_URL_${t}__`,s)}),_.forEach((s,t)=>{e=e.replace(`__PROTECTED_EMAIL_${t}__`,s)}),a.forEach((s,t)=>{e=e.replace(`__PROTECTED_MENTION_${t}__`,s)}),e}function I(r){if(!r||typeof r!="string")return{sanitized_text:""};let o=new f.JSDOM(`<body>${r}</body>`).window.document,_=a=>{a.nodeType===3?a.textContent&&(a.textContent=T(a.textContent)):a.childNodes.forEach(_)};return _(o.body),{sanitized_text:o.body.innerHTML.trim()}}var O=T;0&&(module.exports={sanitizeContent,sanitizeDescription});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{JSDOM as T}from"jsdom";var p={CONNECTION_STRING:/([a-z0-9+.-]+:\/\/)([^:@\s]+):([^:@\s]+)@/gi,SQL_INSERT:/\bINSERT\s+INTO\b.*?\((?:[^)]*,\s*)?\b(password|pwd|pass|passcode)\b.*?\)\s*VALUES\s*\((?:[^,']*,|[^,"]*,)*\s*['"]([^'"]+)['"]/gi,HTML_INPUT:/<input[^>]+(?:type=["']password["'](?:\s+[^>]*?)?value=["']([^"']*)["']|value=["']([^"']*)["'](?:\s+[^>]*?)?type=["']password["'])/gi,QUERY_PARAM:/([?&])(api[_-]?key|access[_-]?token|secret|password|pass|passwrod|psswrd|pw|pwd|token|key|auth[_-]?token|u|p|user|username|passcode|wifi[_-]?password|p_?w_?d|confirm[_-]?password|confirm[_-]?pwd)=([^&\s<"']+)/gi,AUTH_TOKEN:/\b(authorization|auth[_-]?token)\s*[:=]\s*(bearer|basic|token)?\s*([a-zA-Z0-9.\-_~+/]{8,})|(?:\b(bearer|basic|token)\s+([a-zA-Z0-9.\-_~+/]{8,}))/gi,JWT:/\beyJ[a-zA-Z0-9._-]{10,}\b/gi,BASE64_PASS:/cGFzc3dvcmQ9[a-zA-Z0-9+/=]+/g,USER_PASS:/\b(user(?:name)?|login)\b\s*[:=\s/]\s*([^"'\s,]+)\s*(?:and\s+)?\b(pass(?:word)?|pwd|p|p_?w_?d)\b\s*[:=\s]\s*([^"'\s<,]+)/gi,SLASH_CRED:/\b(admin|user|root|api_?user)\/([^"'\s,;]{3,})\b/gi,CURL_AUTH:/(^|\s)(-u\s+)([^:\s]+):([^:\s\\]+)/gi,ASSIGNMENT:/\b(DB[_-]?PASSWORD|JWT[_-]?SECRET|SECRET[_-]?KEY|AUTH[_-]?PASSWORD|PASSWORD|SECRET|KEY|WIFI[_-]?PASSWORD|PASSCODE|API[_-]?KEY|CONFIRM[_-]?PASSWORD|PASSWROD)\s*[:=]\s*(?:["']?)([^"'\s;<>]{3,})(?:["']?)/gi,XML_TAG:/<([^>]*password|pass|secret|token|key)>([^<]+)<\/\1>/gi,LABEL_HINT:/(?:\b|["'<])(password|pass|passwrod|psswrd|pw|pwd|api[_-]?key|access[_-]?token|auth[_-]?token|credentials|creds|secret|token|key|passcode|wifi[_-]?password|p_?w_?d|u|p|confirm[_-]?password|confirm[_-]?pwd|actual|temp|temporary|new\s+one|old\s+one|new\s+password|old\s+password)(?:\b|["'>])[^a-zA-Z0-9\s]*\s*(?:[:=\s]|was\s+something\s+like|it\s+was\s+something\s+like|was|is|like|should\s+be|actual\s+was|could\s+be|might\s+be|set\s+to|entered)(?:\s+it)?\s*[:=]?\s*(?:["']?)([^"'\s<>&,;?]+)(?:["']?)(?:\s+or\s+([^"'\s<>&,;?]+))?/gi,URL:/\bhttps?:\/\/[^\s"'<>]+/gi,EMAIL:/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g,MENTION:/(^|\s|[(\[])(@([a-zA-Z0-9._-]+))/g},a="[REDACTED]",g=/^(value|type|name|id|class|and|or|was|is|it|the|set|to|values|into|select|from|where|union|join|table|input|button|form|label|div|span|script|style|html|body|head|meta|link|header|footer|auth|login|signin|signout|logout|session|cookie|token|true|false|null|undefined|error|success|failed|warn|info|debug|trace|admin|user|root|for|test|testing|staging|placeholder|password|pass|pwd|psswrd|passwrod|token|key|api[_-]?key|secret|hidden|entered|shown|verified)$/i;function l(n,e,i){if(!i||i===a||i.length<1||i.includes(a)||i.includes("__PROTECTED_"))return n;let c=i.replace(/["']/g,"").trim();if(c.length<2||g.test(c)||c.toLowerCase()===e.toLowerCase())return n;let d=n.toLowerCase().indexOf(e.toLowerCase());if(d===-1)return n;let t=n.substring(d+e.length).indexOf(i);if(t===-1)return n;let r=d+e.length+t;return n.substring(0,r)+a+n.substring(r+i.length)}function f(n){return n.replace(/(?<!\w)([A-Za-z\d@$!%*#?&^()_\-+=]{7,64})(?!\w)/g,e=>{if(/^__PROTECTED_/.test(e)||e.includes(a)||g.test(e))return e;let i=/[A-Z]/.test(e),c=/[a-z]/.test(e),d=/\d/.test(e),s=/[@$!%*#?&^()_\-+=]/.test(e);return[i,c,d,s].filter(Boolean).length>=3?a:e})}function w(n){if(!n||typeof n!="string")return n;let e=n;e=e.replace(p.CONNECTION_STRING,"$1"+a+"@"),e=e.replace(p.QUERY_PARAM,"$1$2="+a),e=e.replace(p.XML_TAG,(s,t,r)=>`<${t}>${a}</${t}>`);let i=[];e=e.replace(p.URL,s=>{let t=`__PROTECTED_URL_${i.length}__`;return i.push(s),t});let c=[];e=e.replace(p.EMAIL,s=>{let t=`__PROTECTED_EMAIL_${c.length}__`;return c.push(s),t});let d=[];if(e=e.replace(p.MENTION,(s,t,r)=>{let o=`__PROTECTED_MENTION_${d.length}__`;return d.push(r),t+o}),e=e.replace(p.SQL_INSERT,(s,t,r)=>s.replace(r,a)),e=e.replace(p.HTML_INPUT,(s,t,r)=>{let o=t||r;return o?l(s,"password",o):s}),e=e.replace(p.AUTH_TOKEN,(s,t,r,o,_,u)=>{if(_&&u)return`${_} ${a}`;let E=r?`${r} `:"";return`${t}: ${E}${a}`}),e=e.replace(p.JWT,a),e=e.replace(p.BASE64_PASS,"cGFzc3dvcmQ9W1JFREFDVEVEX1BBU1NXT1JEXQ=="),e=e.replace(p.USER_PASS,(s,t,r,o,_)=>l(s,o,_)),e=e.replace(p.CURL_AUTH,"$1$2$3:"+a),e=e.replace(p.ASSIGNMENT,(s,t,r)=>l(s,t,r)),e=e.replace(p.SLASH_CRED,"$1/"+a),e=e.replace(p.LABEL_HINT,(s,t,r,o)=>{let _=l(s,t,r);return o&&(_=l(_,a,o)),_}),e.toLowerCase().includes("password")&&e.includes(",")){let s=e.split(/\r?\n/),t=-1,r=-1;for(let o=0;o<s.length;o++)if(s[o].includes(",")&&!s[o].toUpperCase().includes("VALUES")){let u=s[o].toLowerCase().split(",").findIndex(E=>E.includes("password")||E.trim()==="pwd");if(u!==-1){t=o,r=u;break}}if(t!==-1){for(let o=t+1;o<s.length;o++){let _=s[o].split(",");_.length>r&&_[r].trim().length>0&&(g.test(_[r].trim())||(_[r]=a,s[o]=_.join(",")))}e=s.join(`
|
|
2
|
+
`)}}return e=f(e),e=e.replace(/(\[REDACTED\]\s*){2,}/g,a+" "),i.forEach((s,t)=>{e=e.replace(`__PROTECTED_URL_${t}__`,s)}),c.forEach((s,t)=>{e=e.replace(`__PROTECTED_EMAIL_${t}__`,s)}),d.forEach((s,t)=>{e=e.replace(`__PROTECTED_MENTION_${t}__`,s)}),e}function S(n){if(!n||typeof n!="string")return{sanitized_text:""};let i=new T(`<body>${n}</body>`).window.document,c=d=>{d.nodeType===3?d.textContent&&(d.textContent=w(d.textContent)):d.childNodes.forEach(c)};return c(i.body),{sanitized_text:i.body.innerHTML.trim()}}var R=w;export{R as default,w as sanitizeContent,S as sanitizeDescription};
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sanitize-contents",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A robust library to sanitize sensitive information from content.",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsup src/index.ts --format cjs,esm --dts --clean --minify",
|
|
20
|
+
"test": "vitest run",
|
|
21
|
+
"test:watch": "vitest",
|
|
22
|
+
"lint": "eslint src/**/*.ts",
|
|
23
|
+
"prepublishOnly": "npm run build"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"sanitize",
|
|
27
|
+
"redact",
|
|
28
|
+
"security",
|
|
29
|
+
"password",
|
|
30
|
+
"sensitive",
|
|
31
|
+
"content"
|
|
32
|
+
],
|
|
33
|
+
"author": "Kishan",
|
|
34
|
+
"license": "ISC",
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"tsup": "^8.0.1",
|
|
37
|
+
"typescript": "^5.3.3",
|
|
38
|
+
"vitest": "^1.2.1"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@types/jsdom": "^27.0.0",
|
|
42
|
+
"jsdom": "^27.3.0"
|
|
43
|
+
}
|
|
44
|
+
}
|