Skip to content

Commit 04e95ce

Browse files
authored
Remove SRI check for loaded resources (#210)
1 parent 85713db commit 04e95ce

File tree

3 files changed

+82
-42
lines changed

3 files changed

+82
-42
lines changed

lib/resource-handler/html/html-source-element.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ class HtmlSourceElement {
4343
this.rule.attr ? this.el.attr(this.rule.attr, newData) : this.el.text(newData);
4444
}
4545

46+
removeIntegrityCheck () {
47+
if (this.el.attr('integrity')) {
48+
this.el.attr('integrity', null);
49+
}
50+
}
51+
4652
/**
4753
* Returns PathContainer instance for element
4854
* @returns {CssText|HtmlCommonTag|HtmlImgSrcSetTag|null}

lib/resource-handler/html/index.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ class HtmlResourceHandler {
2525

2626
loadResourcesForRule ($, parentResource, rule) {
2727
const self = this;
28-
const promises = $(rule.selector).map(function loadForElement () {
29-
const el = new HtmlSourceElement($(this), rule);
28+
const promises = $(rule.selector).map((i, element) => {
29+
const el = new HtmlSourceElement($(element), rule);
3030

3131
const isRecursive = self.options.recursiveSources && Boolean(el.findMatchedRule(self.options.recursiveSources));
3232
const isDepthGreaterThanMax = self.options.maxRecursiveDepth && parentResource.getDepth() >= self.options.maxRecursiveDepth;
@@ -39,7 +39,10 @@ class HtmlResourceHandler {
3939
if (!pathContainer) {
4040
return Promise.resolve();
4141
}
42-
return self.handleChildrenPaths(pathContainer, parentResource).then(el.setData.bind(el));
42+
return self.handleChildrenPaths(pathContainer, parentResource).then((updatedText) => {
43+
el.setData(updatedText);
44+
el.removeIntegrityCheck();
45+
});
4346
}).get();
4447

4548
return utils.waitAllFulfilled(promises);
Lines changed: 70 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,99 @@
1+
'use strict';
2+
13
require('should');
2-
var Promise = require('bluebird');
3-
var sinon = require('sinon');
4-
var Resource = require('../../../lib/resource');
5-
var HtmlHandler = require('../../../lib/resource-handler/html');
4+
const Promise = require('bluebird');
5+
const sinon = require('sinon');
6+
const Resource = require('../../../lib/resource');
7+
const HtmlHandler = require('../../../lib/resource-handler/html');
68

7-
var HtmlImgSrcsetTag = require('../../../lib/resource-handler/path-containers/html-img-srcset-tag');
8-
var HtmlCommonTag = require('../../../lib/resource-handler/path-containers/html-common-tag');
9-
var CssText = require('../../../lib/resource-handler/path-containers/css-text');
9+
const HtmlImgSrcsetTag = require('../../../lib/resource-handler/path-containers/html-img-srcset-tag');
10+
const HtmlCommonTag = require('../../../lib/resource-handler/path-containers/html-common-tag');
11+
const CssText = require('../../../lib/resource-handler/path-containers/css-text');
1012

11-
describe('ResourceHandler: Html', function () {
12-
var htmlHandler;
13+
describe('ResourceHandler: Html', () => {
14+
let htmlHandler;
1315

14-
beforeEach(function() {
16+
beforeEach(() => {
1517
htmlHandler = new HtmlHandler({ sources: [] }, sinon.stub().returns(Promise.resolve()));
1618
});
1719

18-
describe('<base> tag', function () {
19-
it('should remove base tag from text and update resource url for absolute href', function () {
20-
var html = `
20+
describe('<base> tag', () => {
21+
it('should remove base tag from text and update resource url for absolute href', () => {
22+
const html = `
2123
<html lang="en">
2224
<head>
2325
<base href="http://some-other-domain.com/src">
2426
</head>
2527
<body></body>
2628
</html>
2729
`;
28-
var resource = new Resource('http://example.com', 'index.html');
30+
const resource = new Resource('http://example.com', 'index.html');
2931
resource.setText(html);
3032

31-
return htmlHandler.handle(resource).then(function() {
33+
return htmlHandler.handle(resource).then(() =>{
3234
resource.getUrl().should.be.eql('http://some-other-domain.com/src');
3335
resource.getText().should.not.containEql('<base');
3436
});
3537
});
3638

37-
it('should remove base tag from text and update resource url for relative href', function () {
38-
var html = `
39+
it('should remove base tag from text and update resource url for relative href', () => {
40+
const html = `
3941
<html lang="en">
4042
<head>
4143
<base href="/src">
4244
</head>
4345
<body></body>
4446
</html>
4547
`;
46-
var resource = new Resource('http://example.com', 'index.html');
48+
const resource = new Resource('http://example.com', 'index.html');
4749
resource.setText(html);
4850

49-
return htmlHandler.handle(resource).then(function() {
51+
return htmlHandler.handle(resource).then(() => {
5052
resource.getUrl().should.be.eql('http://example.com/src');
5153
resource.getText().should.not.containEql('<base');
5254
});
5355
});
5456

55-
it('should not remove base tag if it doesn\'t have href attribute', function () {
56-
var html = `
57+
it('should not remove base tag if it doesn\'t have href attribute', () => {
58+
const html = `
5759
<html lang="en">
5860
<head>
5961
<base target="_blank">
6062
</head>
6163
<body></body>
6264
</html>
6365
`;
64-
var resource = new Resource('http://example.com', 'index.html');
66+
const resource = new Resource('http://example.com', 'index.html');
6567
resource.setText(html);
6668

67-
return htmlHandler.handle(resource).then(function() {
69+
return htmlHandler.handle(resource).then(() => {
6870
resource.getUrl().should.be.eql('http://example.com');
6971
resource.getText().should.containEql('<base target="_blank">');
7072
});
7173
});
7274
});
7375

74-
it('should not encode text to html entities', function () {
75-
var html = `
76+
it('should not encode text to html entities', () => {
77+
const html = `
7678
<html>
7779
<body>
7880
<p>Этот текст не должен быть преобразован в html entities</p>
7981
</body>
8082
</html>
8183
`;
8284

83-
var resource = new Resource('http://example.com', 'index.html');
85+
const resource = new Resource('http://example.com', 'index.html');
8486
resource.setText(html);
8587

86-
return htmlHandler.handle(resource).then(function () {
88+
return htmlHandler.handle(resource).then(() => {
8789
resource.getText().should.containEql('Этот текст не должен быть преобразован в html entities');
8890
});
8991
});
9092

91-
it('should call handleChildrenResources for each source', function () {
93+
it('should call handleChildrenResources for each source', () => {
9294
htmlHandler.options.sources.push({ selector: 'img', attr: 'src' });
9395

94-
var html = `
96+
const html = `
9597
<html lang="en">
9698
<head></head>
9799
<body>
@@ -102,38 +104,38 @@ describe('ResourceHandler: Html', function () {
102104
</html>
103105
`;
104106

105-
var resource = new Resource('http://example.com', 'index.html');
107+
const resource = new Resource('http://example.com', 'index.html');
106108
resource.setText(html);
107109

108-
return htmlHandler.handle(resource).then(function() {
110+
return htmlHandler.handle(resource).then(() =>{
109111
htmlHandler.handleChildrenPaths.calledThrice.should.be.eql(true);
110112
});
111113
});
112114

113-
it('should not call handleChildrenResources if source attr is empty', function () {
115+
it('should not call handleChildrenResources if source attr is empty', () =>{
114116
htmlHandler.options.sources.push({ selector: 'img', attr: 'src' });
115117

116-
var html = `
118+
const html = `
117119
<html lang="en">
118120
<head></head>
119121
<body><img src=""></body>
120122
</html>
121123
`;
122124

123-
var resource = new Resource('http://example.com', 'index.html');
125+
const resource = new Resource('http://example.com', 'index.html');
124126
resource.setText(html);
125127

126-
return htmlHandler.handle(resource).then(function() {
128+
return htmlHandler.handle(resource).then(() =>{
127129
htmlHandler.handleChildrenPaths.called.should.be.eql(false);
128130
});
129131
});
130132

131-
it('should use correct path containers based on tag', function() {
133+
it('should use correct path containers based on tag', () =>{
132134
htmlHandler.options.sources.push({ selector: 'img', attr: 'src' });
133135
htmlHandler.options.sources.push({ selector: 'img', attr: 'srcset' });
134136
htmlHandler.options.sources.push({ selector: '.styled', attr: 'style' });
135137

136-
var html = `
138+
const html = `
137139
<html lang="en">
138140
<head></head>
139141
<body>
@@ -144,14 +146,43 @@ describe('ResourceHandler: Html', function () {
144146
</html>
145147
`;
146148

147-
var resource = new Resource('http://example.com', 'index.html');
149+
const resource = new Resource('http://example.com', 'index.html');
148150
resource.setText(html);
149151

150-
return htmlHandler.handle(resource).then(function() {
152+
return htmlHandler.handle(resource).then(() =>{
151153
htmlHandler.handleChildrenPaths.calledThrice.should.be.eql(true);
152154
htmlHandler.handleChildrenPaths.args[0][0].should.be.instanceOf(HtmlCommonTag);
153155
htmlHandler.handleChildrenPaths.args[1][0].should.be.instanceOf(HtmlImgSrcsetTag);
154156
htmlHandler.handleChildrenPaths.args[2][0].should.be.instanceOf(CssText);
155157
});
156158
});
159+
160+
it('should remove SRI check for loaded resources', () => {
161+
htmlHandler.options.sources.push({ selector: 'script', attr: 'src' });
162+
163+
const html = `
164+
<html>
165+
<head>
166+
<link href="http://examlpe.com/style.css" integrity="sha256-gaWb8m2IHSkoZnT23u/necREOC//MiCFtQukVUYMyuU=" rel="stylesheet">
167+
</head>
168+
<body>
169+
<script integrity="sha256-X+Q/xqnlEgxCczSjjpp2AUGGgqM5gcBzhRQ0p+EAUEk=" src="http://example.com/script.js"></script>
170+
</body>
171+
</html>
172+
`;
173+
174+
const resource = new Resource('http://example.com', 'index.html');
175+
resource.setText(html);
176+
177+
// before handle should contain both integrity checks
178+
resource.getText().should.containEql('integrity="sha256-gaWb8m2IHSkoZnT23u/necREOC//MiCFtQukVUYMyuU="');
179+
resource.getText().should.containEql('integrity="sha256-X+Q/xqnlEgxCczSjjpp2AUGGgqM5gcBzhRQ0p+EAUEk="');
180+
181+
return htmlHandler.handle(resource).then(() => {
182+
// after handle should contain integrity check for styles
183+
// but not contain integrity check for script because it was loaded
184+
resource.getText().should.containEql('integrity="sha256-gaWb8m2IHSkoZnT23u/necREOC//MiCFtQukVUYMyuU="');
185+
resource.getText().should.not.containEql('integrity="sha256-X+Q/xqnlEgxCczSjjpp2AUGGgqM5gcBzhRQ0p+EAUEk="');
186+
});
187+
});
157188
});

0 commit comments

Comments
 (0)