Before Release
Before Release
Security scanning completed (SAST/DAST)
Penetration testing completed (if required)
Security documentation updated
Incident response plan reviewed
Monitoring and alerting configured
Security training completed by team """
with open(self.project_root / 'SECURITY_CHECKLIST.md', 'w') as f: f.write(checklist)
class CICDSecurityPipeline: """Security integration for CI/CD pipelines"""
def __init__(self, platform: str):
self.platform = platform
self.config = self._get_platform_config()
def _get_platform_config(self) -> Dict:
"""Get platform-specific configuration"""
configs = {
'github': self._github_actions_config,
'gitlab': self._gitlab_ci_config,
'jenkins': self._jenkins_config,
'azure': self._azure_pipelines_config
}
return configs.get(self.platform, self._github_actions_config)()
def _github_actions_config(self) -> Dict:
"""GitHub Actions security workflow"""
return {
'name': 'Security Scan',
'on': {
'push': {'branches': ['main', 'develop']},
'pull_request': {'branches': ['main']},
'schedule': [{'cron': '0 0 * * 1'}] # Weekly scan
},
'jobs': {
'security-scan': {
'runs-on': 'ubuntu-latest',
'steps': [
{
'name': 'Checkout code',
'uses': 'actions/checkout@v3'
},
{
'name': 'Set up Python',
'uses': 'actions/setup-python@v4',
'with': {'python-version': '3.10'}
},
{
'name': 'Install dependencies',
'run': 'pip install -r requirements.txt\npip install bandit safety semgrep'
},
{
'name': 'Run Bandit',
'run': 'bandit -r . -f json -o bandit-report.json || true'
},
{
'name': 'Run Safety',
'run': 'safety check --json --output safety-report.json || true'
},
{
'name': 'Run Semgrep',
'uses': 'returntocorp/semgrep-action@v1',
'with': {
'config': 'p/security-audit p/python p/owasp-top-ten'
}
},
{
'name': 'Run Security Tests',
'run': 'pytest tests/security/ --junitxml=security-tests.xml'
},
{
'name': 'Upload results',
'uses': 'actions/upload-artifact@v3',
'if': 'always()',
'with': {
'name': 'security-reports',
'path': '|bandit-report.json\nsafety-report.json\nsecurity-tests.xml'
}
},
{
'name': 'Comment PR',
'uses': 'actions/github-script@v6',
'if': "github.event_name == 'pull_request'",
'with': {
'script': self._generate_pr_comment_script()
}
}
]
},
'dependency-check': {
'runs-on': 'ubuntu-latest',
'steps': [
{
'name': 'Checkout code',
'uses': 'actions/checkout@v3'
},
{
'name': 'Run OWASP Dependency Check',
'uses': 'dependency-check/Dependency-Check_Action@main',
'with': {
'project': 'MyProject',
'path': '.',
'format': 'ALL'
}
},
{
'name': 'Upload results',
'uses': 'actions/upload-artifact@v3',
'with': {
'name': 'dependency-check-report',
'path': 'reports'
}
}
]
},
'container-scan': {
'runs-on': 'ubuntu-latest',
'if': "contains(github.event.head_commit.message, '[docker]')",
'steps': [
{
'name': 'Run Trivy scanner',
'uses': 'aquasecurity/trivy-action@master',
'with': {
'image-ref': '${{ github.repository }}:latest',
'format': 'sarif',
'output': 'trivy-results.sarif'
}
},
{
'name': 'Upload Trivy scan results',
'uses': 'github/codeql-action/upload-sarif@v2',
'with': {'sarif_file': 'trivy-results.sarif'}
}
]
}
}
}
def _generate_pr_comment_script(self) -> str:
"""Generate script for PR security comments"""
return """
const fs = require('fs');
// Read security reports let comment = '## Security Scan Results\n\n';
try { const banditReport = JSON.parse(fs.readFileSync('bandit-report.json')); const issues = banditReport.results.length; comment += ### Bandit (SAST)\\n
; comment += Found ${issues} potential security issues\\n\\n
;
if (issues > 0) {
comment += '<details><summary>View issues</summary>\\n\\n';
banditReport.results.forEach(issue => {
comment += `- **${issue.issue_severity}**: ${issue.issue_text} (${issue.filename}:${issue.line_number})\\n`;
});
comment += '</details>\\n\\n';
}
} catch (e) { comment += '### Bandit (SAST)\n'; comment += 'No issues found ✅\n\n'; }
try { const safetyReport = JSON.parse(fs.readFileSync('safety-report.json')); const vulns = safetyReport.vulnerabilities?.length || 0; comment += ### Safety (Dependency Check)\\n
; comment += Found ${vulns} vulnerable dependencies\\n\\n
;
if (vulns > 0) {
comment += '<details><summary>View vulnerabilities</summary>\\n\\n';
safetyReport.vulnerabilities.forEach(vuln => {
comment += `- **${vuln.package_name}** ${vuln.analyzed_version}: ${vuln.vulnerability}\\n`;
});
comment += '</details>\\n\\n';
}
} catch (e) { comment += '### Safety (Dependency Check)\n'; comment += 'No vulnerable dependencies found ✅\n\n'; }
// Post comment github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: comment }); """
def generate_pipeline_config(self) -> str:
"""Generate pipeline configuration file"""
if self.platform == 'github':
config_path = '.github/workflows/security.yml'
config_content = yaml.dump(self.config, default_flow_style=False)
elif self.platform == 'gitlab':
config_path = '.gitlab-ci.yml'
config_content = yaml.dump(self._gitlab_ci_config(), default_flow_style=False)
elif self.platform == 'jenkins':
config_path = 'Jenkinsfile.security'
config_content = self._generate_jenkinsfile()
else:
config_path = 'azure-pipelines-security.yml'
config_content = yaml.dump(self._azure_pipelines_config(), default_flow_style=False)
return config_path, config_content
```javascript
// JavaScript - Secure Development Workflow
const fs = require('fs').promises;
const path = require('path');
const { execSync } = require('child_process');
const yaml = require('js-yaml');
class SecureDevEnvironment {
constructor(projectRoot) {
this.projectRoot = projectRoot;
this.config = this.loadSecurityConfig();
}
async loadSecurityConfig() {
const configPath = path.join(this.projectRoot, '.security.yml');
try {
const content = await fs.readFile(configPath, 'utf8');
return yaml.load(content);
} catch (error) {
return this.getDefaultConfig();
}
}
getDefaultConfig() {
return {
preCommitHooks: [
'eslint',
'prettier',
'security-audit',
'dependency-check',
'secret-scan'
],
securityTools: {
eslint: {
plugins: ['security', 'no-secrets'],
extends: ['plugin:security/recommended']
},
audit: {
level: 'moderate',
excludeDevDependencies: false
}
},
ide: {
vscode: {
extensions: [
'dbaeumer.vscode-eslint',
'ms-vscode.vscode-typescript-tslint-plugin',
'snyk-security.snyk-vulnerability-scanner'
]
}
}
};
}
async setupPreCommitHooks() {
// Husky configuration
const huskyConfig = {
hooks: {
'pre-commit': 'lint-staged',
'pre-push': 'npm run security:check',
'commit-msg': 'commitlint -E HUSKY_GIT_PARAMS'
}
};
// Lint-staged configuration
const lintStagedConfig = {
'*.{js,jsx,ts,tsx}': [
'eslint --fix',
'prettier --write',
'npm run security:scan'
],
'*.{json,md,yml,yaml}': [
'prettier --write'
],
'package.json': [
'npm audit',
'npm run check:dependencies'
]
};
// Write configurations
const packageJson = JSON.parse(
await fs.readFile(path.join(this.projectRoot, 'package.json'), 'utf8')
);
packageJson.husky = huskyConfig;
packageJson['lint-staged'] = lintStagedConfig;
// Add security scripts
packageJson.scripts = {
...packageJson.scripts,
'security:check': 'npm run security:audit && npm run security:scan',
'security:audit': 'npm audit --production',
'security:scan': 'detect-secrets scan && eslint . --ext .js,.jsx,.ts,.tsx',
'security:test': 'jest --testPathPattern=security',
'check:dependencies': 'npm-check-updates -u --dep prod,dev',
'prepare': 'husky install'
};
await fs.writeFile(
path.join(this.projectRoot, 'package.json'),
JSON.stringify(packageJson, null, 2)
);
// Install Husky
execSync('npm install --save-dev husky lint-staged', {
cwd: this.projectRoot
});
execSync('npm run prepare', {
cwd: this.projectRoot
});
console.log('✓ Pre-commit hooks configured');
}
async configureESLintSecurity() {
const eslintConfig = {
env: {
browser: true,
es2021: true,
node: true
},
extends: [
'eslint:recommended',
'plugin:security/recommended',
'plugin:no-secrets/recommended'
],
plugins: [
'security',
'no-secrets',
'sonarjs',
'promise'
],
rules: {
// Security rules
'security/detect-eval-with-expression': 'error',
'security/detect-non-literal-regexp': 'warn',
'security/detect-non-literal-require': 'warn',
'security/detect-object-injection': 'warn',
'security/detect-possible-timing-attacks': 'warn',
'security/detect-pseudoRandomBytes': 'error',
'security/detect-unsafe-regex': 'error',
'security/detect-buffer-noassert': 'error',
'security/detect-child-process': 'warn',
'security/detect-disable-mustache-escape': 'error',
'security/detect-no-csrf-before-method-override': 'error',
'security/detect-non-literal-fs-filename': 'warn',
// No secrets
'no-secrets/no-secrets': ['error', {
tolerance: 4.5
}],
// Code quality
'sonarjs/cognitive-complexity': ['error', 15],
'sonarjs/no-duplicate-string': 'error',
'sonarjs/no-identical-functions': 'error',
// Promise handling
'promise/always-return': 'error',
'promise/no-return-wrap': 'error',
'promise/param-names': 'error',
'promise/catch-or-return': 'error',
'promise/no-native': 'off',
'promise/no-nesting': 'warn',
'promise/no-promise-in-callback': 'warn',
'promise/no-callback-in-promise': 'warn',
'promise/avoid-new': 'off',
'promise/no-new-statics': 'error',
'promise/no-return-in-finally': 'warn',
'promise/valid-params': 'warn'
},
overrides: [
{
files: ['*.test.js', '*.spec.js'],
env: {
jest: true
},
rules: {
'security/detect-object-injection': 'off',
'security/detect-non-literal-require': 'off'
}
}
]
};
await fs.writeFile(
path.join(this.projectRoot, '.eslintrc.json'),
JSON.stringify(eslintConfig, null, 2)
);
// Create .eslintignore
const eslintIgnore = `
node_modules/
dist/
build/
coverage/
*.min.js
*.bundle.js
`;
await fs.writeFile(
path.join(this.projectRoot, '.eslintignore'),
eslintIgnore.trim()
);
console.log('✓ ESLint security configuration created');
}
async setupSecretScanning() {
// detect-secrets configuration
const detectSecretsConfig = {
version: '1.4.0',
filters_used: [
{
path: 'detect_secrets.filters.common.is_ignored_due_to_verification_policies',
min_level: 2
},
{
path: 'detect_secrets.filters.heuristic.is_indirect_reference'
},
{
path: 'detect_secrets.filters.heuristic.is_likely_id_string'
},
{
path: 'detect_secrets.filters.heuristic.is_potential_uuid'
}
],
plugins_used: [
{
name: 'ArtifactoryDetector'
},
{
name: 'AWSKeyDetector'
},
{
name: 'AzureStorageKeyDetector'
},
{
name: 'Base64HighEntropyString',
limit: 4.5
},
{
name: 'BasicAuthDetector'
},
{
name: 'CloudantDetector'
},
{
name: 'GitHubTokenDetector'
},
{
name: 'HexHighEntropyString',
limit: 3.0
},
{
name: 'JwtTokenDetector'
},
{
name: 'KeywordDetector',
keyword_exclude: ''
},
{
name: 'MailchimpDetector'
},
{
name: 'NpmDetector'
},
{
name: 'PrivateKeyDetector'
},
{
name: 'SendGridDetector'
},
{
name: 'SlackDetector'
},
{
name: 'SoftlayerDetector'
},
{
name: 'SquareOAuthDetector'
},
{
name: 'StripeDetector'
},
{
name: 'TwilioKeyDetector'
}
],
exclude: {
files: [
'.*\\.lock$',
'.*\\.png$',
'.*\\.jpg$',
'.*\\.jpeg$',
'.*\\.gif$',
'.*\\.svg$',
'.*\\.min\\.js$',
'node_modules/.*'
],
lines: [
'.*integrity.*',
'.*sha512.*'
]
}
};
await fs.writeFile(
path.join(this.projectRoot, '.secrets.baseline'),
JSON.stringify(detectSecretsConfig, null, 2)
);
// Git secrets patterns
const gitSecretsPatterns = `
# AWS Keys
(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}
# AWS Secret Key
aws(.{0,20})?(?-i)['"][0-9a-zA-Z\/+]{40}['"]
# GitHub Token
gh[ps]_[0-9a-zA-Z]{36}
# Generic API Key
api[_-]?key[_-]?['"]?[:=]\\s*['"]?[0-9a-zA-Z]{32,}['"]?
# Generic Secret
secret[_-]?['"]?[:=]\\s*['"]?[0-9a-zA-Z]{32,}['"]?
# Private Key
-----BEGIN (RSA|DSA|EC|PGP) PRIVATE KEY-----
# Google API Key
AIza[0-9A-Za-z\\-_]{35}
# Slack Token
xox[baprs]-[0-9]{12}-[0-9]{12}-[0-9a-zA-Z]{24}
# JWT
eyJ[A-Za-z0-9_-]*\\.[A-Za-z0-9_-]*\\.[A-Za-z0-9_-]*
`;
await fs.writeFile(
path.join(this.projectRoot, '.gitsecrets'),
gitSecretsPatterns.trim()
);
console.log('✓ Secret scanning configured');
}
async createSecurityPolicies() {
// Security policy
const securityPolicy = `# Security Policy