Adds API endpoint for checking HSTS headers

This commit is contained in:
Alicia Sykes 2023-07-16 23:42:22 +01:00
parent 77b8feb435
commit 7727106d46
2 changed files with 68 additions and 0 deletions

View File

@ -104,6 +104,11 @@
to = "/.netlify/functions/dns-sec"
status = 301
force = true
[[redirects]]
from = "/check-hsts"
to = "/.netlify/functions/check-hsts"
status = 301
force = true
# For router history mode, ensure pages land on index
[[redirects]]

View File

@ -0,0 +1,63 @@
const https = require('https');
exports.handler = async function(event, context) {
const siteURL = event.queryStringParameters.url;
const errorResponse = (message, statusCode = 500) => {
return {
statusCode: statusCode,
body: JSON.stringify({ error: message }),
};
};
const hstsIncompatible = (message, statusCode = 200) => {
return {
statusCode: statusCode,
body: JSON.stringify({ message, compatible: false }),
};
};
if (!siteURL) {
return {
statusCode: 400,
body: JSON.stringify({ error: 'URL parameter is missing!' }),
};
}
return new Promise((resolve, reject) => {
const req = https.request(siteURL, res => {
const headers = res.headers;
const hstsHeader = headers['strict-transport-security'];
if (!hstsHeader) {
resolve(hstsIncompatible(`Site does not serve any HSTS headers.`));
} else {
const maxAgeMatch = hstsHeader.match(/max-age=(\d+)/);
const includesSubDomains = hstsHeader.includes('includeSubDomains');
const preload = hstsHeader.includes('preload');
if (!maxAgeMatch || parseInt(maxAgeMatch[1]) < 10886400) {
resolve(hstsIncompatible(`HSTS max-age is less than 10886400.`));
} else if (!includesSubDomains) {
resolve(hstsIncompatible(`HSTS header does not include all subdomains.`));
} else if (!preload) {
resolve(hstsIncompatible(`HSTS header does not contain the preload directive.`));
} else {
resolve({
statusCode: 200,
body: JSON.stringify({
message: "Site is compatible with the HSTS preload list!",
compatible: true,
hstsHeader: hstsHeader,
}),
});
}
}
});
req.on('error', (error) => {
resolve(errorResponse(`Error making request: ${error.message}`));
});
req.end();
});
};