feat: add git awareness and optional description field to config

This commit is contained in:
ezl-keygraph
2026-03-22 21:25:13 +05:30
parent c689ef0de0
commit 8f795f6dca
10 changed files with 48 additions and 5 deletions
+18 -2
View File
@@ -294,9 +294,9 @@ const validateConfig = (config: Config): void => {
performSecurityValidation(config);
if (!config.rules && !config.authentication) {
if (!config.rules && !config.authentication && !config.description) {
console.warn(
'⚠️ Configuration file contains no rules or authentication. The pentest will run without any scoping restrictions or login capabilities.',
'⚠️ Configuration file contains no rules, authentication, or description. The pentest will run without any scoping restrictions or login capabilities.',
);
} else if (config.rules && !config.rules.avoid && !config.rules.focus) {
console.warn('⚠️ Configuration file contains no rules. The pentest will run without any scoping restrictions.');
@@ -370,6 +370,20 @@ const performSecurityValidation = (config: Config): void => {
checkForDuplicates(config.rules.focus || [], 'focus');
checkForConflicts(config.rules.avoid, config.rules.focus);
}
if (config.description) {
for (const pattern of DANGEROUS_PATTERNS) {
if (pattern.test(config.description)) {
throw new PentestError(
`description contains potentially dangerous pattern: ${pattern.source}`,
'config',
false,
{ field: 'description', pattern: pattern.source },
ErrorCode.CONFIG_VALIDATION_FAILED,
);
}
}
}
};
const validateRulesSecurity = (rules: Rule[] | undefined, ruleType: string): void => {
@@ -527,11 +541,13 @@ export const distributeConfig = (config: Config | null): DistributedConfig => {
const avoid = config?.rules?.avoid || [];
const focus = config?.rules?.focus || [];
const authentication = config?.authentication || null;
const description = config?.description?.trim() || '';
return {
avoid: avoid.map(sanitizeRule),
focus: focus.map(sanitizeRule),
authentication: authentication ? sanitizeAuthentication(authentication) : null,
description,
};
};
+2 -1
View File
@@ -167,7 +167,8 @@ async function interpolateVariables(
.replace(/{{WEB_URL}}/g, variables.webUrl)
.replace(/{{REPO_PATH}}/g, variables.repoPath)
.replace(/{{PLAYWRIGHT_SESSION}}/g, variables.PLAYWRIGHT_SESSION || 'agent1')
.replace(/{{AUTH_CONTEXT}}/g, buildAuthContext(config));
.replace(/{{AUTH_CONTEXT}}/g, buildAuthContext(config))
.replace(/{{DESCRIPTION}}/g, config?.description ? `Description: ${config.description}` : '');
if (config) {
// Handle rules section - if both are empty, use cleaner messaging
+2
View File
@@ -46,6 +46,7 @@ export interface Config {
rules?: Rules;
authentication?: Authentication;
pipeline?: PipelineConfig;
description?: string;
}
export type RetryPreset = 'default' | 'subscription';
@@ -59,4 +60,5 @@ export interface DistributedConfig {
avoid: Rule[];
focus: Rule[];
authentication: Authentication | null;
description: string;
}