@contrast/agent 4.28.1 → 4.29.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/lib/app-info.js CHANGED
@@ -18,22 +18,35 @@ const fs = require('fs');
18
18
  const path = require('path');
19
19
  const parentPackageJson = require('parent-package-json');
20
20
  const semver = require('semver');
21
+ const { v4: uuid } = require('uuid');
21
22
  const { AGENT_INFO } = require('./constants');
22
23
  const logger = require('./core/logger')('contrast:appInfo');
23
24
 
24
- const isContainer = () => {
25
+ const MOUNTINFO_REGEX = /\/docker\/containers\/(.*?)\//;
26
+ const CGROUP_REGEX = /:\/docker\/([^/]+)$/;
27
+
28
+ const getContainerId = () => {
25
29
  try {
26
- fs.statSync('/.dockerenv');
27
- return true;
30
+ const results = fs.readFileSync('/proc/self/mountinfo', 'utf8').match(MOUNTINFO_REGEX);
31
+
32
+ if (results) return results[1];
28
33
  } catch (err) {
29
- // if no docker env, check /proc/self/cgroup
34
+ //
30
35
  }
31
36
 
32
37
  try {
33
- return fs.readFileSync('/proc/self/cgroup', 'utf8').includes('docker');
38
+ const results = fs.readFileSync('/proc/self/cgroup', 'utf8').match(CGROUP_REGEX);
39
+
40
+ if (results) return results[1];
41
+ } catch (err) {
42
+ //
43
+ }
44
+
45
+ try {
46
+ fs.statSync('/.dockerenv');
47
+ return `_${uuid()}`;
34
48
  } catch (err) {
35
- // if file not present,
36
- return false;
49
+ return null;
37
50
  }
38
51
  };
39
52
 
@@ -69,7 +82,7 @@ class AppInfo {
69
82
  type: os.type()
70
83
  };
71
84
  this.hostname = os.hostname();
72
- this.isContainer = isContainer();
85
+ this.containerId = getContainerId();
73
86
 
74
87
  logger.info('finding package.json for %s', this.indexFile);
75
88
 
@@ -555,6 +555,48 @@
555
555
  }
556
556
  ]
557
557
  }
558
+ },
559
+ "mssql/lib/base/prepared-statement.prototype.prepare": {
560
+ "type": "dataflow",
561
+ "enabled": true,
562
+ "conditions": {
563
+ "mode": "or",
564
+ "args": [
565
+ {
566
+ "index": 0,
567
+ "requiredTags": ["untrusted"],
568
+ "disallowedTags": ["sql-encoded", "limited-chars"]
569
+ }
570
+ ]
571
+ }
572
+ },
573
+ "mssql/lib/base/request.prototype.batch": {
574
+ "type": "dataflow",
575
+ "enabled": true,
576
+ "conditions": {
577
+ "mode": "or",
578
+ "args": [
579
+ {
580
+ "index": 0,
581
+ "requiredTags": ["untrusted"],
582
+ "disallowedTags": ["sql-encoded", "limited-chars"]
583
+ }
584
+ ]
585
+ }
586
+ },
587
+ "mssql/lib/base/request.prototype.query": {
588
+ "type": "dataflow",
589
+ "enabled": true,
590
+ "conditions": {
591
+ "mode": "or",
592
+ "args": [
593
+ {
594
+ "index": 0,
595
+ "requiredTags": ["untrusted"],
596
+ "disallowedTags": ["sql-encoded", "limited-chars"]
597
+ }
598
+ ]
599
+ }
558
600
  }
559
601
  }
560
602
  },
@@ -626,6 +626,24 @@
626
626
  "methodName": "Database.prototype.prepare",
627
627
  "isModule": true
628
628
  },
629
+ "mssql/lib/base/prepared-statement.prototype.prepare": {
630
+ "moduleName": "mssql",
631
+ "version": ">=6.4.0",
632
+ "methodName": "PreparedStatement.prototype.prepare",
633
+ "isModule": true
634
+ },
635
+ "mssql/lib/base/request.prototype.batch": {
636
+ "moduleName": "mssql",
637
+ "version": ">=6.4.0",
638
+ "methodName": "Request.prototype.batch",
639
+ "isModule": true
640
+ },
641
+ "mssql/lib/base/request.prototype.query": {
642
+ "moduleName": "mssql",
643
+ "version": ">=6.4.0",
644
+ "methodName": "Request.prototype.query",
645
+ "isModule": true
646
+ },
629
647
  "path.format": {
630
648
  "moduleName": "path",
631
649
  "methodName": "format",
package/lib/telemetry.js CHANGED
@@ -74,12 +74,18 @@ module.exports = class Telemetry {
74
74
  const mac = getMac();
75
75
 
76
76
  const hash = createHash('sha256').update(mac);
77
+ if (appInfo.containerId) {
78
+ hash.update(appInfo.containerId);
79
+ }
77
80
  this.instanceId = hash.copy().digest('hex');
78
81
  this.applicationId = hash.update(appInfo.name).digest('hex');
79
82
  } catch (err) {
80
83
  // If getMac fails we fall back to generating a UUID. "Unstable"
81
84
  // identifiers such as these are prefixed with an underscore.
82
- const id = uuid();
85
+ let id = uuid();
86
+ if (appInfo.containerId) {
87
+ id += `_${appInfo.containerId}`;
88
+ }
83
89
 
84
90
  this.instanceId = `_${id}`;
85
91
  this.applicationId = this.instanceId;
@@ -92,7 +98,7 @@ module.exports = class Telemetry {
92
98
  osArch: appInfo.os.architecture,
93
99
  osPlatform: appInfo.os.platform,
94
100
  osRelease: appInfo.os.release,
95
- isContainer: appInfo.isContainer,
101
+ isContainer: !!appInfo.containerId,
96
102
  agent: AGENT_INFO.NAME,
97
103
  agentVersion: AGENT_INFO.VERSION,
98
104
  isAssess: agent.isInAssessMode(),
@@ -59,14 +59,12 @@ const init = function init(config) {
59
59
  let count = 0;
60
60
 
61
61
  const interval = setInterval(() => {
62
- if (count >= config.count) {
63
- clearInterval(interval);
64
- return;
65
- }
66
-
67
62
  writeHeapSnapshot(config.path);
68
-
69
63
  count++;
64
+
65
+ if (count === config.count) {
66
+ clearInterval(interval);
67
+ }
70
68
  }, config.window_ms);
71
69
  }, config.delay_ms).unref();
72
70
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/agent",
3
- "version": "4.28.1",
3
+ "version": "4.29.0",
4
4
  "description": "Node.js security instrumentation by Contrast Security",
5
5
  "keywords": [
6
6
  "security",
@@ -40,14 +40,22 @@ function isContainer() {
40
40
  fs.statSync('/.dockerenv');
41
41
  return true;
42
42
  } catch (err) {
43
- // if no docker env, check /proc/self/cgroup
43
+ // if no docker env, check /proc/self/mountinfo
44
+ }
45
+
46
+ try {
47
+ return fs.readFileSync('proc/self/mountinfo', 'utf8').includes('docker/containers/');
48
+ } catch (err) {
49
+ // else check /proc/self/cgroup
44
50
  }
45
51
 
46
52
  try {
47
53
  return fs.readFileSync('/proc/self/cgroup', 'utf8').includes('docker');
48
54
  } catch (err) {
49
- return false;
55
+ // if there's not such file we can conclude it's not docker env
50
56
  }
57
+
58
+ return false;
51
59
  }
52
60
 
53
61
  function isUsingPM2() {
@@ -55,11 +63,11 @@ function isUsingPM2() {
55
63
  let version = null;
56
64
 
57
65
  for (const pathVar of ['npm_package_json', 'PWD']) {
58
- let packagePath;
59
- if (packagePath = process.env[pathVar]) {
66
+ const packagePath = process.env[pathVar];
67
+ if (packagePath) {
60
68
  try {
61
- version = require(path.join(packagePath, 'package.json'));
62
- } catch(err) {
69
+ version = require(path.join(packagePath, 'package.json')).dependencies['pm2'];
70
+ } catch (err) {
63
71
  //
64
72
  }
65
73
  }
@@ -142,7 +150,6 @@ const diagnostics = {
142
150
  Node: {
143
151
  Version: process.version
144
152
  },
145
- PM2: isUsingPM2(),
146
153
  OperatingSystem: {
147
154
  Architecture: os.arch(),
148
155
  Name: os.type(),
@@ -155,12 +162,14 @@ const diagnostics = {
155
162
  },
156
163
  Host: {
157
164
  isDocker: isContainer(),
165
+ PM2: isUsingPM2(),
158
166
  Memory: {
159
167
  Total: (os.totalmem() / 1e6).toFixed(0).concat(' MB'),
160
168
  Free: (os.freemem() / 1e6).toFixed(0).concat(' MB'),
161
169
  Used: ((os.totalmem() - os.freemem()) / 1e6).toFixed(0).concat(' MB'),
162
170
  }
163
171
  },
172
+ Application: require(path.join(process.env['PWD'], 'package.json')),
164
173
  };
165
174
 
166
175
  return info;