@qa-ai-stlc/runner-security 0.0.0-stage → 1.8.0

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 (94) hide show
  1. package/README.md +52 -2
  2. package/dist/checks/authz-check.d.ts +9 -0
  3. package/dist/checks/authz-check.d.ts.map +1 -0
  4. package/dist/checks/authz-check.js +100 -0
  5. package/dist/checks/authz-check.js.map +1 -0
  6. package/dist/checks/code-check-support.d.ts +9 -0
  7. package/dist/checks/code-check-support.d.ts.map +1 -0
  8. package/dist/checks/code-check-support.js +19 -0
  9. package/dist/checks/code-check-support.js.map +1 -0
  10. package/dist/checks/configuration-check.d.ts +10 -0
  11. package/dist/checks/configuration-check.d.ts.map +1 -0
  12. package/dist/checks/configuration-check.js +128 -0
  13. package/dist/checks/configuration-check.js.map +1 -0
  14. package/dist/checks/cookies-check.d.ts +10 -0
  15. package/dist/checks/cookies-check.d.ts.map +1 -0
  16. package/dist/checks/cookies-check.js +113 -0
  17. package/dist/checks/cookies-check.js.map +1 -0
  18. package/dist/checks/cors-check.d.ts +10 -0
  19. package/dist/checks/cors-check.d.ts.map +1 -0
  20. package/dist/checks/cors-check.js +55 -0
  21. package/dist/checks/cors-check.js.map +1 -0
  22. package/dist/checks/csrf-check.d.ts +10 -0
  23. package/dist/checks/csrf-check.d.ts.map +1 -0
  24. package/dist/checks/csrf-check.js +108 -0
  25. package/dist/checks/csrf-check.js.map +1 -0
  26. package/dist/checks/dependencies-check.d.ts +10 -0
  27. package/dist/checks/dependencies-check.d.ts.map +1 -0
  28. package/dist/checks/dependencies-check.js +160 -0
  29. package/dist/checks/dependencies-check.js.map +1 -0
  30. package/dist/checks/encoding-check.d.ts +10 -0
  31. package/dist/checks/encoding-check.d.ts.map +1 -0
  32. package/dist/checks/encoding-check.js +67 -0
  33. package/dist/checks/encoding-check.js.map +1 -0
  34. package/dist/checks/errors-check.d.ts +8 -0
  35. package/dist/checks/errors-check.d.ts.map +1 -0
  36. package/dist/checks/errors-check.js +60 -0
  37. package/dist/checks/errors-check.js.map +1 -0
  38. package/dist/checks/headers-check.d.ts +9 -0
  39. package/dist/checks/headers-check.d.ts.map +1 -0
  40. package/dist/checks/headers-check.js +110 -0
  41. package/dist/checks/headers-check.js.map +1 -0
  42. package/dist/checks/secrets-check.d.ts +10 -0
  43. package/dist/checks/secrets-check.d.ts.map +1 -0
  44. package/dist/checks/secrets-check.js +113 -0
  45. package/dist/checks/secrets-check.js.map +1 -0
  46. package/dist/checks/session-check.d.ts +10 -0
  47. package/dist/checks/session-check.d.ts.map +1 -0
  48. package/dist/checks/session-check.js +87 -0
  49. package/dist/checks/session-check.js.map +1 -0
  50. package/dist/checks/session-pages.d.ts +11 -0
  51. package/dist/checks/session-pages.d.ts.map +1 -0
  52. package/dist/checks/session-pages.js +25 -0
  53. package/dist/checks/session-pages.js.map +1 -0
  54. package/dist/cookie-flags.d.ts +14 -0
  55. package/dist/cookie-flags.d.ts.map +1 -0
  56. package/dist/cookie-flags.js +28 -0
  57. package/dist/cookie-flags.js.map +1 -0
  58. package/dist/default-checks.d.ts +4 -0
  59. package/dist/default-checks.d.ts.map +1 -0
  60. package/dist/default-checks.js +28 -0
  61. package/dist/default-checks.js.map +1 -0
  62. package/dist/fetch-page.d.ts +19 -0
  63. package/dist/fetch-page.d.ts.map +1 -0
  64. package/dist/fetch-page.js +36 -0
  65. package/dist/fetch-page.js.map +1 -0
  66. package/dist/finding.d.ts +8 -0
  67. package/dist/finding.d.ts.map +1 -0
  68. package/dist/finding.js +14 -0
  69. package/dist/finding.js.map +1 -0
  70. package/dist/identity-sessions.d.ts +42 -0
  71. package/dist/identity-sessions.d.ts.map +1 -0
  72. package/dist/identity-sessions.js +102 -0
  73. package/dist/identity-sessions.js.map +1 -0
  74. package/dist/index.d.ts +8 -0
  75. package/dist/index.d.ts.map +1 -0
  76. package/dist/index.js +10 -0
  77. package/dist/index.js.map +1 -0
  78. package/dist/security-audit.d.ts +30 -0
  79. package/dist/security-audit.d.ts.map +1 -0
  80. package/dist/security-audit.js +173 -0
  81. package/dist/security-audit.js.map +1 -0
  82. package/dist/security-check.d.ts +30 -0
  83. package/dist/security-check.d.ts.map +1 -0
  84. package/dist/security-check.js +4 -0
  85. package/dist/security-check.js.map +1 -0
  86. package/dist/security-probe.d.ts +56 -0
  87. package/dist/security-probe.d.ts.map +1 -0
  88. package/dist/security-probe.js +128 -0
  89. package/dist/security-probe.js.map +1 -0
  90. package/dist/source-checkout.d.ts +56 -0
  91. package/dist/source-checkout.d.ts.map +1 -0
  92. package/dist/source-checkout.js +140 -0
  93. package/dist/source-checkout.js.map +1 -0
  94. package/package.json +36 -4
@@ -0,0 +1,140 @@
1
+ // Copyright The QA-AI-STLC Authors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { posix } from 'node:path';
4
+ import { assertRelativePath, resolveRelativePath, toRelativePath, } from '@qa-ai-stlc/core';
5
+ export const DEFAULT_MAX_SOURCE_FILES = 3000;
6
+ export const DEFAULT_MAX_SOURCE_FILE_SIZE_BYTES = 256 * 1024;
7
+ // Directories that hold installed or generated code rather than what the team wrote. Their content
8
+ // is somebody else's (or a copy of it), and walking them would bury the checkout's own files.
9
+ const IGNORED_DIRECTORIES = new Set([
10
+ '.git',
11
+ 'node_modules',
12
+ 'dist',
13
+ 'build',
14
+ 'coverage',
15
+ '.next',
16
+ '.nuxt',
17
+ '.qa',
18
+ '.venv',
19
+ '__pycache__',
20
+ 'vendor',
21
+ 'target',
22
+ ]);
23
+ const BINARY_EXTENSIONS = new Set([
24
+ '.png',
25
+ '.jpg',
26
+ '.jpeg',
27
+ '.gif',
28
+ '.webp',
29
+ '.ico',
30
+ '.bmp',
31
+ '.pdf',
32
+ '.zip',
33
+ '.gz',
34
+ '.tgz',
35
+ '.jar',
36
+ '.woff',
37
+ '.woff2',
38
+ '.ttf',
39
+ '.eot',
40
+ '.otf',
41
+ '.mp3',
42
+ '.mp4',
43
+ '.mov',
44
+ '.exe',
45
+ '.dll',
46
+ '.so',
47
+ '.map',
48
+ ]);
49
+ // A NUL byte near the start is the usual sign of a file that is not text.
50
+ const BINARY_SNIFF_BYTES = 1024;
51
+ /**
52
+ * A read-only view of the application's source checkout (`source.path`). It exposes no write, so a
53
+ * code-assisted check cannot change the code it audits (AGENTS.md 12.4). The scan is bounded by a
54
+ * file count and a file size and says when it was cut short, so a clean result is never mistaken
55
+ * for a complete one.
56
+ */
57
+ export class SourceCheckout {
58
+ /** Project-relative with `/` separators; `''` when the checkout is the project root itself. */
59
+ relativeRoot;
60
+ processRunner;
61
+ projectRoot;
62
+ fs;
63
+ maxFiles;
64
+ maxFileSizeBytes;
65
+ constructor(options) {
66
+ const normalizedRoot = posix.normalize(options.relativeRoot).replace(/\/$/u, '');
67
+ this.relativeRoot = normalizedRoot === '.' ? '' : normalizedRoot;
68
+ this.processRunner = options.processRunner;
69
+ this.projectRoot = options.projectRoot;
70
+ this.fs = options.fs;
71
+ this.maxFiles = options.maxFiles ?? DEFAULT_MAX_SOURCE_FILES;
72
+ this.maxFileSizeBytes = options.maxFileSizeBytes ?? DEFAULT_MAX_SOURCE_FILE_SIZE_BYTES;
73
+ }
74
+ /** The text files of the checkout in a stable order, without installed or generated directories. */
75
+ async scan() {
76
+ const root = this.absoluteDirectory(this.relativeRoot);
77
+ const candidates = (await this.fs.listFiles(root))
78
+ .map((absolutePath) => toRelativePath(this.projectRoot, absolutePath))
79
+ .filter((path) => this.isInsideRoot(path) && !this.isInIgnoredDirectory(path))
80
+ .sort();
81
+ const isTruncated = candidates.length > this.maxFiles;
82
+ const files = [];
83
+ let skippedCount = 0;
84
+ for (const path of candidates.slice(0, this.maxFiles)) {
85
+ const text = await this.readText(path);
86
+ if (text === undefined) {
87
+ skippedCount += 1;
88
+ continue;
89
+ }
90
+ files.push({ path, text });
91
+ }
92
+ return { files, isTruncated, skippedCount };
93
+ }
94
+ /** One file's text, or `undefined` when it is missing, binary or over the size limit. */
95
+ async readText(path) {
96
+ const absolutePath = resolveRelativePath(this.projectRoot, path);
97
+ if (BINARY_EXTENSIONS.has(posix.extname(path).toLowerCase()) ||
98
+ !(await this.fs.pathExists(absolutePath))) {
99
+ return undefined;
100
+ }
101
+ const bytes = await this.fs.readBytes(absolutePath);
102
+ if (bytes.length > this.maxFileSizeBytes || bytes.subarray(0, BINARY_SNIFF_BYTES).includes(0)) {
103
+ return undefined;
104
+ }
105
+ return Buffer.from(bytes).toString('utf-8');
106
+ }
107
+ /**
108
+ * The nearest directory, from the checkout's root up to the project root, that holds `fileName`:
109
+ * project-relative, `''` for the project root itself. A monorepo keeps one lockfile above the
110
+ * packages it covers.
111
+ */
112
+ async findDirectoryWith(fileName) {
113
+ let directory = this.relativeRoot;
114
+ for (;;) {
115
+ const candidate = directory === '' ? fileName : posix.join(directory, fileName);
116
+ if (await this.fs.pathExists(resolveRelativePath(this.projectRoot, assertRelativePath(candidate)))) {
117
+ return directory;
118
+ }
119
+ if (directory === '') {
120
+ return undefined;
121
+ }
122
+ const parent = posix.dirname(directory);
123
+ directory = parent === '.' ? '' : parent;
124
+ }
125
+ }
126
+ /** The absolute, OS-native path of a project-relative directory (`''` is the project root). */
127
+ absoluteDirectory(relativeDirectory) {
128
+ return relativeDirectory === ''
129
+ ? this.projectRoot
130
+ : resolveRelativePath(this.projectRoot, assertRelativePath(relativeDirectory));
131
+ }
132
+ isInsideRoot(path) {
133
+ return this.relativeRoot === '' || path.startsWith(`${this.relativeRoot}/`);
134
+ }
135
+ isInIgnoredDirectory(path) {
136
+ const relativeToRoot = (this.relativeRoot === '' ? path : path.slice(this.relativeRoot.length + 1)).split('/');
137
+ return relativeToRoot.slice(0, -1).some((segment) => IGNORED_DIRECTORIES.has(segment));
138
+ }
139
+ }
140
+ //# sourceMappingURL=source-checkout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-checkout.js","sourceRoot":"","sources":["../src/source-checkout.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,38 @@
1
1
  {
2
2
  "name": "@qa-ai-stlc/runner-security",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.8.0",
4
+ "description": "On-demand, non-destructive black-box security audit: an authorization-gated probe, security checks and findings registered as evidence and defect drafts.",
5
+ "type": "module",
6
+ "license": "Apache-2.0",
7
+ "homepage": "https://github.com/Klim-101/QA-AI-STLC/tree/main/packages/runner-security#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/Klim-101/QA-AI-STLC.git",
11
+ "directory": "packages/runner-security"
12
+ },
13
+ "bugs": "https://github.com/Klim-101/QA-AI-STLC/issues",
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "exports": {
18
+ ".": "./dist/index.js"
19
+ },
20
+ "scripts": {
21
+ "pretypecheck": "npm run build --workspace @qa-ai-stlc/schemas --workspace @qa-ai-stlc/core --workspace @qa-ai-stlc/test-utils",
22
+ "typecheck": "tsc --noEmit -p .",
23
+ "pretest": "npm run build --workspace @qa-ai-stlc/schemas --workspace @qa-ai-stlc/core --workspace @qa-ai-stlc/test-utils",
24
+ "test": "vitest run",
25
+ "pretest:coverage": "npm run build --workspace @qa-ai-stlc/schemas --workspace @qa-ai-stlc/core --workspace @qa-ai-stlc/test-utils",
26
+ "test:coverage": "vitest run --coverage",
27
+ "build": "tsc -b tsconfig.build.json",
28
+ "clean": "node ../../scripts/clean-dir.mjs dist"
29
+ },
30
+ "dependencies": {
31
+ "@qa-ai-stlc/core": "1.8.0",
32
+ "@qa-ai-stlc/schemas": "1.8.0",
33
+ "zod": "4.6.5"
34
+ },
35
+ "devDependencies": {
36
+ "@qa-ai-stlc/test-utils": "0.0.0"
37
+ }
38
+ }