Contributing to WebSecScan¶
Guidelines for contributing code, documentation, and tests to WebSecScan.
Code Standards¶
TypeScript Strict Mode¶
All code must be strict TypeScript:
// ✅ Good
function analyzeCode(code: string): Vulnerability[] {
return [];
}
// ❌ Bad
function analyzeCode(code: any): any {
return [];
}
Never use any without documented justification.
Naming Conventions¶
- Files: kebab-case (
url-normalizer.ts) - Classes: PascalCase (
URLNormalizer) - Functions: camelCase (
normalizeURL()) - Constants: UPPER_SNAKE_CASE (
MAX_DEPTH = 2)
Comments & Documentation¶
Add JSDoc for public functions:
/**
* Analyzes JavaScript code for security vulnerabilities.
* @param code - Source code to analyze
* @param filename - Original filename for context
* @returns Array of detected vulnerabilities
*/
export async function analyzeJavaScript(
code: string,
filename: string
): Promise<Vulnerability[]> {
// implementation
}
Testing Requirements¶
Unit Tests Required¶
For every new rule or function:
Test Quality¶
import { describe, it } from 'node:test';
import assert from 'node:assert';
describe('MyNewFeature', () => {
it('should detect the vulnerability', () => {
const result = myNewCheck('vulnerable code');
assert.ok(result.length > 0);
});
it('should not flag safe code', () => {
const result = myNewCheck('safe code');
assert.equal(result.length, 0);
});
});
Requirements: - Edge cases covered - Both positive and negative tests - Clear assertions - Deterministic (no random data)
Mandatory Project Rules¶
From .github/copilot-instructions.md:
- ✅ No placeholder logic — Implement real rule checks, not fake findings
- ✅ Validate all inputs — Server-side validation always
- ✅ TypeScript strict mode — Avoid
any - ✅ Server-only scanning — Never run scanners on client
- ✅ OWASP 2025 taxonomy — Use current classification
- ✅ Separate modules — Small, focused files
- ✅ Clear comments — Explain why each finding is risky
- ✅ No hardcoded secrets — Never commit credentials
OWASP 2025 Examples¶
// ✅ Correct
vulnerability.owaspId = 'A02:2025'; // Security Misconfiguration
// ❌ Wrong
vulnerability.owaspId = 'A05:2021'; // Old taxonomy
vulnerability.owaspId = 'A05:2025'; // Wrong number (moved to A02!)
See OWASP 2025 Mapping for complete guide.
Pull Request Checklist¶
Before submitting:
Code Quality¶
- [ ]
npx tsc --noEmitpasses (no type errors) - [ ]
npm run lintpasses (ESLint) - [ ] No hardcoded secrets or credentials
- [ ] No console.log() — Use logger instead
- [ ] No commented-out code
Testing¶
- [ ]
npm testpasses - [ ] New tests written for new code
- [ ] Edge cases tested
- [ ] At least 80% coverage for new code
Documentation¶
- [ ] Function JSDoc comments added
- [ ] Complex logic explained
- [ ] README updated if needed
- [ ] CHANGELOG updated
Ethical & Safety¶
- [ ] No exploitative code
- [ ] No credential harvesting
- [ ] No unethical defaults
- [ ] Includes safety constraints
PR Process¶
-
Fork the repository
-
Create a feature branch
-
Make your changes
- Follow code standards
- Write tests
-
Add documentation
-
Test locally
-
Commit with clear messages
-
Push and create Pull Request
-
Address review comments
- Respond to feedback
- Make requested changes
- Update tests if needed
Development Workflow¶
1. Set Up Environment¶
2. Make Changes¶
// Add new vulnerability check in src/security/rules/
export async function checkNewVulnerability(code: string): Vulnerability[] {
// Implementation
}
3. Write Tests¶
// Add test in __tests__/
it('should detect new vulnerability', () => {
const result = checkNewVulnerability('vulnerable code');
assert.ok(result.length > 0);
});
4. Test Locally¶
5. Commit & Push¶
git add src/ __tests__/
git commit -m "feat: add new vulnerability check"
git push origin feat/my-feature
Adding New Detection Rules¶
Step 1: Create Rule Module¶
File: src/security/rules/my-check.ts
import { Vulnerability } from '@prisma/client';
export async function checkMyVulnerability(
code: string,
filename: string
): Promise<Vulnerability[]> {
const vulnerabilities: Vulnerability[] = [];
// Your detection logic here
if (code.includes('dangerous_pattern')) {
vulnerabilities.push({
id: 'WSS-XXX-001',
owaspId: 'A02:2025', // OWASP 2025 category
severity: 'HIGH',
confidence: 'HIGH',
title: 'Dangerous Pattern Detected',
description: 'Explain why this is risky...',
evidence: 'Code snippet...',
remediation: 'How to fix it...',
location: `${filename}:${lineNumber}`
});
}
return vulnerabilities;
}
Step 2: Write Tests¶
File: __tests__/my-check.test.ts
describe('My Check', () => {
it('should detect vulnerability', async () => {
const result = await checkMyVulnerability('bad code');
assert.ok(result.length > 0);
});
it('should not flag safe code', async () => {
const result = await checkMyVulnerability('safe code');
assert.equal(result.length, 0);
});
});
Step 3: Register Rule¶
Update src/security/rules/index.ts:
import { checkMyVulnerability } from './my-check';
export const SECURITY_RULES = [
// ... existing rules
checkMyVulnerability
];
Step 4: Test & Document¶
Common Mistakes to Avoid¶
❌ Don't: Mock core scanning logic ✅ Do: Test real vulnerability detection
❌ Don't: Use any types ✅ Do: Use explicit TypeScript types
❌ Don't: Hardcode secrets or credentials ✅ Do: Use environment variables
❌ Don't: Skip tests for new code ✅ Do: Write comprehensive tests
❌ Don't: Mix OWASP 2021/2025 ✅ Do: Use OWASP 2025 exclusively
Code Review¶
Your PR will be reviewed on:
- Code Quality — Follows standards, no
any, clear logic - Testing — Comprehensive tests, all passing
- Documentation — JSDoc, comments, README updated
- Safety — No exploitative code, ethical defaults
- Correctness — OWASP 2025, no false logic
Getting Help¶
- Questions? Open a GitHub Discussion
- Stuck? Ask in the PR comments
- Want to discuss? Start an issue for design feedback
Thank you for contributing! 🎉