Fix blocked resources in library.htm, add new security headers

This commit is contained in:
David Evans 2021-12-09 23:03:46 +00:00
parent f0f34e0380
commit a84f2e01fc
12 changed files with 106 additions and 56 deletions

View File

@ -55,20 +55,41 @@ const PREVIEW_CACHE = {
}; };
const SKETCH_CSS_SHA = 'sha256-s7UPtBgvov5WNF9C1DlTZDpqwLgEmfiWha5a5p/Zn7E='; const SKETCH_CSS_SHA = 'sha256-s7UPtBgvov5WNF9C1DlTZDpqwLgEmfiWha5a5p/Zn7E=';
const PERMISSIONS_POLICY = [
'accelerometer=()',
'autoplay=()',
'camera=()',
'geolocation=()',
'gyroscope=()',
'interest-cohort=()',
'magnetometer=()',
'microphone=()',
'payment=()',
'sync-xhr=()',
'usb=()',
].join(', ');
const statics = new StaticRequestHandler('') const statics = new StaticRequestHandler('')
.setCache(DEV ? {} : STATIC_CACHE) .setCache(DEV ? {} : STATIC_CACHE)
.addHeader('Content-Security-Policy', [ .addHeader('Content-Security-Policy', [
'base-uri \'self\'', 'base-uri \'self\'',
'default-src \'none\'', 'default-src \'none\'',
'script-src \'self\' https://unpkg.com', 'script-src \'self\' https://unpkg.com',
`style-src 'self' '${SKETCH_CSS_SHA}'`, // Using fonts.googleapis.com for library.htm only
`style-src 'self' https://fonts.googleapis.com '${SKETCH_CSS_SHA}'`,
'connect-src \'self\'', 'connect-src \'self\'',
'font-src \'self\' data:', // Using fonts.gstatic.com for library.htm only
'font-src \'self\' data: https://fonts.gstatic.com',
'img-src \'self\' blob:', 'img-src \'self\' blob:',
'form-action \'self\'', 'form-action \'self\'',
'frame-ancestors \'self\'', 'frame-ancestors \'self\'',
'frame-src \'self\'', 'frame-src \'self\'',
].join('; ')) ].join('; '))
.addHeader('Cross-Origin-Embedder-Policy', 'require-corp')
.addHeader('Cross-Origin-Opener-Policy', 'same-origin')
.addHeader('Cross-Origin-Resource-Policy', 'same-origin')
.addHeader('Permissions-Policy', PERMISSIONS_POLICY)
.addHeader('Referrer-Policy', 'no-referrer')
.addHeader('X-Content-Type-Options', 'nosniff') .addHeader('X-Content-Type-Options', 'nosniff')
.addHeader('X-Frame-Options', 'DENY') .addHeader('X-Frame-Options', 'DENY')
.addHeader('X-XSS-Protection', '1; mode=block') .addHeader('X-XSS-Protection', '1; mode=block')
@ -83,6 +104,15 @@ const statics = new StaticRequestHandler('')
statics statics
.add('/robots.txt', '') .add('/robots.txt', '')
.add('/ads.txt', [
'# Deny inclusion in any advertising system\n',
'placeholder.example.com, placeholder, DIRECT, placeholder\n',
].join(''))
.add('/.well-known/security.txt', [
'Contact: https://github.com/davidje13/SequenceDiagram/issues\n',
'Preferred-Languages: en\n',
'Expires: 3000-01-01T00:00:00Z\n',
].join(''))
.addResources('/', BASEDIR, [ .addResources('/', BASEDIR, [
'index.html', 'index.html',
'library.htm', 'library.htm',
@ -115,6 +145,11 @@ const render = new RenderRequestHandler('/render')
'font-src data:', 'font-src data:',
'form-action \'none\'', 'form-action \'none\'',
].join('; ')) ].join('; '))
.addHeader('Cross-Origin-Embedder-Policy', 'require-corp')
.addHeader('Cross-Origin-Opener-Policy', 'unsafe-none')
.addHeader('Cross-Origin-Resource-Policy', 'cross-origin')
.addHeader('Permissions-Policy', PERMISSIONS_POLICY)
.addHeader('Referrer-Policy', 'no-referrer')
.addHeader('X-Content-Type-Options', 'nosniff'); .addHeader('X-Content-Type-Options', 'nosniff');
const preview = new PreviewRequestHandler('/preview') const preview = new PreviewRequestHandler('/preview')
@ -129,6 +164,11 @@ const preview = new PreviewRequestHandler('/preview')
'frame-ancestors \'self\'', 'frame-ancestors \'self\'',
'frame-src \'self\'', 'frame-src \'self\'',
].join('; ')) ].join('; '))
.addHeader('Cross-Origin-Embedder-Policy', 'require-corp')
.addHeader('Cross-Origin-Opener-Policy', 'same-origin')
.addHeader('Cross-Origin-Resource-Policy', 'same-origin')
.addHeader('Permissions-Policy', PERMISSIONS_POLICY)
.addHeader('Referrer-Policy', 'no-referrer')
.addHeader('X-Content-Type-Options', 'nosniff'); .addHeader('X-Content-Type-Options', 'nosniff');
new Server() new Server()

View File

@ -82,8 +82,8 @@
<p class="loadmsg">Loading&hellip;</p> <p class="loadmsg">Loading&hellip;</p>
<nav> <nav>
<a href="#" data-touch="Files">My Diagrams</a> <a href="#" data-touch="Files">My Diagrams</a>
<a href="library.htm" target="_blank" data-touch="API">Library</a> <a href="library.htm" target="_blank" rel="noopener" data-touch="API">Library</a>
<a href="https://github.com/davidje13/SequenceDiagram" target="_blank" data-touch="">GitHub</a> <a href="https://github.com/davidje13/SequenceDiagram" target="_blank" rel="noopener" data-touch="">GitHub</a>
</nav> </nav>
</div> </div>
@ -92,7 +92,7 @@
<main> <main>
<section class="banner"> <section class="banner">
Enable JavaScript for live rendering, templates, PNG export, and local file saving. Enable JavaScript for live rendering, templates, PNG export, and local file saving.
<nav><a href="library.htm" target="_blank">Library</a><a href="https://github.com/davidje13/SequenceDiagram" target="_blank">GitHub</a></nav> <nav><a href="library.htm" target="_blank" rel="noopener">Library</a><a href="https://github.com/davidje13/SequenceDiagram" target="_blank" rel="noopener">GitHub</a></nav>
</section> </section>
<form target="preview" action="preview" method="GET"> <form target="preview" action="preview" method="GET">
<textarea name="c"> <textarea name="c">

View File

@ -7274,7 +7274,7 @@
if(attrs.href) { if(attrs.href) {
element = svg.el('a').attrs({ element = svg.el('a').attrs({
'cursor': 'pointer', 'cursor': 'pointer',
'rel': 'nofollow', 'rel': 'nofollow noopener',
'target': '_blank', 'target': '_blank',
}); });
} else { } else {

File diff suppressed because one or more lines are too long

View File

@ -7274,7 +7274,7 @@
if(attrs.href) { if(attrs.href) {
element = svg.el('a').attrs({ element = svg.el('a').attrs({
'cursor': 'pointer', 'cursor': 'pointer',
'rel': 'nofollow', 'rel': 'nofollow noopener',
'target': '_blank', 'target': '_blank',
}); });
} else { } else {

View File

@ -42,37 +42,7 @@
<script src="lib/sequence-diagram-web.min.js"></script> <script src="lib/sequence-diagram-web.min.js"></script>
<!-- /LIVE --> <!-- /LIVE -->
<script>document.addEventListener('DOMContentLoaded', () => { <script src="web/resources/library.js"></script>
const diagrams = [];
// Example 1:
(() => {
const diagram = new SequenceDiagram();
diagram.set('A -> B\nB -> A', {render: false});
diagram.dom().setAttribute('class', 'sequence-diagram');
document.getElementById('hold1').appendChild(diagram.dom());
diagram.setHighlight(1);
diagrams.push(diagram);
})();
// Snippets:
const elements = document.getElementsByClassName('example');
for(let i = 0; i < elements.length; ++ i) {
const el = elements[i];
const diagram = new SequenceDiagram(el.textContent, {render: false});
diagram.dom().setAttribute('class', 'example-diagram');
el.parentNode.insertBefore(diagram.dom(), el);
diagrams.push(diagram);
}
SequenceDiagram.renderAll(diagrams);
if (CodeMirror && CodeMirror.colorize) {
CodeMirror.colorize();
}
}, {once: true});</script>
</head> </head>
<body> <body>
@ -102,11 +72,11 @@ if (CodeMirror && CodeMirror.colorize) {
<p> <p>
Want to draw a Sequence Diagram? Want to draw a Sequence Diagram?
<a href="." target="_blank">Go to the online editor</a>. <a href="." target="_blank" rel="noopener">Go to the online editor</a>.
</p> </p>
<p> <p>
This library renders sequence diagrams from code. It is This library renders sequence diagrams from code. It is
<a href="https://github.com/davidje13/SequenceDiagram" target="_blank">open-source</a> <a href="https://github.com/davidje13/SequenceDiagram" target="_blank" rel="noopener">open-source</a>
(LGPL-3.0), and including it in a website is as simple as adding the script:</p> (LGPL-3.0), and including it in a website is as simple as adding the script:</p>
<pre data-lang="text/html"> <pre data-lang="text/html">
@ -406,7 +376,7 @@ R -> ...fin2
<p> <p>
More features are supported. See the More features are supported. See the
<a href="." target="_blank">online editor</a>&rsquo;s library and autocomplete <a href="." target="_blank" rel="noopener">online editor</a>&rsquo;s library and autocomplete
features to discover them. features to discover them.
</p> </p>
</section> </section>
@ -418,7 +388,7 @@ This has been tested in the latest versions of Google Chrome, Mozilla Firefox,
and Apple Safari. Versions of Microsoft Internet Explorer / Edge have not been and Apple Safari. Versions of Microsoft Internet Explorer / Edge have not been
tested and probably won&rsquo;t work. Any bugs found in a supported browser tested and probably won&rsquo;t work. Any bugs found in a supported browser
should be reported in the should be reported in the
<a href="https://github.com/davidje13/SequenceDiagram/issues" target="_blank">Issue Tracker</a>. <a href="https://github.com/davidje13/SequenceDiagram/issues" target="_blank" rel="noopener">Issue Tracker</a>.
</p> </p>
<h2 id="API">API</h2> <h2 id="API">API</h2>
@ -877,29 +847,29 @@ for all types.
There are quite a lot of sequence diagram drawing tools available. If this one There are quite a lot of sequence diagram drawing tools available. If this one
doesn&rsquo;t fit your needs for whatever reason, you might want to take a look doesn&rsquo;t fit your needs for whatever reason, you might want to take a look
at the alternatives: (but also feel free to raise feature requests in the at the alternatives: (but also feel free to raise feature requests in the
<a href="https://github.com/davidje13/SequenceDiagram/issues" target="_blank">issue tracker</a>!) <a href="https://github.com/davidje13/SequenceDiagram/issues" target="_blank" rel="noopener">issue tracker</a>!)
</p> </p>
<ul> <ul>
<li><a href="https://www.websequencediagrams.com/" target="_blank">websequencediagrams.com</a> <li><a href="https://www.websequencediagrams.com/" target="_blank" rel="noopener">websequencediagrams.com</a>
is a commercial offering which inspired the syntax of this project and many is a commercial offering which inspired the syntax of this project and many
others. It has a wide range of themes but limited functionality. Also offers a others. It has a wide range of themes but limited functionality. Also offers a
hosted image generation service.</li> hosted image generation service.</li>
<li><a href="https://github.com/bramp/js-sequence-diagrams" target="_blank">js-sequence-diagrams</a> <li><a href="https://github.com/bramp/js-sequence-diagrams" target="_blank" rel="noopener">js-sequence-diagrams</a>
is a Javascript library which has wider browser support via snap.svg but very is a Javascript library which has wider browser support via snap.svg but very
limited functionality.</li> limited functionality.</li>
<li><a href="https://github.com/knsv/mermaid" target="_blank">mermaid</a> <li><a href="https://github.com/knsv/mermaid" target="_blank" rel="noopener">mermaid</a>
is a Javascript library and online editor which can render multiple types of UML is a Javascript library and online editor which can render multiple types of UML
diagram, including simple sequence diagrams.</li> diagram, including simple sequence diagrams.</li>
<li><a href="https://github.com/aivarsk/scruffy" target="_blank">Scruffy UML</a> <li><a href="https://github.com/aivarsk/scruffy" target="_blank" rel="noopener">Scruffy UML</a>
is a Python library which can render multiple types of UML diagram, including is a Python library which can render multiple types of UML diagram, including
simple sequence diagrams, from the commandline. Uses yUML syntax rather than the simple sequence diagrams, from the commandline. Uses yUML syntax rather than the
human friendly syntax used by most other projects.</li> human friendly syntax used by most other projects.</li>
<li><a href="https://github.com/plantuml/plantuml" target="_blank">PlantUML</a> <li><a href="https://github.com/plantuml/plantuml" target="_blank" rel="noopener">PlantUML</a>
is a Java project and online editor which can render multiple types of UML is a Java project and online editor which can render multiple types of UML
diagram, including sequence diagrams. Has a good range of features and allows a diagram, including sequence diagrams. Has a good range of features and allows a
high degree of customisation (e.g. diagram colours).</li> high degree of customisation (e.g. diagram colours).</li>
@ -911,7 +881,7 @@ high degree of customisation (e.g. diagram colours).</li>
<p> <p>
Thanks to the other tools mentioned above for inspiring parts of the syntax of Thanks to the other tools mentioned above for inspiring parts of the syntax of
this project, and to this project, and to
<a href="https://fonts.google.com/specimen/Handlee" target="_blank">the Handlee font</a> <a href="https://fonts.google.com/specimen/Handlee" target="_blank" rel="noopener">the Handlee font</a>
which is used in the sketch theme. which is used in the sketch theme.
</p> </p>
@ -935,7 +905,7 @@ which is used in the sketch theme.
</pre> </pre>
<nav> <nav>
<a href="." target="_blank">Online Editor</a><a href="https://github.com/davidje13/SequenceDiagram" target="_blank">GitHub</a> <a href="." target="_blank" rel="noopener">Online Editor</a><a href="https://github.com/davidje13/SequenceDiagram" target="_blank" rel="noopener">GitHub</a>
</nav> </nav>
</article> </article>

View File

@ -20,7 +20,7 @@ function populateSvgTextLine(svg, node, formattedLine) {
if(attrs.href) { if(attrs.href) {
element = svg.el('a').attrs({ element = svg.el('a').attrs({
'cursor': 'pointer', 'cursor': 'pointer',
'rel': 'nofollow', 'rel': 'nofollow noopener',
'target': '_blank', 'target': '_blank',
}); });
} else { } else {

View File

@ -105,7 +105,8 @@ describe('SVGTextBlock', () => {
expect(hold.childNodes[0].innerHTML).toContain(' cursor="pointer"'); expect(hold.childNodes[0].innerHTML).toContain(' cursor="pointer"');
expect(hold.childNodes[0].innerHTML).toContain(' target="_blank"'); expect(hold.childNodes[0].innerHTML).toContain(' target="_blank"');
expect(hold.childNodes[0].innerHTML).toContain(' rel="nofollow"'); expect(hold.childNodes[0].innerHTML)
.toContain(' rel="nofollow noopener"');
}); });
it('re-uses text nodes when possible, adding more if needed', () => { it('re-uses text nodes when possible, adding more if needed', () => {

View File

@ -1819,7 +1819,11 @@
const links = this.links.map((link) => { const links = this.links.map((link) => {
const label = this.touchUI ? link.touchLabel : link.label; const label = this.touchUI ? link.touchLabel : link.label;
return label && this.dom.el('a') return label && this.dom.el('a')
.attrs({'href': link.href, 'target': link.target || ''}) .attrs({
'href': link.href,
'rel': 'noopener',
'target': link.target || '',
})
.text(label); .text(label);
}).filter((x) => x); }).filter((x) => x);

File diff suppressed because one or more lines are too long

31
web/resources/library.js Normal file
View File

@ -0,0 +1,31 @@
/* globals SequenceDiagram CodeMirror */
document.addEventListener('DOMContentLoaded', () => {
const diagrams = [];
// Example 1:
(() => {
const diagram = new SequenceDiagram();
diagram.set('A -> B\nB -> A', {render: false});
diagram.dom().setAttribute('class', 'sequence-diagram');
document.getElementById('hold1').appendChild(diagram.dom());
diagram.setHighlight(1);
diagrams.push(diagram);
})();
// Snippets:
const elements = document.getElementsByClassName('example');
for(let i = 0; i < elements.length; ++ i) {
const el = elements[i];
const diagram = new SequenceDiagram(el.textContent, {render: false});
diagram.dom().setAttribute('class', 'example-diagram');
el.parentNode.insertBefore(diagram.dom(), el);
diagrams.push(diagram);
}
SequenceDiagram.renderAll(diagrams);
if(CodeMirror && CodeMirror.colorize) {
CodeMirror.colorize();
}
}, {once: true});

View File

@ -491,7 +491,11 @@ export default class Interface {
const links = this.links.map((link) => { const links = this.links.map((link) => {
const label = this.touchUI ? link.touchLabel : link.label; const label = this.touchUI ? link.touchLabel : link.label;
return label && this.dom.el('a') return label && this.dom.el('a')
.attrs({'href': link.href, 'target': link.target || ''}) .attrs({
'href': link.href,
'rel': 'noopener',
'target': link.target || '',
})
.text(label); .text(label);
}).filter((x) => x); }).filter((x) => x);