From c6f87cf98326ddc8699e5bc5d80c6ca7ea25441b Mon Sep 17 00:00:00 2001 From: Bob Qiu Date: Thu, 8 Oct 2026 14:07:51 +0800 Subject: [PATCH] Refactor TLS/mTLS certificate handling in echo, event-stream, gRPC, and other servers - Introduced a `certPath` utility to streamline certificate file path resolution. - Updated all server files to use the new `certPath` function for loading TLS/mTLS certificates. - Removed hardcoded certificate files from the repository to enhance security. - Added `node-forge` as a dependency for certificate generation. - Ensured that the Playwright configuration initializes certificates before server startup. - Updated tests to reference the new certificate paths, ensuring compatibility with the refactored structure. --- .gitignore | 3 + package-lock.json | 1 + packages/insomnia-test/misc/certs.js | 145 ++++++++++++++++++ packages/insomnia-test/misc/echo-server.js | 11 +- .../insomnia-test/misc/event-stream-server.js | 6 +- .../misc/fixtures/localhost-cert.pem | 17 -- .../misc/fixtures/localhost-key.pem | 28 ---- .../misc/fixtures/mtls-ca-key.pem | 27 ---- .../insomnia-test/misc/fixtures/mtls-ca.pem | 17 -- .../misc/fixtures/mtls-client-cert.pem | 17 -- .../misc/fixtures/mtls-client-key.pem | 27 ---- .../misc/fixtures/mtls-server-cert.pem | 18 --- .../misc/fixtures/mtls-server-key.pem | 27 ---- packages/insomnia-test/misc/grpc-server.js | 11 +- packages/insomnia-test/misc/mcp-server.js | 9 +- packages/insomnia-test/misc/oauth2-server.js | 3 + packages/insomnia-test/misc/socket-server.js | 6 +- packages/insomnia-test/misc/ws-echo-server.js | 6 +- packages/insomnia-test/package.json | 1 + packages/insomnia-test/playwright.config.ts | 6 + .../mtls-client-certificate.spec.ts | 5 +- .../custom-ca-root-certificate.spec.ts | 4 +- .../mtls-client-certificate.spec.ts | 5 +- 23 files changed, 194 insertions(+), 206 deletions(-) create mode 100644 packages/insomnia-test/misc/certs.js delete mode 100644 packages/insomnia-test/misc/fixtures/localhost-cert.pem delete mode 100644 packages/insomnia-test/misc/fixtures/localhost-key.pem delete mode 100644 packages/insomnia-test/misc/fixtures/mtls-ca-key.pem delete mode 100644 packages/insomnia-test/misc/fixtures/mtls-ca.pem delete mode 100644 packages/insomnia-test/misc/fixtures/mtls-client-cert.pem delete mode 100644 packages/insomnia-test/misc/fixtures/mtls-client-key.pem delete mode 100644 packages/insomnia-test/misc/fixtures/mtls-server-cert.pem delete mode 100644 packages/insomnia-test/misc/fixtures/mtls-server-key.pem diff --git a/.gitignore b/.gitignore index a1822bacaa..a2182f7f10 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,6 @@ final.rc test-results/ playwright-report/ blob-report/ + +# TLS/mTLS key pairs generated by misc/certs.js +packages/insomnia-test/misc/fixtures/generated/ diff --git a/package-lock.json b/package-lock.json index 3e7ece80b2..ebd3eeb3f1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27616,6 +27616,7 @@ "git-http-backend": "^1.1.2", "graphql": "^17.0.2", "monocart-coverage-reports": "^2.13.0", + "node-forge": "^1.4.0", "socket.io": "^4.8.3", "ws": "^8.21.1", "zod": "^4.4.3" diff --git a/packages/insomnia-test/misc/certs.js b/packages/insomnia-test/misc/certs.js new file mode 100644 index 0000000000..8f623ef803 --- /dev/null +++ b/packages/insomnia-test/misc/certs.js @@ -0,0 +1,145 @@ +// Generates the TLS/mTLS fixtures the mock servers and specs use, so no +// private key has to be committed. Output goes to misc/fixtures/generated/ +// (git-ignored). Idempotent: does nothing when every file already exists, so +// playwright.config.ts can call it once before the webServers start and each +// server can call it again as a no-op (or to run standalone). +const crypto = require("node:crypto"); +const fs = require("node:fs"); +const path = require("node:path"); + +const forge = require("node-forge"); + +const CERT_DIR = path.join(__dirname, "fixtures", "generated"); + +const FILES = [ + "localhost-key.pem", + "localhost-cert.pem", + "mtls-ca.pem", + "mtls-server-key.pem", + "mtls-server-cert.pem", + "mtls-client-key.pem", + "mtls-client-cert.pem", +]; + +const TEN_YEARS_MS = 10 * 365 * 24 * 60 * 60 * 1000; + +function generateKeyPair() { + const { privateKey } = crypto.generateKeyPairSync("rsa", { + modulusLength: 2048, + }); + const privatePem = privateKey.export({ type: "pkcs8", format: "pem" }); + const forgePrivate = forge.pki.privateKeyFromPem(privatePem); + const forgePublic = forge.pki.setRsaPublicKey(forgePrivate.n, forgePrivate.e); + return { privatePem, forgePrivate, forgePublic }; +} + +function createCert({ commonName, issuer, issuerKey, key, extensions }) { + const cert = forge.pki.createCertificate(); + cert.publicKey = key.forgePublic; + cert.serialNumber = crypto.randomBytes(8).toString("hex"); + // Back-date the start so a clock a little behind this machine's still accepts it. + cert.validity.notBefore = new Date(Date.now() - 24 * 60 * 60 * 1000); + cert.validity.notAfter = new Date(Date.now() + TEN_YEARS_MS); + const subject = [{ name: "commonName", value: commonName }]; + cert.setSubject(subject); + cert.setIssuer(issuer ?? subject); + cert.setExtensions(extensions); + cert.sign(issuerKey ?? key.forgePrivate, forge.md.sha256.create()); + return forge.pki.certificateToPem(cert); +} + +const LOCALHOST_SAN = { + name: "subjectAltName", + altNames: [ + { type: 2, value: "localhost" }, + { type: 7, ip: "127.0.0.1" }, + ], +}; + +function generate() { + fs.mkdirSync(CERT_DIR, { recursive: true }); + const write = (name, contents) => + fs.writeFileSync(path.join(CERT_DIR, name), contents); + + // Self-signed localhost cert, used by every plain HTTPS/WSS/gRPC-TLS server. + const localhostKey = generateKeyPair(); + write("localhost-key.pem", localhostKey.privatePem); + write( + "localhost-cert.pem", + createCert({ + commonName: "localhost", + key: localhostKey, + extensions: [LOCALHOST_SAN], + }), + ); + + // CA that signs the mTLS server and client certs. Its private key is only + // needed to sign them, so it's never written to disk. + const caKey = generateKeyPair(); + const caName = [{ name: "commonName", value: "Insomnia Test mTLS CA" }]; + const caPem = createCert({ + commonName: "Insomnia Test mTLS CA", + key: caKey, + extensions: [ + { name: "basicConstraints", cA: true }, + { name: "keyUsage", keyCertSign: true, cRLSign: true }, + ], + }); + write("mtls-ca.pem", caPem); + + const serverKey = generateKeyPair(); + write("mtls-server-key.pem", serverKey.privatePem); + write( + "mtls-server-cert.pem", + createCert({ + commonName: "localhost", + issuer: caName, + issuerKey: caKey.forgePrivate, + key: serverKey, + extensions: [ + { name: "basicConstraints", cA: false }, + { name: "extKeyUsage", serverAuth: true }, + LOCALHOST_SAN, + ], + }), + ); + + const clientKey = generateKeyPair(); + write("mtls-client-key.pem", clientKey.privatePem); + write( + "mtls-client-cert.pem", + createCert({ + commonName: "insomnia-test-client", + issuer: caName, + issuerKey: caKey.forgePrivate, + key: clientKey, + extensions: [ + { name: "basicConstraints", cA: false }, + { name: "extKeyUsage", clientAuth: true }, + ], + }), + ); +} + +/** + * Generates the fixtures when any is missing. + * @returns The directory the PEM files live in + */ +function ensureCerts() { + const complete = FILES.every((name) => + fs.existsSync(path.join(CERT_DIR, name)), + ); + if (!complete) generate(); + return CERT_DIR; +} + +/** + * @param name - A fixture file name, e.g. `"localhost-key.pem"` + * @returns The absolute path to that generated file, creating it first if needed + */ +function certPath(name) { + ensureCerts(); + return path.join(CERT_DIR, name); +} + +module.exports = { CERT_DIR, ensureCerts, certPath }; diff --git a/packages/insomnia-test/misc/echo-server.js b/packages/insomnia-test/misc/echo-server.js index 61570e0cf8..55f323a6ae 100644 --- a/packages/insomnia-test/misc/echo-server.js +++ b/packages/insomnia-test/misc/echo-server.js @@ -6,6 +6,7 @@ const https = require("node:https"); const fs = require("node:fs"); const path = require("node:path"); const { graphql, buildSchema } = require("graphql"); +const { certPath } = require("./certs"); const PETSTORE_SWAGGER = fs.readFileSync( path.join(__dirname, "fixtures", "petstore-swagger.json"), @@ -66,14 +67,14 @@ const GRAPHQL_ROOT = { }; const HTTPS_OPTIONS = { - key: fs.readFileSync(path.join(__dirname, "fixtures", "localhost-key.pem")), - cert: fs.readFileSync(path.join(__dirname, "fixtures", "localhost-cert.pem")), + key: fs.readFileSync(certPath("localhost-key.pem")), + cert: fs.readFileSync(certPath("localhost-cert.pem")), }; -const MTLS_CA = fs.readFileSync(path.join(__dirname, "fixtures", "mtls-ca.pem")); +const MTLS_CA = fs.readFileSync(certPath("mtls-ca.pem")); const MTLS_SERVER_OPTIONS = { - key: fs.readFileSync(path.join(__dirname, "fixtures", "mtls-server-key.pem")), - cert: fs.readFileSync(path.join(__dirname, "fixtures", "mtls-server-cert.pem")), + key: fs.readFileSync(certPath("mtls-server-key.pem")), + cert: fs.readFileSync(certPath("mtls-server-cert.pem")), }; const CUSTOM_CA_HTTPS_OPTIONS = { ...MTLS_SERVER_OPTIONS }; diff --git a/packages/insomnia-test/misc/event-stream-server.js b/packages/insomnia-test/misc/event-stream-server.js index abebef100b..899aebe06e 100644 --- a/packages/insomnia-test/misc/event-stream-server.js +++ b/packages/insomnia-test/misc/event-stream-server.js @@ -4,11 +4,11 @@ const http = require("node:http"); const https = require("node:https"); const fs = require("node:fs"); -const path = require("node:path"); +const { certPath } = require("./certs"); const HTTPS_OPTIONS = { - key: fs.readFileSync(path.join(__dirname, "fixtures", "localhost-key.pem")), - cert: fs.readFileSync(path.join(__dirname, "fixtures", "localhost-cert.pem")), + key: fs.readFileSync(certPath("localhost-key.pem")), + cert: fs.readFileSync(certPath("localhost-cert.pem")), }; const MAX_REPLY_DELAY_MS = 60_000; diff --git a/packages/insomnia-test/misc/fixtures/localhost-cert.pem b/packages/insomnia-test/misc/fixtures/localhost-cert.pem deleted file mode 100644 index e1572d622d..0000000000 --- a/packages/insomnia-test/misc/fixtures/localhost-cert.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICyTCCAbGgAwIBAgIJAKxqgBxIan+zMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV -BAMMCWxvY2FsaG9zdDAeFw0yNjA3MjgwODM4NTNaFw0zNjA3MjUwODM4NTNaMBQx -EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAL3lolmhRAGFlchkIXWmriWhopx7mC8xCNmNOAvyavdAc9C5XvTiPUocfhwZ -sRdYUpnfaG0xRYzZut9bBex27QyE2Im8l4A0K0lLCZIjbEGvbZBk0f/cjR89+8T6 -ckA1gsOfvVlIFqqnv5FnQ4e+pihwRZItKnQI93KCl0sbWLYmt/IQhiXQVotzKBua -AHgmOp7seS6LvD3Y3ebEAJFEmPE85tD04nvUW3GpLmrKmRhd6Zsh+vjjjv+RqHFF -UKKXir0Isv28XkV32G4GT8iqXDR+Y6Oiz82/u5wol9QNiHfVH93hxDWTozk4S+Sv -gYbmBwltS3+Wtv+MMcn7wfVniuECAwEAAaMeMBwwGgYDVR0RBBMwEYIJbG9jYWxo -b3N0hwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBAQBOM4YV/SZSnCD21e2B5/7LxTKr -MPyTk3trugMSnOYeWamakhriDQs8cB3K2eEGFEbDAF0XQZ/Dpz+UGhqnMz+WcRTi -G7G4gapQLhOZTzH8nU+yu2SDzYOA6EVYQJBtrHIZhpZuQ4WFEosr3KckRfTMeLB3 -snb5NFgQEy84DKuwG8fAhI18YcpEitw84bD6fTdRCHCHYkEM6Y2+seD8hsfznX/m -rKcj90xqEJuEmbAEDI7x18RIheGmdnx84AIf0E9JkxXgKdmPeFnqEN5Kduzrfc14 -L/NYei534YG+7pyk6LMuSiNAy2HqZ3EeCE/Ft0WXolUo2MXCmSfYeUjAboCm ------END CERTIFICATE----- diff --git a/packages/insomnia-test/misc/fixtures/localhost-key.pem b/packages/insomnia-test/misc/fixtures/localhost-key.pem deleted file mode 100644 index 511dfb4004..0000000000 --- a/packages/insomnia-test/misc/fixtures/localhost-key.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC95aJZoUQBhZXI -ZCF1pq4loaKce5gvMQjZjTgL8mr3QHPQuV704j1KHH4cGbEXWFKZ32htMUWM2brf -WwXsdu0MhNiJvJeANCtJSwmSI2xBr22QZNH/3I0fPfvE+nJANYLDn71ZSBaqp7+R -Z0OHvqYocEWSLSp0CPdygpdLG1i2JrfyEIYl0FaLcygbmgB4Jjqe7Hkui7w92N3m -xACRRJjxPObQ9OJ71FtxqS5qypkYXembIfr4447/kahxRVCil4q9CLL9vF5Fd9hu -Bk/Iqlw0fmOjos/Nv7ucKJfUDYh31R/d4cQ1k6M5OEvkr4GG5gcJbUt/lrb/jDHJ -+8H1Z4rhAgMBAAECggEACnUP2LG5xf+uPOfOs+Tm6Cmbg9SGj+q6Wwic0oOaAl2p -QxBCO2gOCfvBshh0GR4DBng4DvNMqjH/SXeAvwHZkfvq1MLu8N9uls2sDEEpIADi -HrZ+ngFuQA8wwysriX+o4M72JWmD3gf407AFFv+XtNhh7GfSU6t+vO6WGEu8OeOV -feuYBfyJPFShIKnAtBj8s7ya/nqfLRtvwWEMEhv3F8Xe/O+qyPBY8kuoD69GqBP+ -m4RV3yEM3VAcBHZFAc6goIDvqSC6TLOdtVlwMMTQkkPw//q2MyMut3U7y8qbUJgx -3LOyXtkEBzJmg+QM5b3ksOt8voKwWyvLba/eA6moJQKBgQD4rQXsB6UHrb4V42yB -aB+XUYjLsNX8ETfnrAT8DHbv7KuusmvmfSixsEM/LTDpy8HILeHWsj3gBWJtvkXY -/eZoEE/kHV1alfNsGX2fqbkI/XjGa9QDDTxwTfuTCu8P82SttmE3tjt3yqsByD/R -wtNdnaxHaWcrfhtbacJhsqCrfwKBgQDDfW182hqfdM5KhSY8LsMfhuUUexzXh+CH -Oy+OwfIbGRHWz9K0Twd1pPtd34SqBmkCdp4sHd2mlNJsqr/Odfj15/uLjkXxx6QH -0crm3feLCLyava4oVpTlZieuPqCymQt5iesoOrlblK8TC7oKSsp9z1UUHiunLgMP -cYLQTHJ5nwKBgQC2k6pWaiJzac+3GFvRAxa2ralHC9WAFVA7ayPZvnkQnG5MfDkW -Z+wZ0bT9zHsuHGhxRaabUBB3ytxCgMGdmISzAM73R8wDtzaatnhyYlU1UYx7+i0V -9IDcX5UGl69/wY64r7/e/I/a2tUFIPYiVu2CvUIAyFV0LEl/qz2JJ3IplwKBgEPQ -7D2Gr/unGrVRUX1JP5ldQ3UCbHP8iBCBoLLmZyWtYbniaJbyX4UZUbY0ByKwjJc1 -LRPi3HSgZgsahOWLmW09J8828N66QhYQWlISqIBL7JnFuXf26TpXYOaahUbPvuJP -zQssrAawIrf5tnVBktNoLHyJJt2dIaSm3RmDm6bDAoGAbLPB8enxDggrBJldcNh/ -NgTaitfEtP2AdHlJcVJ2ROxOY7B4nJTxdQS+rlUHUIvILG/rn+s5iELYv96ZSpG9 -wcfDLzRtf82hDuk78usNUSeecsUp7jDTB5NW+yqvupda3SmcAg+dtzvQL8hnLFpw -2oDkGN8z9PagokFIreRXrVE= ------END PRIVATE KEY----- diff --git a/packages/insomnia-test/misc/fixtures/mtls-ca-key.pem b/packages/insomnia-test/misc/fixtures/mtls-ca-key.pem deleted file mode 100644 index ed2e08704d..0000000000 --- a/packages/insomnia-test/misc/fixtures/mtls-ca-key.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEAt0but6x1QUc9UT/9pTpBdISfEUNBJRq6rfEVbKQba+2n/OOp -OFFKMURkvaumhgBjbjSGOAp96ROw57cTJjDtL412dbnbR1UpCm2pIfeg1dpzsVcG -MV8GVG87R/DrwFjl2gBv5V7GGE5G+0e49OC3ObynelShIZaLBV/n3J0jSRAkvt6k -hbdXcW6EXvyMo5LgyVpfMk9JPC46SBU91CdAEYdbV9t6dNzAe+iHuBuAtZNadlTv -l5mv6PdX9ZsqFZUsF9o7ILUfcl9/9qw1jKMNjb5BiLT0hrQXtGGLmn11xVy9gUgq -kl6DTZ10LAAkZ+M4to1xSHExGuKtWhW3Ir4FXQIDAQABAoIBAQC3C4LzsqxRDANz -mIONd8dTxfjQVulDU5TKkJOjM6uneW5jpkSl2JpO5k3vGPZxswWbVZ4PbnseQ+pV -IoVfiVH6QkDjh0I31hftMGTRZe4eZ9VQcufee1dpEMaWLUpniuHVfsZCwQr7z4IZ -CSLyf1S/t2lVRhy/3Qjvzz9VGSPanTCPw3J2qI7eM7jWnr/KveOskzbxWu4+m8pq -/+yCt1HfUvmEFWXFNrVd/7Q3s0ikUAsP2c+Qcl7sSOgj1NgMoOeDmvt+pUPLuzs7 -1ZtT7ZS9slubGUnlmM4UtlABwNIZpDgYB87qUifrhqxqLssgsHuFugrJgUTDe6h9 -cxAIpGjJAoGBAOzV8W9SrAe9GgveTtMvfYigKvWk08cNy+UAgq/VGUj/igNwrNnx -PIqx2CffYV65lrDTJrIaQq+iaiVlAnBz1ANgl9biX29jf2MUV7GxpmE1eSu14gZe -pW7gKhza8yUCRGyLcRS6ty0TPa20bxRJ/7p0YowRF9Iof8RksmOaXX4fAoGBAMYb -hWe5HzyPcBBM9ZIN+PSm2MZInZN+Y+zDTdh6RZpNoZmtMSN29ayVaG/WceaBVrEZ -rVLH5vMDpfAQjrqMk2vsRuCUiInnqIYc+HU0woUMZ6+aoAjbuYHgOOJ+jKupv+Dl -sgMFfvMM7J+kRizRmXJUIxYzfhRvxKZK7Sw0ExUDAoGALhNZSz0cNs01WgW/9BoT -JBd1BCEzClDG0CCPTEH7D1aXtR+goS3rh1geI3Oz78fPZ0tNBe1R9/VzDR9foB0I -rDeIkserpXIIAHCetvVG1zaeAkD6Xh7ftHhr+P0nvJV6VluyfkPtCxnpL/ggfCQB -Wnb2DSXuKnaylLS6d+I6OiUCgYB8KbWUC7ejKjdPUBy9fJpjI8tLgymXzqhsNQAu -RHwpOKym96CLnLxffYjmR1493SRrfS9facC64Ld43bfG/eJLytulWBK3dATwgWnL -c9TStLKrodrZknUTDGg6tJwP3yVOnEfUkvY8+QW5DKma34cv28Hd4UoNHvv+SYma -ocyv5wKBgC6nBQUe3UUJTZZD8stTbuGi1xk2BN7fw9QceGdLgP/2Ll9z/W4ZJtKJ -Btuvm5KlXNUrPRbIbCNhWdFWHBVi9GXQA28CfQyO2Cni8B+dcYP5kLuNJwMtddzg -8hxvfq5JsDbzoJIWJG6LxSffHQqminFtGTOC8h62j+lDBA5mJ1zR ------END RSA PRIVATE KEY----- diff --git a/packages/insomnia-test/misc/fixtures/mtls-ca.pem b/packages/insomnia-test/misc/fixtures/mtls-ca.pem deleted file mode 100644 index ce3947de28..0000000000 --- a/packages/insomnia-test/misc/fixtures/mtls-ca.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICvDCCAaQCCQCbsBiedsHb1DANBgkqhkiG9w0BAQsFADAgMR4wHAYDVQQDDBVJ -bnNvbW5pYSBUZXN0IG1UTFMgQ0EwHhcNMjYwODEwMDQzNzI0WhcNMzYwODA3MDQz -NzI0WjAgMR4wHAYDVQQDDBVJbnNvbW5pYSBUZXN0IG1UTFMgQ0EwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3Ru63rHVBRz1RP/2lOkF0hJ8RQ0ElGrqt -8RVspBtr7af846k4UUoxRGS9q6aGAGNuNIY4Cn3pE7DntxMmMO0vjXZ1udtHVSkK -bakh96DV2nOxVwYxXwZUbztH8OvAWOXaAG/lXsYYTkb7R7j04Lc5vKd6VKEhlosF -X+fcnSNJECS+3qSFt1dxboRe/IyjkuDJWl8yT0k8LjpIFT3UJ0ARh1tX23p03MB7 -6Ie4G4C1k1p2VO+Xma/o91f1myoVlSwX2jsgtR9yX3/2rDWMow2NvkGItPSGtBe0 -YYuafXXFXL2BSCqSXoNNnXQsACRn4zi2jXFIcTEa4q1aFbcivgVdAgMBAAEwDQYJ -KoZIhvcNAQELBQADggEBAJGRCkDsLj/KMgRiuvP4WCLvMCvjjXL8jRidR6hhnnn3 -ukGUcSjzKa80/usQw8tFvHTil9meZHEt1gjzyzDWZpUGI9qtdgkOWKdgVA/c0gb+ -uwQArd9hy5qqQ2wzeBA4dj7xrsHcUEpdepKe+WhwFp2jcJXmzJniDIkSMQBm1isb -GiwhLGv/MN5Pg1WD9ImYjVA69IYQyFKeOpstbVq194jgCP769+D/g+l97gRsCHnb -Iz7mQNWS5DY1pVTL1SqGknapoC1Q23YWsmkIohyAhDaLCOlh6A8l0lvSy69LKuNk -jwDtZFVGFZfRTSxpGLm7LBWwqmEOKnP3CsGKeKOl/xE= ------END CERTIFICATE----- diff --git a/packages/insomnia-test/misc/fixtures/mtls-client-cert.pem b/packages/insomnia-test/misc/fixtures/mtls-client-cert.pem deleted file mode 100644 index e5c183782c..0000000000 --- a/packages/insomnia-test/misc/fixtures/mtls-client-cert.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICuzCCAaMCCQDLYupB7sEMJTANBgkqhkiG9w0BAQsFADAgMR4wHAYDVQQDDBVJ -bnNvbW5pYSBUZXN0IG1UTFMgQ0EwHhcNMjYwODEwMDQzNzI0WhcNMzYwODA3MDQz -NzI0WjAfMR0wGwYDVQQDDBRpbnNvbW5pYS10ZXN0LWNsaWVudDCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAN5r/CkX/6MFLdQO7v5pXTgqQjPi/Y1yVcW+ -ksJgBwLoAbQnRvSIKne7hYFfWSVbKMzGa8Mhtgx0+R2wKRCPC+/OjOHOGaG10fmu -XmEulRc6A2sNUlC2O9joQnWg39eLk6/98d95OEgWAoSLBwHfhlKcmB+albNmug0e -Egi1RnrAWJHzi+HNVNiDYb4v/jgyWwIqQTeVJRh4XE6HHiihP8LtXl6klmrZGUnP -Zwvp/Z3YmQyQtwHz5aXQjhnoQCRzNlrnxtp/hglL3X+DudYN8sLwW8SbTN1GWDv+ -qvhN9ZSnxOLx7r0Y5EibWkmDQDvEZhXatWtju6qpd0mzzU2L96ECAwEAATANBgkq -hkiG9w0BAQsFAAOCAQEAdB+E8pLopdrq7Z95DWk/v1shkySE06O9QFe5HQPdiKXX -ffxI0EzcOwgvzpTNwYlKj/Yrq9Py2135zcZhWOvTbfjjo4otV+3Ib3AqJDfu2211 -hRhwLi6fBXRUcxRNaGf68gHxv/5Cp9akUGP91N29Rk4C2113wUUhaC/4kx4P5qHM -GmfbcGsjpDmP+Z2Q9BulP3G5KneDrefGGs0w3q4YAuxFmQJgGaNC2xaplmskSAgT -QewpzYYe5KinqsMM5tKtF756jqsBr6YoMXXJCN07hLD+OzEkaJLElnkxpq+zsr01 -UOrBxfw0PuPeJhvEsxy9Fk5Rmx+pZihOryGqySx03w== ------END CERTIFICATE----- diff --git a/packages/insomnia-test/misc/fixtures/mtls-client-key.pem b/packages/insomnia-test/misc/fixtures/mtls-client-key.pem deleted file mode 100644 index b32a63737b..0000000000 --- a/packages/insomnia-test/misc/fixtures/mtls-client-key.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEA3mv8KRf/owUt1A7u/mldOCpCM+L9jXJVxb6SwmAHAugBtCdG -9Igqd7uFgV9ZJVsozMZrwyG2DHT5HbApEI8L786M4c4ZobXR+a5eYS6VFzoDaw1S -ULY72OhCdaDf14uTr/3x33k4SBYChIsHAd+GUpyYH5qVs2a6DR4SCLVGesBYkfOL -4c1U2INhvi/+ODJbAipBN5UlGHhcToceKKE/wu1eXqSWatkZSc9nC+n9ndiZDJC3 -AfPlpdCOGehAJHM2WufG2n+GCUvdf4O51g3ywvBbxJtM3UZYO/6q+E31lKfE4vHu -vRjkSJtaSYNAO8RmFdq1a2O7qql3SbPNTYv3oQIDAQABAoIBAQC2j6vJjwkkpXuY -Mym3aIQ7NXRhYk77an08cc/D+03F9OhxFkwHKjyxShmqtrhVER3L9pE8+M6UKu7O -j2klTkRd8Qtxy9j+Al72sUiGO9Xj2pozpBuMZAd7YigqpIEWSlpOegGti7HGeUpX -wEVgJDf8VswGJLv7JLZRTf0/aIsQ9IdyEHIi7J0HCmsDOOrVJ4YzvylmPjhm6IAf -0ICWzkorKDqeGPb7SptOgn85dRaV1LalrnI0SNANeIYx7eFjI/250A4K1VP5CZO8 -NGxfnCbwa08on65+ushkt8L2ofK9nBJf32eN6jlVIFGc3QlnPoAsTGQJPp+asg6C -yA8ecuYBAoGBAPvt8okdNsqF3CmUfG2/poofsfbZL+8DvavZgr/e3DwoL1MTpspj -KS3RoaRM9XxRzoQbZ0r1LYQIaO5/TJ8PFVYxjvRyXGw/PQmHDSElV+5kCt4G9XIx -XJP/uGlg8eVLVNXc9ooDAN/5mgiXZ3n1vsOr2/Zcn2w+WzIsZXNea7O9AoGBAOID -/EUTBgRdvCZHrxS+gyhSYLL3aS1gQs2oQoA20JVgodfJ6IdALeib0zwj+qww4MBy -lZY4qIMDPwVIu4StLK6Ge6i0HSrHBhYwd58ktzRIRUimH+GIO6oyOPhsY/Anv+XA -wfHWLtNtMFhB8/81sHgGpFxFRiv4oiNb8Td8Sh+1AoGAcnkNkrYelmm6v34ECA5k -izCZufO4LyABCFw+aBbI9eDAmDw+tonWRUaS70g057d4YljdV5cOhocXvv9C/qdo -55B/R53LVzho8LJYCe6hBOaadYat8qRxT6KL1f5CDBFty/uqXs28kQkmr660Sxua -AelOeqRdoF65K5Q2yPRndfUCgYEApau0NFHAfFzVON4cyUDo1RqlRSo0D43bCfMH -ZAJKHOTrXUjkSJfTzwjB6viYm7VsWcTkP2wioX40qMPqqFNkSD3N0RjNtHiUzpkS -ZjY8kHdVSe5zuhbpXVVZC0gwbW5FrL0BrSqJwnLsGBWoK++H/kMoIXap/DtRZkfT -5g8WKm0CgYA1BV4LYp3wowS075xkrMjDpSsOn2JNecDxhOifD3GGmSk0snMly0VJ -DqCsrfdfuKIXQm10rfco/ekOX/TW2aaKopx/FNCBQytEvZ6vBv0+Ks0Q5YZBpKaO -3nnYkfsQ3DC3ARoElqaaTYRS8HZyWsn4q8eI0TXDBkWGT+nnc7aErw== ------END RSA PRIVATE KEY----- diff --git a/packages/insomnia-test/misc/fixtures/mtls-server-cert.pem b/packages/insomnia-test/misc/fixtures/mtls-server-cert.pem deleted file mode 100644 index e196b4e02b..0000000000 --- a/packages/insomnia-test/misc/fixtures/mtls-server-cert.pem +++ /dev/null @@ -1,18 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIC1TCCAb2gAwIBAgIJAMti6kHuwQwkMA0GCSqGSIb3DQEBCwUAMCAxHjAcBgNV -BAMMFUluc29tbmlhIFRlc3QgbVRMUyBDQTAeFw0yNjA4MTAwNDM3MjRaFw0zNjA4 -MDcwNDM3MjRaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBALchFJX3FxMAlZM36I7rt1CFMGAFHgvA/InV8aKkAXom -LXxCKs9/6VE0G03r+YBNp5OpMrsgQrn0djYom/9D8QnNSsmEBP/NBJJD/jgd2ueD -7/jcsERupZ3DfpL2Kqk4nTq/M7Z/yP4z/JQUjJ5WqJBPnirZZHFo1jQ8Of4+V37j -/Nw+Hk7IRcr8yOFhxY5XznR1hhszrR+3M/RDDt84jr7b9+Vaid26zYc2CVdJU9Y7 -sGOyd/+5pcwOZMHdGciQGVLupXH3wwab42xmQZSUTZa81LTITToqJ81ehqjLe4+i -KtE6SyEQqSBysnyv+ZnKSe2FN51ROuwoI0fgVBsERpECAwEAAaMeMBwwGgYDVR0R -BBMwEYIJbG9jYWxob3N0hwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBAQAzkyo+YeQH -S90xtLm8p+NB6l0mWSwzP01HMuSa7DfMPYrKH2AA8ft9H8OJ0OZmNeJDn7JzLtGf -XuiBqHmILQLWuehpLXggj3cihqRhJTnVNrCjr/DTbsV38H0YbfKps2akaNxf1Y+c -353G4sj82iHl+0AXNfDhYp/p1E6pJpVnv7bmasLxTsQEBqV+4hyfmj2vzaKN1Mro -zf+UxAhcUH42feMVoYWEJT7Whfdn0kBuRp/40gZLIRwXGRXYtrIi9H5QWBoZLiQV -MWZnjZvDCtMrRsSDYdrFODZzdDMDIrFuc9QfdaQ7+OjlEnFUVyhQ3teT9kc1gsSc -0ISbCcg9H/sA ------END CERTIFICATE----- diff --git a/packages/insomnia-test/misc/fixtures/mtls-server-key.pem b/packages/insomnia-test/misc/fixtures/mtls-server-key.pem deleted file mode 100644 index d7ada3f24f..0000000000 --- a/packages/insomnia-test/misc/fixtures/mtls-server-key.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAtyEUlfcXEwCVkzfojuu3UIUwYAUeC8D8idXxoqQBeiYtfEIq -z3/pUTQbTev5gE2nk6kyuyBCufR2Niib/0PxCc1KyYQE/80EkkP+OB3a54Pv+Nyw -RG6lncN+kvYqqTidOr8ztn/I/jP8lBSMnlaokE+eKtlkcWjWNDw5/j5XfuP83D4e -TshFyvzI4WHFjlfOdHWGGzOtH7cz9EMO3ziOvtv35VqJ3brNhzYJV0lT1juwY7J3 -/7mlzA5kwd0ZyJAZUu6lcffDBpvjbGZBlJRNlrzUtMhNOionzV6GqMt7j6Iq0TpL -IRCpIHKyfK/5mcpJ7YU3nVE67CgjR+BUGwRGkQIDAQABAoIBAHqecdRAUHjuyTh8 -FQGtn18Q72U7x/SC0hXQ5SzLuBl7+rTa8SNjOGyhAS9ZtARO+sgKYOefIE62+3gk -FOAFNB4mEc+A0IAfXNI7KLuWcf7W/xWZX4VSuR47ykLJBaOtPsoZQJ0QTxq24Iae -g9F5oQCP7w4t5e1yDwuG0CYGxDs3dfbYYcngGRPGPQi3U7O7ZSHhkI6ovkmkhkLo -kKXD73hMxtAT+CRX91lRUTc976U85F3xHgg1KTliO9tPb8+Rz+EESLFrinz81z4X -UynQqVTIPy/eiRwaAjYpOlzTjpar0Lo9l7YBmrv3irDjBqLxBx2T2hmAWoFc6O11 -YKLsHAECgYEA7NGVxjeqkKfKyQSbxCykdfQvtlstIyvpOfwGBbsyCNeRwodt3GLj -iv24p+vyQTh6orVkOb6PnhU9nLDdjpbVUr/uWJyKvoTEoy8GqoDvVkDc3ZUFSfN9 -d+oy48Vcr9ylZl6oCEH5JlbM6QJQbgyXKWE8SfF+nc5vTyGs/QwhqqECgYEAxfY/ -tHMvqJV17IAMatDpBgbR7QLiocmBLjWGFugY1YWtRaNmnXJYnvjvcL9RMt7VSZbk -RBqedAuMmaS5/H4zm++PSfcV7kb4QeQfy7bsLcesBWeT6ptgDVUnsIcPeXDdSqMM -bvo/GEysevy51Qvao6phvFgXzYnceMEcNteNhfECgYEAkNCpEglAWC0DKGGVDyVt -fGPSOWUP+Q4FFNw0opSSSC3qiFZgrAAcvQXiQW1bOt7av1zE6TrKgBTlFEhjc6pw -0KVljvJLNa3iwRcksGcf9FK9vRI/pbUr6IRikj5CK5h13F/NyR7uyK8TpvkvTdyN -I1S+lUkD8GQoVO925Vbhz4ECgYEAueprp+Ap2S0NA+C6SLMMtdE/5FS6XXFudeRk -myy87gNOWMF+BM439o0Z6oxzCNCIBUXF+UP6nkeec0lmNoCbnY5dxvxbx101mERT -rDGOG+yTXLwLCeGEUuEvljUxzj62RXtdmPhCu2J+9j5VlIU+gEjq40Tkje80dN// -zG2iBzECgYAT7pihEvHy1RKUsQ/BUjHDZMTFN2sW64o045heux0fi1/byUQptYRC -drfVOyuxRal88qrTvxUQvFOuVvfQTeBq+hcNREeLM1xasJmtyMyTSZriyFh26jHO -5Oa12t4ulgnORLyCg/sKoS+A2nVyKv2YryfzPx1H/5szUy+MbEGSDw== ------END RSA PRIVATE KEY----- diff --git a/packages/insomnia-test/misc/grpc-server.js b/packages/insomnia-test/misc/grpc-server.js index 3ef7d159c1..c5adad33fb 100644 --- a/packages/insomnia-test/misc/grpc-server.js +++ b/packages/insomnia-test/misc/grpc-server.js @@ -6,22 +6,23 @@ const path = require("node:path"); const grpc = require("@grpc/grpc-js"); const protoLoader = require("@grpc/proto-loader"); const { ReflectionService } = require("@grpc/reflection"); +const { certPath } = require("./certs"); const PROTO_PATH = path.join(__dirname, "protos", "hello.proto"); const TLS_KEY = fs.readFileSync( - path.join(__dirname, "fixtures", "localhost-key.pem"), + certPath("localhost-key.pem"), ); const TLS_CERT = fs.readFileSync( - path.join(__dirname, "fixtures", "localhost-cert.pem"), + certPath("localhost-cert.pem"), ); -const MTLS_CA = fs.readFileSync(path.join(__dirname, "fixtures", "mtls-ca.pem")); +const MTLS_CA = fs.readFileSync(certPath("mtls-ca.pem")); const MTLS_KEY = fs.readFileSync( - path.join(__dirname, "fixtures", "mtls-server-key.pem"), + certPath("mtls-server-key.pem"), ); const MTLS_CERT = fs.readFileSync( - path.join(__dirname, "fixtures", "mtls-server-cert.pem"), + certPath("mtls-server-cert.pem"), ); const packageDefinition = protoLoader.loadSync(PROTO_PATH, { diff --git a/packages/insomnia-test/misc/mcp-server.js b/packages/insomnia-test/misc/mcp-server.js index bfacc17a15..4a26a31a1f 100644 --- a/packages/insomnia-test/misc/mcp-server.js +++ b/packages/insomnia-test/misc/mcp-server.js @@ -3,17 +3,17 @@ const https = require("node:https"); const fs = require("node:fs"); -const path = require("node:path"); const express = require("express"); const { McpServer } = require("@modelcontextprotocol/sdk/server/mcp.js"); const { StreamableHTTPServerTransport, } = require("@modelcontextprotocol/sdk/server/streamableHttp.js"); const z = require("zod/v4"); +const { certPath } = require("./certs"); const HTTPS_OPTIONS = { - key: fs.readFileSync(path.join(__dirname, "fixtures", "localhost-key.pem")), - cert: fs.readFileSync(path.join(__dirname, "fixtures", "localhost-cert.pem")), + key: fs.readFileSync(certPath("localhost-key.pem")), + cert: fs.readFileSync(certPath("localhost-cert.pem")), }; function getServer() { @@ -78,6 +78,9 @@ function getServer() { return server; } +// A loopback-only mock with no cookies or sessions, so there is no ambient +// credential for a cross-site request to ride on and CSRF tokens don't apply. +// nosemgrep: javascript.express.security.audit.express-check-csurf-middleware-usage.express-check-csurf-middleware-usage const app = express(); app.use(express.json()); diff --git a/packages/insomnia-test/misc/oauth2-server.js b/packages/insomnia-test/misc/oauth2-server.js index 6996ac8725..a8086fdd13 100644 --- a/packages/insomnia-test/misc/oauth2-server.js +++ b/packages/insomnia-test/misc/oauth2-server.js @@ -11,6 +11,9 @@ const CLIENT_SECRET = "test-client-secret"; const USERNAME = "testuser"; const PASSWORD = "testpass"; +// A loopback-only mock with no cookies or sessions, so there is no ambient +// credential for a cross-site request to ride on and CSRF tokens don't apply. +// nosemgrep: javascript.express.security.audit.express-check-csurf-middleware-usage.express-check-csurf-middleware-usage const app = express(); app.use(express.urlencoded({ extended: true })); app.use(express.json()); diff --git a/packages/insomnia-test/misc/socket-server.js b/packages/insomnia-test/misc/socket-server.js index ddd1c1bef4..3b868840e1 100644 --- a/packages/insomnia-test/misc/socket-server.js +++ b/packages/insomnia-test/misc/socket-server.js @@ -4,15 +4,15 @@ const { createServer } = require("node:http"); const { createServer: createHttpsServer } = require("node:https"); const fs = require("node:fs"); -const path = require("node:path"); const { Server } = require("socket.io"); +const { certPath } = require("./certs"); const PORT = process.env.SOCKET_PORT || 3000; const SECURE_PORT = process.env.SOCKET_SECURE_PORT || 3001; const HTTPS_OPTIONS = { - key: fs.readFileSync(path.join(__dirname, "fixtures", "localhost-key.pem")), - cert: fs.readFileSync(path.join(__dirname, "fixtures", "localhost-cert.pem")), + key: fs.readFileSync(certPath("localhost-key.pem")), + cert: fs.readFileSync(certPath("localhost-cert.pem")), }; const httpServer = createServer(); diff --git a/packages/insomnia-test/misc/ws-echo-server.js b/packages/insomnia-test/misc/ws-echo-server.js index 4978b521c1..41a9b60eb6 100644 --- a/packages/insomnia-test/misc/ws-echo-server.js +++ b/packages/insomnia-test/misc/ws-echo-server.js @@ -4,15 +4,15 @@ const { createServer } = require("node:http"); const { createServer: createHttpsServer } = require("node:https"); const fs = require("node:fs"); -const path = require("node:path"); const { WebSocketServer } = require("ws"); +const { certPath } = require("./certs"); const PORT = process.env.WS_PORT || 4040; const SECURE_PORT = process.env.WS_SECURE_PORT || 4041; const HTTPS_OPTIONS = { - key: fs.readFileSync(path.join(__dirname, "fixtures", "localhost-key.pem")), - cert: fs.readFileSync(path.join(__dirname, "fixtures", "localhost-cert.pem")), + key: fs.readFileSync(certPath("localhost-key.pem")), + cert: fs.readFileSync(certPath("localhost-cert.pem")), }; function handleRequest(req, res) { diff --git a/packages/insomnia-test/package.json b/packages/insomnia-test/package.json index f926efc885..e34c8c2319 100644 --- a/packages/insomnia-test/package.json +++ b/packages/insomnia-test/package.json @@ -27,6 +27,7 @@ "git-http-backend": "^1.1.2", "graphql": "^17.0.2", "monocart-coverage-reports": "^2.13.0", + "node-forge": "^1.4.0", "socket.io": "^4.8.3", "ws": "^8.21.1", "zod": "^4.4.3" diff --git a/packages/insomnia-test/playwright.config.ts b/packages/insomnia-test/playwright.config.ts index 188efb86a8..b1c7c5f7c1 100644 --- a/packages/insomnia-test/playwright.config.ts +++ b/packages/insomnia-test/playwright.config.ts @@ -2,6 +2,8 @@ import path from "node:path"; import { defineConfig, devices } from "@playwright/test"; +import { ensureCerts } from "./misc/certs"; + // By default, misc/fixtures.ts launches the app straight out of the // sibling ../insomnia source checkout (its local `electron` binary against // packages/insomnia) instead of a packaged build — so the app under test @@ -22,6 +24,10 @@ const isDevMode = process.env.INSOMNIA_DEV_MODE !== "0"; const INSOMNIA_SRC_PACKAGE = path.resolve(__dirname, "..", "insomnia"); +// The mock servers' TLS/mTLS key pairs are generated rather than committed. +// Do it here, once, before any webServer below starts reading them. +ensureCerts(); + export default defineConfig({ timeout: 90 * 1000, testDir: "./tests", diff --git a/packages/insomnia-test/tests/grpc-request/mtls-client-certificate.spec.ts b/packages/insomnia-test/tests/grpc-request/mtls-client-certificate.spec.ts index 98f723562f..4b296ba1e2 100644 --- a/packages/insomnia-test/tests/grpc-request/mtls-client-certificate.spec.ts +++ b/packages/insomnia-test/tests/grpc-request/mtls-client-certificate.spec.ts @@ -3,6 +3,7 @@ import path from "node:path"; import { faker } from "@faker-js/faker"; import { ProjectType } from "../../enums/project-types"; +import { certPath } from "../../misc/certs"; import { expect, GRPC_SERVER_MTLS,test } from "../../misc/fixtures"; import { Collection } from "../../models/collection"; import { Project } from "../../models/project"; @@ -38,8 +39,8 @@ test("Verify Client Certificate Toggle Controls mTLS Enforcement For gRPC Reques await certificatesFlow.addClientCertificate(collection, { host: "localhost", - cert: path.join(__dirname, "../../misc/fixtures/mtls-client-cert.pem"), - key: path.join(__dirname, "../../misc/fixtures/mtls-client-key.pem"), + cert: certPath("mtls-client-cert.pem"), + key: certPath("mtls-client-key.pem"), }); const greeting = faker.person.firstName(); diff --git a/packages/insomnia-test/tests/http-request/custom-ca-root-certificate.spec.ts b/packages/insomnia-test/tests/http-request/custom-ca-root-certificate.spec.ts index 9528af1d0c..7740b49db7 100644 --- a/packages/insomnia-test/tests/http-request/custom-ca-root-certificate.spec.ts +++ b/packages/insomnia-test/tests/http-request/custom-ca-root-certificate.spec.ts @@ -1,9 +1,9 @@ -import path from "node:path"; import { faker } from "@faker-js/faker"; import { HttpMethod } from "../../enums/http-method"; import { ProjectType } from "../../enums/project-types"; +import { certPath } from "../../misc/certs"; import { DEFAULT_TIMEOUT, expect, @@ -41,7 +41,7 @@ test("Verify Custom CA Root Certificate Establishes Trust For HTTPS Request", as await certificatesFlow.setCaCertificate( collection, - path.join(__dirname, "../../misc/fixtures/mtls-ca.pem"), + certPath("mtls-ca.pem"), ); const requestAfterCa = await httpRequestFlow.create(collection, { diff --git a/packages/insomnia-test/tests/http-request/mtls-client-certificate.spec.ts b/packages/insomnia-test/tests/http-request/mtls-client-certificate.spec.ts index 97007f25cf..f40123006e 100644 --- a/packages/insomnia-test/tests/http-request/mtls-client-certificate.spec.ts +++ b/packages/insomnia-test/tests/http-request/mtls-client-certificate.spec.ts @@ -4,6 +4,7 @@ import { faker } from "@faker-js/faker"; import { HttpMethod } from "../../enums/http-method"; import { ProjectType } from "../../enums/project-types"; +import { certPath } from "../../misc/certs"; import { DEFAULT_TIMEOUT, expect, @@ -47,8 +48,8 @@ test("Verify Client Certificate Toggle Controls mTLS Enforcement For HTTP Reques await certificatesFlow.addClientCertificate(collection, { host: "localhost", - cert: path.join(__dirname, "../../misc/fixtures/mtls-client-cert.pem"), - key: path.join(__dirname, "../../misc/fixtures/mtls-client-key.pem"), + cert: certPath("mtls-client-cert.pem"), + key: certPath("mtls-client-key.pem"), }); const requestWithCert = await httpRequestFlow.create(collection, {