Skip to content

Commit 0ad21d8

Browse files
authored
Inline scripts CSP for login (#1871)
* Protect the login page a little bit more Post #944 #1867 Auto-merge
1 parent 9413bed commit 0ad21d8

File tree

6 files changed

+27
-5
lines changed

6 files changed

+27
-5
lines changed

controllers/index.js

+22
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ var isDbg = require('../libs/debug').isDbg;
1111
var async = require('async');
1212
var _ = require('underscore');
1313
var url = require('url');
14+
var crypto = require('crypto');
1415

1516
//--- Model inclusions
1617
var Discussion = require('../models/discussion').Discussion;
@@ -261,6 +262,11 @@ exports.register = function (aReq, aRes) {
261262
//
262263

263264
Strategy.find({}, function (aErr, aAvailableStrategies) {
265+
var SECRET = process.env.HCAPTCHA_SECRET_KEY;
266+
var SITEKEY = process.env.HCAPTCHA_SITE_KEY;
267+
var defaultCSP = ' \'self\'';
268+
var captchaCSP = (SECRET ? ' hcaptcha.com *.hcaptcha.com' : '');
269+
264270
if (aErr || !aAvailableStrategies) {
265271
statusCodePage(aReq, aRes, aNext, {
266272
statusCode: 503,
@@ -277,6 +283,11 @@ exports.register = function (aReq, aRes) {
277283
});
278284
});
279285

286+
options.hasCaptcha = (SECRET ? true : false);
287+
288+
options.nonce = crypto.randomBytes(512).toString('hex');
289+
defaultCSP += ' \'nonce-' + options.nonce + '\'';
290+
280291
// Insert an empty default strategy at the beginning
281292
// NOTE: Safari always autoselects an option when disabled
282293
options.strategies.unshift({'strat': '', 'display': '(default preferred authentication)'});
@@ -286,10 +297,21 @@ exports.register = function (aReq, aRes) {
286297
return aStrategy.display;
287298
});
288299

300+
289301
aRes.header('Cache-Control', 'no-cache, no-store, must-revalidate');
290302
aRes.header('Pragma', 'no-cache');
291303
aRes.header('Expires', '0');
292304

305+
//
306+
aRes.header('Content-Security-Policy',
307+
'default-src' + defaultCSP +
308+
'; connect-src' + defaultCSP + captchaCSP +
309+
'; frame-src' + defaultCSP + captchaCSP +
310+
'; style-src' + defaultCSP + captchaCSP +
311+
'; script-src' + defaultCSP + captchaCSP +
312+
''
313+
);
314+
293315
aRes.render('pages/loginPage', options);
294316
}
295317
});

views/includes/scripts/formControlClear.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<script type="text/javascript">
1+
<script type="text/javascript"{{#nonce}} nonce="{{nonce}}"{{/nonce}}>
22
(function () {
33
'use strict';
44

views/includes/scripts/googleAnalytics.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<script type="text/javascript">
1+
<script type="text/javascript"{{#nonce}} nonce="{{nonce}}"{{/nonce}}>>
22
(function () {
33

44
if (!{{DNT}}) {

views/includes/scripts/hideReminders.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<script type="text/javascript">
1+
<script type="text/javascript"{{#nonce}} nonce="{{nonce}}"{{/nonce}}>>
22
(function () {
33

44
var events = 'focus resize scroll';

views/includes/scripts/loginEcho.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<script type="text/javascript">
1+
<script type="text/javascript"{{#nonce}} nonce="{{nonce}}"{{/nonce}}>
22
(function () {
33

44
// NOTE: Keep in sync with helper

views/pages/loginPage.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<title>{{title}}</title>
55
{{> includes/head.html }}
66
{{#hasCaptcha}}
7-
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>
7+
<script src="https://js.hcaptcha.com/1/api.js" async="async" defer="defer"></script>
88
{{/hasCaptcha}}
99
</head>
1010
<body>

0 commit comments

Comments
 (0)