From ff894f49fcfb42d6ca1c07e956ec9120f604d5db Mon Sep 17 00:00:00 2001 From: Alicia Sykes Date: Mon, 24 Jul 2023 21:00:40 +0100 Subject: [PATCH] Adds lambda function for fetching security.txt --- api/security-txt.js | 112 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 api/security-txt.js diff --git a/api/security-txt.js b/api/security-txt.js new file mode 100644 index 0000000..dd6e68b --- /dev/null +++ b/api/security-txt.js @@ -0,0 +1,112 @@ +const { https } = require('follow-redirects'); +const { URL } = require('url'); + +const SECURITY_TXT_PATHS = [ + '/security.txt', + '/.well-known/security.txt', +]; + +const parseResult = (result) => { + let output = {}; + let counts = {}; + const lines = result.split('\n'); + const regex = /^([^:]+):\s*(.+)$/; + + for (const line of lines) { + if (!line.startsWith("#") && !line.startsWith("-----") && line.trim() !== '') { + const match = line.match(regex); + if (match && match.length > 2) { + let key = match[1].trim(); + const value = match[2].trim(); + if (output.hasOwnProperty(key)) { + counts[key] = counts[key] ? counts[key] + 1 : 1; + key += counts[key]; + } + output[key] = value; + } + } + } + + return output; +}; + +const isPgpSigned = (result) => { + if (result.includes('-----BEGIN PGP SIGNED MESSAGE-----')) { + return true; + } + return false; +}; + +exports.handler = async (event, context) => { + const urlParam = event.queryStringParameters.url; + if (!urlParam) { + return { + statusCode: 400, + body: JSON.stringify({ error: 'Missing url parameter' }) + }; + } + + let url; + try { + url = new URL(urlParam.includes('://') ? urlParam : 'https://' + urlParam); + } catch (error) { + return { + statusCode: 500, + body: JSON.stringify({ error: 'Invalid URL format' }), + }; + } + url.pathname = ''; + + for (let path of SECURITY_TXT_PATHS) { + try { + const result = await fetchSecurityTxt(url, path); + if (result && result.includes(' { + const url = new URL(path, baseURL); + https.get(url.toString(), (res) => { + if (res.statusCode === 200) { + let data = ''; + res.on('data', (chunk) => { + data += chunk; + }); + res.on('end', () => { + resolve(data); + }); + } else { + resolve(null); + } + }).on('error', (err) => { + reject(err); + }); + }); +}