http-referrer-policy 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 +57 -0
- package/lib/referrer-policy.js +152 -0
- package/package.json +21 -0
package/README.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# HTTP Referrer Policy
|
|
2
|
+
[](https://npmjs.com/package/http-referrer-policy)
|
|
3
|
+
[](https://npmjs.com/package/http-referrer-policy)
|
|
4
|
+
[](https://npmjs.com/package/http-referrer-policy)
|
|
5
|
+
|
|
6
|
+
## Installation
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
npm install --save http-referrer-policy
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
```js
|
|
15
|
+
const referrerPolicy = require( 'http-referrer-policy' )
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
```js
|
|
19
|
+
import referrerPolicy from 'http-referrer-policy'
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## API
|
|
23
|
+
|
|
24
|
+
### Constants
|
|
25
|
+
|
|
26
|
+
- readonly string `referrerPolicy.default` - Default policy directive ('strict-origin-when-cross-origin')
|
|
27
|
+
- readonly array\<string\> `referrerPolicy.directives` - List of supported referrer policy directives
|
|
28
|
+
|
|
29
|
+
### Methods
|
|
30
|
+
|
|
31
|
+
#### `referrerPolicy.select( directives, fallback )`
|
|
32
|
+
|
|
33
|
+
Select the most restrictive policy from a given `Referrer-Policy` value,
|
|
34
|
+
returning the fallback policy if no value is given or selected.
|
|
35
|
+
If no fallback policy is given, `referrerPolicy.default` is returned.
|
|
36
|
+
|
|
37
|
+
- string `directives`: `Referrer-Policy` header field value
|
|
38
|
+
- string `fallback`: Optional. Fallback policy directive.
|
|
39
|
+
|
|
40
|
+
Returns `string`
|
|
41
|
+
|
|
42
|
+
#### `referrerPolicy.url( from, to, directives, fallback )`
|
|
43
|
+
|
|
44
|
+
Constructs the value of a `Referer` header based on
|
|
45
|
+
the policy directive and navigation endpoint URLs.
|
|
46
|
+
|
|
47
|
+
- string|URL `from`: Current (referring) URL.
|
|
48
|
+
- string|URL `to`: URL being navigated to.
|
|
49
|
+
- string `directives`: `Referer-Policy` directive.
|
|
50
|
+
- string `fallback`: Optional. Fallback policy directive.
|
|
51
|
+
|
|
52
|
+
Returns `string`
|
|
53
|
+
|
|
54
|
+
## Resources
|
|
55
|
+
|
|
56
|
+
- Specification: [W3C / webappsec-referrer-policy](https://w3c.github.io/webappsec-referrer-policy/#referrer-policies)
|
|
57
|
+
- MDN: [Headers / Referrer-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Referrer-Policy)
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
const policyDirectives = [
|
|
2
|
+
'no-referrer',
|
|
3
|
+
'no-referrer-when-downgrade',
|
|
4
|
+
'same-origin',
|
|
5
|
+
'origin',
|
|
6
|
+
'strict-origin',
|
|
7
|
+
'origin-when-cross-origin',
|
|
8
|
+
'strict-origin-when-cross-origin',
|
|
9
|
+
'unsafe-url',
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
function _isDowngrade( ref, dst ) {
|
|
13
|
+
switch( ref.protocol ) {
|
|
14
|
+
case 'https:': return dst.protocol != 'https:' && dst.protocol != 'wss:'
|
|
15
|
+
case 'wss:': return dst.protocol != 'https:' && dst.protocol != 'wss:'
|
|
16
|
+
default: return false
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
class ReferrerPolicy {
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The default referrer policy as per specification is 'strict-origin-when-cross-origin'.
|
|
24
|
+
* @see https://w3c.github.io/webappsec-referrer-policy/#referrer-policies
|
|
25
|
+
* @type {String}
|
|
26
|
+
*/
|
|
27
|
+
static get default() { return 'strict-origin-when-cross-origin' }
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Set of supported directives
|
|
31
|
+
* @type {Array<String>}
|
|
32
|
+
*/
|
|
33
|
+
static directives = policyDirectives.slice()
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Select the most restrictive policy from a given `Referrer-Policy` value,
|
|
37
|
+
* using the fallback policy if no policy is resolved.
|
|
38
|
+
* If no fallback policy is given, `ReferrerPolicy.default` is used.
|
|
39
|
+
* @param {String|null} value
|
|
40
|
+
* @param {String} [fallback]
|
|
41
|
+
* @returns {String}
|
|
42
|
+
*/
|
|
43
|
+
static select( value, fallback ) {
|
|
44
|
+
|
|
45
|
+
if( fallback != null && typeof fallback != 'string' ) {
|
|
46
|
+
throw new TypeError( 'Referrer-policy fallback must be a string' )
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// The empty string "" corresponds to no referrer policy, causing a fallback to a
|
|
50
|
+
// referrer policy defined elsewhere, or in the case where no such higher-level
|
|
51
|
+
// policy is available, falling back to the default referrer policy.
|
|
52
|
+
if( value == null || value == '' ) {
|
|
53
|
+
return fallback || ReferrerPolicy.default
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if( typeof value != 'string' ) {
|
|
57
|
+
throw new TypeError( 'Referrer-policy must be a string' )
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
var directives = value.split( /\s*,\s*/g )
|
|
61
|
+
var selected = ''
|
|
62
|
+
|
|
63
|
+
// Multiple fallback policies can be specified in the Referrer-Policy header,
|
|
64
|
+
// with increasing preference; the first policy being the least desired.
|
|
65
|
+
for( let directive of directives ) {
|
|
66
|
+
directive = directive.trim().toLowerCase()
|
|
67
|
+
// Use this directive, if we understand it
|
|
68
|
+
if( policyDirectives.includes( directive ) ) {
|
|
69
|
+
selected = directive
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return selected || fallback || ReferrerPolicy.default
|
|
74
|
+
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Construct the value of a `Referer` header based on
|
|
79
|
+
* the policy directive and navigation endpoint URLs.
|
|
80
|
+
* @param {String|URL} from - Current URL
|
|
81
|
+
* @param {String|URL} to - Destination URL
|
|
82
|
+
* @param {String} [value] - Referrer-Policy header value
|
|
83
|
+
* @param {String} [fallback] - Fallback policy directive
|
|
84
|
+
* @returns {String}
|
|
85
|
+
*/
|
|
86
|
+
static url( from, to, value, fallback ) {
|
|
87
|
+
|
|
88
|
+
const directive = ReferrerPolicy.select( value, fallback )
|
|
89
|
+
|
|
90
|
+
// Do not include any referrer information
|
|
91
|
+
if( directive == 'no-referrer' ) return '';
|
|
92
|
+
|
|
93
|
+
var ref = new URL( from )
|
|
94
|
+
var dst = new URL( to )
|
|
95
|
+
|
|
96
|
+
// Always strip auth
|
|
97
|
+
ref.username = ''
|
|
98
|
+
ref.password = ''
|
|
99
|
+
|
|
100
|
+
var isSameOrigin = ref.origin == dst.origin
|
|
101
|
+
var isDowngrade = _isDowngrade( ref, dst )
|
|
102
|
+
|
|
103
|
+
switch( directive ) {
|
|
104
|
+
|
|
105
|
+
// Send only the origin in the `Referer` header.
|
|
106
|
+
case 'origin':
|
|
107
|
+
return ref.origin
|
|
108
|
+
|
|
109
|
+
// Send only the origin when the protocol security level stays the same (HTTPS->HTTPS).
|
|
110
|
+
// Don't send the `Referer` header to less secure destinations (HTTPS->HTTP).
|
|
111
|
+
case 'strict-origin':
|
|
112
|
+
return ref.protocol == dst.protocol ? ref.origin : ''
|
|
113
|
+
|
|
114
|
+
// Send the origin, path, and query string for same-origin requests.
|
|
115
|
+
// Don't send the `Referer` header for cross-origin requests.
|
|
116
|
+
case 'same-origin':
|
|
117
|
+
return isSameOrigin ? ref.toString() : ''
|
|
118
|
+
|
|
119
|
+
// When performing a same-origin request to the same protocol level
|
|
120
|
+
// (HTTP->HTTP, HTTPS->HTTPS), send the origin, path, and query string.
|
|
121
|
+
// Send only the origin for cross origin requests and requests to
|
|
122
|
+
// less secure destinations (HTTPS->HTTP).
|
|
123
|
+
case 'origin-when-cross-origin':
|
|
124
|
+
return isSameOrigin ? ref.toString() : ref.origin
|
|
125
|
+
|
|
126
|
+
// Send the origin, path, and query string when performing a same-origin request.
|
|
127
|
+
// For cross-origin requests send the origin (only) when the protocol security level stays same (HTTPS->HTTPS).
|
|
128
|
+
// Don't send the `Referer` header to less secure destinations (HTTPS->HTTP).
|
|
129
|
+
case 'strict-origin-when-cross-origin':
|
|
130
|
+
return isSameOrigin ? ref.toString() : ( !isDowngrade ? ref.origin : '' )
|
|
131
|
+
|
|
132
|
+
// Send the origin, path, and query string in `Referer` when the protocol
|
|
133
|
+
// security level stays the same or improves.
|
|
134
|
+
case 'no-referrer-when-downgrade':
|
|
135
|
+
return !isDowngrade ? ref.toString() : ''
|
|
136
|
+
|
|
137
|
+
// Send the origin, path, and query string when
|
|
138
|
+
// performing any request, regardless of security.
|
|
139
|
+
case 'unsafe-url':
|
|
140
|
+
return ref.toString()
|
|
141
|
+
|
|
142
|
+
default:
|
|
143
|
+
throw new Error( 'Invalid or unsupported referrer policy' )
|
|
144
|
+
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export default ReferrerPolicy
|
|
152
|
+
export { ReferrerPolicy as 'module.exports' }
|
package/package.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "module",
|
|
3
|
+
"name": "http-referrer-policy",
|
|
4
|
+
"description": "HTTP Referrer-Policy",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"main": "lib/referrer-policy.js",
|
|
7
|
+
"homepage": "https://codeberg.org/jhermsmeier/node-http-referrer-policy",
|
|
8
|
+
"bugs": {
|
|
9
|
+
"url": "https://codeberg.org/jhermsmeier/node-http-referrer-policy/issues"
|
|
10
|
+
},
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://codeberg.org/jhermsmeier/node-http-referrer-policy.git"
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"test": "control"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@jhermsmeier/control": "2.0.4"
|
|
20
|
+
}
|
|
21
|
+
}
|