Skip to content

Commit f6a91a9

Browse files
committed
feat: harden security research workflows
Signed-off-by: zebbern <185730623+zebbern@users.noreply.github.com>
1 parent 2392c92 commit f6a91a9

178 files changed

Lines changed: 16358 additions & 7831 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,10 @@ bun run dev:fe # Frontend-only dev (no Docker needed)
8181

8282
### Integrated Tooling
8383

84-
29 security components wrapping industry-standard open-source tools:
84+
34 security components wrapping industry-standard open-source tools:
8585

8686
- **Discovery & Recon**: `Subfinder`, `Amass`, `DNSX`, `Naabu`, `HTTPx`, `Katana`, `theHarvester`, `ShuffleDNS`
87-
- **Vulnerability Scanning**: `Nuclei`, `Trivy`, `Semgrep`, `Checkov`, `TestSSL`
87+
- **Vulnerability Scanning**: `Nuclei`, `Trivy`, `Semgrep`, `OpenGrep`, `CodeQL`, `Jazzer.js`, `Checkov`, `TestSSL`
8888
- **Secret Detection**: `TruffleHog`
8989
- **Threat Intelligence**: `AbuseIPDB`, `VirusTotal`, `YARA`, `NPM Registry Intel`
9090
- **Web Security**: `Ffuf`, `Wafw00f`, `Prowler`, `Supabase Scanner`

backend/scripts/seed-templates.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -303,9 +303,7 @@ export async function seedTemplates(): Promise<void> {
303303
REMOVED_OFFICIAL_SEED_TEMPLATES,
304304
);
305305
if (deactivated > 0) {
306-
console.log(
307-
`\n Deactivated ${deactivated} retired official seed template(s)`,
308-
);
306+
console.log(`\n Deactivated ${deactivated} retired official seed template(s)`);
309307
}
310308

311309
console.log(`\nDone: ${inserted} inserted, ${updated} updated, ${deactivated} deactivated\n`);

backend/scripts/seed-templates/github-actions-supply-chain-triage.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@
8989
"config": {
9090
"params": {
9191
"ref": "main",
92-
"maxFiles": 80,
9392
"maxTotalBytes": 250000,
9493
"maxFileBytes": 50000
9594
},

backend/scripts/seed-templates/npm-cve-hunt-pipeline.json

Lines changed: 2295 additions & 493 deletions
Large diffs are not rendered by default.

backend/scripts/seed-templates/oss-sast-cve-candidate-hunt.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@
7777
"config": {
7878
"params": {
7979
"ref": "main",
80-
"maxFiles": 80,
8180
"maxTotalBytes": 250000,
8281
"maxFileBytes": 50000
8382
},

backend/scripts/seed-templates/public-repo-code-iac-risk-triage.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@
7575
"config": {
7676
"params": {
7777
"ref": "main",
78-
"maxFiles": 80,
7978
"maxTotalBytes": 250000,
8079
"maxFileBytes": 50000
8180
},

backend/scripts/seed-templates/public-repo-full-code-security.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,6 @@
117117
"config": {
118118
"params": {
119119
"ref": "main",
120-
"maxFiles": 80,
121120
"maxTotalBytes": 250000,
122121
"maxFileBytes": 50000
123122
},

backend/src/agent-skills/__tests__/agent-skill-bundle.spec.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,10 @@ description: Analyze KEV briefs
7171

7272
it('mergeSkillFilesForResponse falls back to content', () => {
7373
expect(
74-
mergeSkillFilesForResponse({ content: '# Legacy', files: null as unknown as Record<string, string> }),
74+
mergeSkillFilesForResponse({
75+
content: '# Legacy',
76+
files: null as unknown as Record<string, string>,
77+
}),
7578
).toEqual({ 'SKILL.md': '# Legacy' });
7679
});
7780

backend/src/agent-skills/agent-skill-bundle.ts

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,23 @@ export const DEFAULT_AGENT_SKILL_DISCOVERY_DIRS = [
1717

1818
export type AgentSkillFileMap = Record<string, string>;
1919

20-
export type ParsedSkillBundle = {
20+
export interface ParsedSkillBundle {
2121
slug: string;
2222
name: string;
2323
description: string | null;
2424
files: AgentSkillFileMap;
2525
content: string;
2626
tags: string[];
27-
};
27+
}
2828

29-
export type DiscoveredAgentSkillSummary = {
29+
export interface DiscoveredAgentSkillSummary {
3030
slug: string;
3131
name: string;
3232
description: string | null;
3333
sourceRoot: string;
3434
relativePath: string;
3535
fileCount: number;
36-
};
36+
}
3737

3838
function isRecord(value: unknown): value is Record<string, unknown> {
3939
return typeof value === 'object' && value !== null && !Array.isArray(value);
@@ -62,7 +62,10 @@ export function resolveAgentSkillsWorkspaceRoot(): string {
6262
export function resolveAgentSkillDiscoveryDirs(workspaceRoot?: string): string[] {
6363
const configured = process.env.SENTRIS_AGENT_SKILLS_DISCOVERY_DIRS?.trim();
6464
const relativeDirs = configured
65-
? configured.split(',').map((dir) => dir.trim()).filter(Boolean)
65+
? configured
66+
.split(',')
67+
.map((dir) => dir.trim())
68+
.filter(Boolean)
6669
: [...DEFAULT_AGENT_SKILL_DISCOVERY_DIRS];
6770

6871
const root = workspaceRoot ?? resolveAgentSkillsWorkspaceRoot();
@@ -111,7 +114,10 @@ export function parseSkillMdFrontmatter(content: string): {
111114
const separator = line.indexOf(':');
112115
if (separator <= 0) continue;
113116
const key = line.slice(0, separator).trim();
114-
const value = line.slice(separator + 1).trim().replace(/^['"]|['"]$/g, '');
117+
const value = line
118+
.slice(separator + 1)
119+
.trim()
120+
.replace(/^['"]|['"]$/g, '');
115121
if (key === 'name') metadata.name = value;
116122
if (key === 'description') metadata.description = value;
117123
if (key === 'tags') {
@@ -181,7 +187,10 @@ export function normalizeSkillBundle(input: {
181187
};
182188
}
183189

184-
async function readTextFileIfAllowed(filePath: string, relativePath: string): Promise<string | null> {
190+
async function readTextFileIfAllowed(
191+
filePath: string,
192+
relativePath: string,
193+
): Promise<string | null> {
185194
validateSkillRelativePath(relativePath);
186195
const fileStat = await stat(filePath);
187196
if (!fileStat.isFile() || fileStat.size > AGENT_SKILL_FILE_MAX_BYTES) {
@@ -293,7 +302,7 @@ export async function readDiscoveredSkillBundle(
293302
}
294303

295304
export function parseSkillBundlesFromZipEntries(
296-
entries: Array<{ entryName: string; getData: () => Buffer }>,
305+
entries: { entryName: string; getData: () => Buffer }[],
297306
): ParsedSkillBundle[] {
298307
const filesBySkill = new Map<string, AgentSkillFileMap>();
299308

@@ -361,9 +370,10 @@ function slugifyFromSkillMd(files: AgentSkillFileMap): string {
361370
.slice(0, 128);
362371
}
363372

364-
export function mergeSkillFilesForResponse(
365-
record: { content: string; files?: AgentSkillFileMap | null },
366-
): AgentSkillFileMap {
373+
export function mergeSkillFilesForResponse(record: {
374+
content: string;
375+
files?: AgentSkillFileMap | null;
376+
}): AgentSkillFileMap {
367377
if (isRecord(record.files) && Object.keys(record.files).length > 0) {
368378
return record.files;
369379
}

backend/src/agent-skills/agent-skills.repository.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,7 @@ import { and, eq, inArray } from 'drizzle-orm';
44

55
import { getPostgresErrorCode, PG_ERROR } from '../common/postgres-error';
66
import { DRIZZLE_TOKEN } from '../database/database.module';
7-
import {
8-
agentSkills,
9-
type AgentSkillRecord,
10-
type NewAgentSkillRecord,
11-
} from '../database/schema';
7+
import { agentSkills, type AgentSkillRecord, type NewAgentSkillRecord } from '../database/schema';
128

139
import type { AgentSkillFileMap } from '../database/schema';
1410

0 commit comments

Comments
 (0)