zsyp 0.0.1 → 1.0.1
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 +59 -16
- package/lib/csp.js +12 -27
- package/lib/filter.js +23 -0
- package/package.json +3 -3
- package/History.md +0 -5
package/Readme.md
CHANGED
|
@@ -1,38 +1,81 @@
|
|
|
1
1
|
[![NPM version][npm-image]][npm-url]
|
|
2
|
-
[![Build Status][
|
|
2
|
+
[![Build Status][build-image]][build-url]
|
|
3
3
|
[![Dependency Status][deps-image]][deps-url]
|
|
4
|
-
[![Dev Dependency Status][deps-dev-image]][deps-dev-url]
|
|
5
4
|
|
|
6
5
|
# zsyp
|
|
7
6
|
|
|
8
|
-
CSP violation reports logger.
|
|
7
|
+
[CSP] violation reports logger. Zsyp is a simple standalone web service that parses CPS violation reports
|
|
8
|
+
and stores them in MongoDB collection.
|
|
9
9
|
|
|
10
10
|
## Install
|
|
11
11
|
|
|
12
12
|
```sh
|
|
13
|
-
|
|
13
|
+
npm install --global zsyp
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
##
|
|
16
|
+
## Environment
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
var zsyp = require('zsyp');
|
|
18
|
+
Zsyp is using [dotenv] and by default reads its environment from `/etc/default/zsyp`
|
|
20
19
|
|
|
21
|
-
|
|
20
|
+
- `ZSYP_PORT` - port number on which, defaults to 3090
|
|
21
|
+
- `ZSYP_DB` - [mongo URI] connection string, defaults to `mongodb://localhost/zsyp`
|
|
22
|
+
- `ZSYP_DOMAINS` - domain name or a regular expression used to filter CSP violation reports - can be left empty in which case all reports for all domains are logged
|
|
23
|
+
|
|
24
|
+
## Report format
|
|
25
|
+
|
|
26
|
+
```json5
|
|
27
|
+
{
|
|
28
|
+
"from": {
|
|
29
|
+
"ua": "Mozilla/5.0 (Macintosh; Intel Mac OS...", // User-Agent string
|
|
30
|
+
"browser": { // browser brand and version
|
|
31
|
+
"name": "Safari",
|
|
32
|
+
"version": "13"
|
|
33
|
+
},
|
|
34
|
+
"os": { // operating system info
|
|
35
|
+
"name": "Mac OS X",
|
|
36
|
+
"version": "10"
|
|
37
|
+
},
|
|
38
|
+
"ip": "1.2.3.4" // originator IP address
|
|
39
|
+
},
|
|
40
|
+
"csp-report": { // original CSP report
|
|
41
|
+
"document-uri": "https://example.com/page",
|
|
42
|
+
"referrer": "https://example.com/",
|
|
43
|
+
"violated-directive": "...",
|
|
44
|
+
"effective-directive": "...",
|
|
45
|
+
"original-policy": "...",
|
|
46
|
+
"blocked-uri": "",
|
|
47
|
+
"status-code": 0,
|
|
48
|
+
"source-file": "..."
|
|
49
|
+
}
|
|
50
|
+
}
|
|
22
51
|
```
|
|
23
52
|
|
|
53
|
+
|
|
54
|
+
## Logger
|
|
55
|
+
|
|
56
|
+
Reports are stored in `csp` collection. If you want to use [capped collection] create it
|
|
57
|
+
manually before running zsyp.
|
|
58
|
+
|
|
59
|
+
```javascript
|
|
60
|
+
db.createCollection( "csp", { capped: true, size: 100000 } );
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
|
|
24
64
|
## License
|
|
25
65
|
|
|
26
66
|
MIT © [Damian Krzeminski](https://pirxpilot.me)
|
|
27
67
|
|
|
28
|
-
[npm-image]: https://img.shields.io/npm/v/zsyp.svg
|
|
29
|
-
[npm-url]: https://npmjs.org/package/zsyp
|
|
30
68
|
|
|
31
|
-
[
|
|
32
|
-
[
|
|
69
|
+
[CSP]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
|
|
70
|
+
[mongo URI]: https://docs.mongodb.com/manual/reference/connection-string
|
|
71
|
+
[capped collection]: https://docs.mongodb.com/manual/core/capped-collections/
|
|
72
|
+
[dotenv]: https://www.npmjs.com/package/dotenv
|
|
73
|
+
|
|
74
|
+
[npm-image]: https://img.shields.io/npm/v/zsyp
|
|
75
|
+
[npm-url]: https://npmjs.org/package/zsyp
|
|
33
76
|
|
|
34
|
-
[
|
|
35
|
-
[
|
|
77
|
+
[build-url]: https://travis-ci.com/pirxpilot/zsyp
|
|
78
|
+
[build-image]: https://img.shields.io/travis/com/pirxpilot/zsyp
|
|
36
79
|
|
|
37
|
-
[deps-
|
|
38
|
-
[deps-
|
|
80
|
+
[deps-image]: https://img.shields.io/librariesio/release/npm/zsyp
|
|
81
|
+
[deps-url]: https://libraries.io/npm/zsyp
|
package/lib/csp.js
CHANGED
|
@@ -2,8 +2,7 @@ const Router = require('router');
|
|
|
2
2
|
const { json } = require('body-parser');
|
|
3
3
|
|
|
4
4
|
const from = require('./from');
|
|
5
|
-
|
|
6
|
-
/* global URL */
|
|
5
|
+
const makeFilter = require('./filter');
|
|
7
6
|
|
|
8
7
|
function respond(req, res, next) {
|
|
9
8
|
res.statusCode = 204; // empty
|
|
@@ -12,38 +11,24 @@ function respond(req, res, next) {
|
|
|
12
11
|
}
|
|
13
12
|
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
function filter(csp) {
|
|
21
|
-
if (!domainRe) {
|
|
22
|
-
return true;
|
|
23
|
-
}
|
|
24
|
-
const { hostname } = new URL(csp['document-uri']);
|
|
25
|
-
return domainRe.test(hostname);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function log({ from, body: csp, log }) {
|
|
29
|
-
|
|
30
|
-
if (!filter(csp)) {
|
|
31
|
-
// skip reports for domains we are not interested in
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
14
|
+
function log({ from, body: csp, log }) {
|
|
15
|
+
const report = {
|
|
16
|
+
from,
|
|
17
|
+
...csp
|
|
18
|
+
};
|
|
34
19
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
...csp
|
|
38
|
-
};
|
|
20
|
+
log(report);
|
|
21
|
+
}
|
|
39
22
|
|
|
40
|
-
|
|
41
|
-
|
|
23
|
+
module.exports = function (opts) {
|
|
24
|
+
const router = new Router();
|
|
25
|
+
const filter = makeFilter(opts);
|
|
42
26
|
|
|
43
27
|
router.post('/csp',
|
|
44
28
|
from,
|
|
45
29
|
json({ limit: 5000, type: [ '*/json', 'application/csp-report' ] }),
|
|
46
30
|
respond,
|
|
31
|
+
filter,
|
|
47
32
|
log
|
|
48
33
|
);
|
|
49
34
|
|
package/lib/filter.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module.exports = makeFilter;
|
|
2
|
+
|
|
3
|
+
/* global URL */
|
|
4
|
+
|
|
5
|
+
function makeFilter({ domains }) {
|
|
6
|
+
|
|
7
|
+
const domainRe = domains && new RegExp(domains);
|
|
8
|
+
|
|
9
|
+
return filter;
|
|
10
|
+
|
|
11
|
+
function filter({ body: csp }, res, next) {
|
|
12
|
+
if (!domainRe) {
|
|
13
|
+
return next();
|
|
14
|
+
}
|
|
15
|
+
const uri = csp['csp-report']['document-uri'];
|
|
16
|
+
const { hostname } = new URL(uri);
|
|
17
|
+
if (domainRe.test(hostname)) {
|
|
18
|
+
console.log('OK!!!!!!!!');
|
|
19
|
+
return next();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zsyp",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "CSP violation reports logger.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Damian Krzeminski",
|
|
@@ -19,14 +19,14 @@
|
|
|
19
19
|
"@pirxpilot/connect": "^4.0.0",
|
|
20
20
|
"body-parser": "~1",
|
|
21
21
|
"debug": "~2 || ~3 || ~4",
|
|
22
|
-
"dotenv": "~
|
|
22
|
+
"dotenv": "~16",
|
|
23
23
|
"mniam": "^2.1.0",
|
|
24
24
|
"router": "~1",
|
|
25
25
|
"useragent": "^2.3.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"jshint": "~2",
|
|
29
|
-
"tape": "~
|
|
29
|
+
"tape": "~5"
|
|
30
30
|
},
|
|
31
31
|
"scripts": {
|
|
32
32
|
"test": "make check"
|