Skip to content

Commit d0ebcdc

Browse files
authored
fix(security): tweak strict SRI regex (#10)
The previous form was vulnerable to ReDoS attacks, by crafting exceptionally long base64 hash strings. This issue only affected consumers using the opts.strict option.
1 parent 427f423 commit d0ebcdc

File tree

3 files changed

+12
-9
lines changed

3 files changed

+12
-9
lines changed

index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const SPEC_ALGORITHMS = ['sha256', 'sha384', 'sha512']
99

1010
const BASE64_REGEX = /^[a-z0-9+/]+(?:=?=?)$/i
1111
const SRI_REGEX = /^([^-]+)-([^?]+)([?\S*]*)$/
12-
const STRICT_SRI_REGEX = /^([^-]+)-([A-Za-z0-9+/]+(?:=?=?))([?\x21-\x7E]*)$/
12+
const STRICT_SRI_REGEX = /^([^-]+)-([A-Za-z0-9+/=]{44,88})(\?[\x21-\x7E]*)*$/
1313
const VCHAR_REGEX = /^[\x21-\x7E]+$/
1414

1515
class Hash {

test/integrity.js

+9-6
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,20 @@ const test = require('tap').test
77
const ssri = require('..')
88

99
test('toString()', t => {
10-
const sri = ssri.parse('sha512-foo sha256-bar!')
10+
const sri = ssri.parse('sha1-eUN/Xt2hP5wGabl43XqQZt0gWfE= sha256-Qhx213Vjr6GRSEawEL0WTzlb00whAuXpngy5zxc8HYc=')
1111
t.equal(
1212
sri.toString(),
13-
'sha512-foo sha256-bar!',
13+
'sha1-eUN/Xt2hP5wGabl43XqQZt0gWfE= sha256-Qhx213Vjr6GRSEawEL0WTzlb00whAuXpngy5zxc8HYc=',
1414
'integrity objects from ssri.parse() can use toString()'
1515
)
1616
t.equal(
1717
sri.toString({strict: true}),
18-
'sha512-foo',
18+
'sha256-Qhx213Vjr6GRSEawEL0WTzlb00whAuXpngy5zxc8HYc=',
1919
'accepts strict mode option'
2020
)
2121
t.equal(
2222
sri.toString({sep: '\n'}),
23-
'sha512-foo\nsha256-bar!',
23+
'sha1-eUN/Xt2hP5wGabl43XqQZt0gWfE=\nsha256-Qhx213Vjr6GRSEawEL0WTzlb00whAuXpngy5zxc8HYc=',
2424
'accepts separator option'
2525
)
2626
t.done()
@@ -72,9 +72,12 @@ test('concat()', t => {
7272
'sha512-foo sha512-quux sha1-bar sha1-baz',
7373
'preserves relative order for algorithms between different concatenations'
7474
)
75+
const strictSri = ssri.parse('sha512-WrLorGiX4iEWOOOaJSiCrmDIamA47exH+Bz7tVwIPb4sCU8w4iNqGCqYuspMMeU5pgz/sU7koP5u8W3RCUojGw==')
7576
t.equal(
76-
sri.concat('sha1-bar!', {strict: true}).toString(),
77-
'sha512-foo',
77+
strictSri.concat('sha1-eUN/Xt2hP5wGabl43XqQZt0gWfE=', {
78+
strict: true
79+
}).toString(),
80+
'sha512-WrLorGiX4iEWOOOaJSiCrmDIamA47exH+Bz7tVwIPb4sCU8w4iNqGCqYuspMMeU5pgz/sU7koP5u8W3RCUojGw==',
7881
'accepts strict mode option'
7982
)
8083
t.done()

test/stringify.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@ test('support strict serialization', t => {
108108
'entries that do not conform to strict spec interpretation removed'
109109
)
110110
t.equal(
111-
ssri.stringify('sha512-foo sha256-bar', {sep: ' \r|\n\t', strict: true}),
112-
'sha512-foo \r \n\tsha256-bar',
111+
ssri.stringify('sha512-WrLorGiX4iEWOOOaJSiCrmDIamA47exH+Bz7tVwIPb4sCU8w4iNqGCqYuspMMeU5pgz/sU7koP5u8W3RCUojGw== sha256-Qhx213Vjr6GRSEawEL0WTzlb00whAuXpngy5zxc8HYc=', {sep: ' \r|\n\t', strict: true}),
112+
'sha512-WrLorGiX4iEWOOOaJSiCrmDIamA47exH+Bz7tVwIPb4sCU8w4iNqGCqYuspMMeU5pgz/sU7koP5u8W3RCUojGw== \r \n\tsha256-Qhx213Vjr6GRSEawEL0WTzlb00whAuXpngy5zxc8HYc=',
113113
'strict mode replaces non-whitespace characters in separator with space'
114114
)
115115
t.done()

0 commit comments

Comments
 (0)