securl 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/CHANGELOG.md +241 -0
  2. package/LICENSE +21 -0
  3. package/README.md +427 -0
  4. package/RELEASING.md +37 -0
  5. package/SECURITY.md +27 -0
  6. package/dist/certificate.d.ts +5 -0
  7. package/dist/certificate.js +92 -0
  8. package/dist/cli.d.ts +1 -0
  9. package/dist/cli.js +674 -0
  10. package/dist/compromiseSignals.d.ts +10 -0
  11. package/dist/compromiseSignals.js +183 -0
  12. package/dist/cookie-analysis.d.ts +2 -0
  13. package/dist/cookie-analysis.js +41 -0
  14. package/dist/cookieAnalysis.d.ts +2 -0
  15. package/dist/cookieAnalysis.js +82 -0
  16. package/dist/ctDiscovery.d.ts +19 -0
  17. package/dist/ctDiscovery.js +357 -0
  18. package/dist/domain-security.d.ts +10 -0
  19. package/dist/domain-security.js +416 -0
  20. package/dist/header-analysis.d.ts +14 -0
  21. package/dist/header-analysis.js +165 -0
  22. package/dist/historyDiff.d.ts +4 -0
  23. package/dist/historyDiff.js +117 -0
  24. package/dist/html-extraction.d.ts +12 -0
  25. package/dist/html-extraction.js +279 -0
  26. package/dist/html-page-analysis.d.ts +38 -0
  27. package/dist/html-page-analysis.js +459 -0
  28. package/dist/htmlInsights.d.ts +23 -0
  29. package/dist/htmlInsights.js +460 -0
  30. package/dist/identityProvider.d.ts +14 -0
  31. package/dist/identityProvider.js +259 -0
  32. package/dist/index.d.ts +17 -0
  33. package/dist/index.js +1008 -0
  34. package/dist/infrastructure.d.ts +9 -0
  35. package/dist/infrastructure.js +149 -0
  36. package/dist/libraryRisk.d.ts +3 -0
  37. package/dist/libraryRisk.js +164 -0
  38. package/dist/network-validation.d.ts +30 -0
  39. package/dist/network-validation.js +161 -0
  40. package/dist/network.d.ts +34 -0
  41. package/dist/network.js +139 -0
  42. package/dist/passive-intelligence.d.ts +21 -0
  43. package/dist/passive-intelligence.js +247 -0
  44. package/dist/path-discovery.d.ts +4 -0
  45. package/dist/path-discovery.js +50 -0
  46. package/dist/postureDigest.d.ts +142 -0
  47. package/dist/postureDigest.js +159 -0
  48. package/dist/postureDrift.d.ts +4 -0
  49. package/dist/postureDrift.js +118 -0
  50. package/dist/postureRemediation.d.ts +6 -0
  51. package/dist/postureRemediation.js +286 -0
  52. package/dist/redirectChain.d.ts +2 -0
  53. package/dist/redirectChain.js +39 -0
  54. package/dist/riskEvents.d.ts +3 -0
  55. package/dist/riskEvents.js +187 -0
  56. package/dist/scannerConfig.d.ts +49 -0
  57. package/dist/scannerConfig.js +79 -0
  58. package/dist/scoring.d.ts +32 -0
  59. package/dist/scoring.js +367 -0
  60. package/dist/security-txt.d.ts +4 -0
  61. package/dist/security-txt.js +123 -0
  62. package/dist/surfaceEnrichment.d.ts +44 -0
  63. package/dist/surfaceEnrichment.js +377 -0
  64. package/dist/technology-detection.d.ts +4 -0
  65. package/dist/technology-detection.js +93 -0
  66. package/dist/types.d.ts +730 -0
  67. package/dist/types.js +1 -0
  68. package/dist/utils.d.ts +7 -0
  69. package/dist/utils.js +66 -0
  70. package/dist/wafFingerprint.d.ts +5 -0
  71. package/dist/wafFingerprint.js +156 -0
  72. package/examples/risk-events.mjs +27 -0
  73. package/examples/scan-url.mjs +17 -0
  74. package/package.json +102 -0
package/RELEASING.md ADDED
@@ -0,0 +1,37 @@
1
+ # Releasing `securl`
2
+
3
+ ## Pre-release checklist
4
+
5
+ Only release `securl` when the package itself changes. Backend-only API resources, hosted app deploy scripts, Railway settings, Hostinger static deploys, and app-only UI changes do not warrant a core package bump unless they also change files that are published from `packages/core`.
6
+
7
+ Version bump guidance:
8
+
9
+ - **Patch**: bug fixes, scoring calibration fixes, false-positive/false-negative corrections, dependency/runtime fixes, or docs/signalling updates intentionally worth republishing.
10
+ - **Minor**: new exported helpers, new analysis signals, new CLI options, new report formats, new typed result fields, or additive public API changes.
11
+ - **Major**: breaking changes to exported functions, CLI commands/options, package exports, result types, scoring semantics that consumers must handle differently, or supported Node/runtime expectations.
12
+
13
+ Before deciding to bump, check what changed since the latest core tag:
14
+
15
+ ```sh
16
+ git diff --name-status securl-v$(node -p "require('./packages/core/package.json').version")..HEAD -- packages/core package.json package-lock.json
17
+ ```
18
+
19
+ 1. Update `packages/core/package.json` version.
20
+ 2. Update `packages/core/CHANGELOG.md`.
21
+ 3. Run:
22
+ - `npm run release:core:check`
23
+ 4. Review the dry-run tarball contents.
24
+ 5. Confirm `NPM_TOKEN` is present in GitHub repository secrets.
25
+
26
+ ## Release steps
27
+
28
+ 1. Commit the version/changelog update.
29
+ 2. Tag the release using `securl-v<version>`, for example `securl-v1.4.1`.
30
+ 3. Push the tag.
31
+ 4. Let `.github/workflows/publish-core-package.yml` publish the package.
32
+
33
+ ## Post-release
34
+
35
+ 1. Confirm the package is available on npm.
36
+ 2. Verify import/install instructions from the published artifact.
37
+ 3. Move changelog notes from `Unreleased` to the released version section.
package/SECURITY.md ADDED
@@ -0,0 +1,27 @@
1
+ # Security Policy for `securl`
2
+
3
+ This package is published from the public source repository:
4
+
5
+ - `https://github.com/this-is-securl/securl`
6
+
7
+ ## Reporting a vulnerability
8
+
9
+ Please report suspected vulnerabilities privately via:
10
+
11
+ - GitHub security advisory / private vulnerability report on the repository, or
12
+ - email `keithbatterham@pm.me`
13
+
14
+ Please avoid filing public issues for security-sensitive reports.
15
+
16
+ ## Package trust signals
17
+
18
+ - public source repository
19
+ - reproducible package contents via `npm pack --dry-run`
20
+ - GitHub Actions release workflow
21
+ - npm provenance enabled at publish time
22
+ - no install scripts
23
+ - one runtime dependency (`node-html-parser`)
24
+
25
+ ## Scope note
26
+
27
+ This package performs network-facing posture analysis by design. That can look high-risk to automated package reputation systems, but the intended use is defensive scanning against targets you own or are authorized to assess.
@@ -0,0 +1,5 @@
1
+ import type { CertificateResult } from "./types.js";
2
+ export declare const OBSERVATIONAL_TLS_OPTIONS: {
3
+ rejectUnauthorized: boolean;
4
+ };
5
+ export declare const scanTls: (targetUrl: URL) => Promise<CertificateResult>;
@@ -0,0 +1,92 @@
1
+ import tls from "node:tls";
2
+ import { TLS_HANDSHAKE_TIMEOUT_MS } from "./scannerConfig.js";
3
+ const firstStringValue = (value) => {
4
+ if (typeof value === "string") {
5
+ return value;
6
+ }
7
+ if (Array.isArray(value)) {
8
+ const first = value.find((item) => typeof item === "string");
9
+ return typeof first === "string" ? first : null;
10
+ }
11
+ return null;
12
+ };
13
+ const allowInsecureTls = process.env.EXTERNAL_POSTURE_ALLOW_INSECURE_TLS === "1";
14
+ export const OBSERVATIONAL_TLS_OPTIONS = {
15
+ // Keep certificate verification on by default.
16
+ // Set EXTERNAL_POSTURE_ALLOW_INSECURE_TLS=1 only for controlled observational runs.
17
+ rejectUnauthorized: !allowInsecureTls,
18
+ };
19
+ export const scanTls = (targetUrl) => {
20
+ if (targetUrl.protocol !== "https:") {
21
+ return Promise.resolve({
22
+ available: false,
23
+ valid: false,
24
+ authorized: false,
25
+ issuer: null,
26
+ subject: null,
27
+ validFrom: null,
28
+ validTo: null,
29
+ daysRemaining: null,
30
+ protocol: null,
31
+ cipher: null,
32
+ fingerprint: null,
33
+ subjectAltName: [],
34
+ issues: ["TLS certificate data is only available for HTTPS targets."],
35
+ });
36
+ }
37
+ return new Promise((resolve, reject) => {
38
+ const socket = tls.connect({
39
+ host: targetUrl.hostname,
40
+ port: Number(targetUrl.port || 443),
41
+ servername: targetUrl.hostname,
42
+ ...OBSERVATIONAL_TLS_OPTIONS,
43
+ timeout: TLS_HANDSHAKE_TIMEOUT_MS,
44
+ });
45
+ socket.once("secureConnect", () => {
46
+ const certificate = socket.getPeerCertificate(true);
47
+ const protocol = socket.getProtocol?.() || null;
48
+ const cipherInfo = socket.getCipher?.();
49
+ const validTo = certificate?.valid_to || null;
50
+ const validFrom = certificate?.valid_from || null;
51
+ const daysRemaining = validTo
52
+ ? Math.ceil((new Date(validTo).getTime() - Date.now()) / (1000 * 60 * 60 * 24))
53
+ : null;
54
+ const subjectAltName = typeof certificate?.subjectaltname === "string"
55
+ ? certificate.subjectaltname.split(",").map((entry) => entry.trim().replace(/^DNS:/, ""))
56
+ : [];
57
+ const issues = [];
58
+ if (!socket.authorized) {
59
+ issues.push(typeof socket.authorizationError === "string"
60
+ ? socket.authorizationError
61
+ : "Certificate is not trusted.");
62
+ }
63
+ if (allowInsecureTls) {
64
+ issues.push("Insecure TLS observation mode is enabled via EXTERNAL_POSTURE_ALLOW_INSECURE_TLS.");
65
+ }
66
+ if (daysRemaining !== null && daysRemaining <= 14)
67
+ issues.push("Certificate expires very soon.");
68
+ if (protocol && /tlsv1(\.0|\.1)?$/i.test(protocol))
69
+ issues.push("TLS protocol is outdated.");
70
+ resolve({
71
+ available: true,
72
+ valid: Boolean(socket.authorized),
73
+ authorized: Boolean(socket.authorized),
74
+ issuer: firstStringValue(certificate?.issuer?.O) ?? firstStringValue(certificate?.issuer?.CN),
75
+ subject: firstStringValue(certificate?.subject?.CN),
76
+ validFrom,
77
+ validTo,
78
+ daysRemaining,
79
+ protocol,
80
+ cipher: cipherInfo?.name || null,
81
+ fingerprint: certificate?.fingerprint256 || null,
82
+ subjectAltName,
83
+ issues,
84
+ });
85
+ socket.end();
86
+ });
87
+ socket.once("timeout", () => {
88
+ socket.destroy(new Error("TLS handshake timed out."));
89
+ });
90
+ socket.once("error", reject);
91
+ });
92
+ };
package/dist/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {};