Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
4cae1dd
Update README.md Delivery 1: Discovery & Reverse Engineering
gitcombo Feb 10, 2026
123406b
Update README.md
gitcombo Feb 10, 2026
0b9d15d
Update README.md - Why we choose this project
gitcombo Feb 11, 2026
aaf81e7
Add comprehensive rehabilitation plan for vulnerable-node project
Esaban17 Feb 11, 2026
e7ade58
Fix #001: Eliminate SQL Injection vulnerability in authentication
Esaban17 Feb 11, 2026
46f8b54
Fix #002: Database initialization failure (Login blocker)
Esaban17 Feb 11, 2026
63cae4a
Rehabilitate vulnerable-node: full security hardening and modernization
Esaban17 Feb 11, 2026
a2ca987
Add fix documentation for all rehabilitation changes (003-012)
Esaban17 Feb 11, 2026
88c2a30
Add fix docs for redirect loop and password column, update gitignore
Esaban17 Feb 22, 2026
b37f470
Merge branch 'master' into rehabilitation-plan
Esaban17 Feb 23, 2026
667d65c
Merge pull request #1 from gitcombo/rehabilitation-plan
Esaban17 Feb 23, 2026
51c6436
Fix CSRF token error: use explicit COOKIE_SECURE env var for session …
Esaban17 Feb 23, 2026
9957b21
Add CI quality pipeline with GitHub Actions and SonarCloud
Esaban17 Feb 24, 2026
8d3f5f7
Add DORA metrics dashboard with GitHub API integration and Grafana su…
Esaban17 Feb 24, 2026
9aebb78
Merge pull request #2 from gitcombo/feature/ci-quality-pipeline
gitcombo Feb 24, 2026
7fcf942
Lower coverage thresholds to match current test coverage
Esaban17 Feb 24, 2026
8af809c
Merge pull request #3 from gitcombo/feature/ci-quality-pipeline
gitcombo Feb 24, 2026
dd75d38
Update SonarCloud organization and project key to gitcombo
Esaban17 Feb 24, 2026
a3725d2
Merge pull request #4 from gitcombo/feature/ci-quality-pipeline
gitcombo Feb 24, 2026
32bc1ed
Add refactoring roadmap document to design folder
Esaban17 Feb 25, 2026
0cb9084
Merge pull request #5 from gitcombo/design/refactoring-roadmap
Esaban17 Feb 25, 2026
4e2ebbe
Merge branch 'master' into feature/dora-metrics-dashboard
Esaban17 Feb 25, 2026
4fc630c
Merge pull request #6 from gitcombo/feature/dora-metrics-dashboard
Esaban17 Feb 25, 2026
6e4dc0d
feat(security): add BEFORE vulnerability evidence reports
Esaban17 Mar 12, 2026
de80b60
fix(security): remediate critical and high dependency vulnerabilities
Esaban17 Mar 12, 2026
784b201
feat(security): add CycloneDX SBOM generated with Syft
Esaban17 Mar 12, 2026
0a9bb8f
feat(security): add Husky v9 pre-commit hook with secretlint secret d…
Esaban17 Mar 12, 2026
dac870d
feat(ci): add sbom-and-scan job with Syft, Grype and Trivy
Esaban17 Mar 12, 2026
23eacc1
docs(security): add VULNERABILITY_REPORT.md with before/after evidence
Esaban17 Mar 12, 2026
da0961f
docs(adr): add ADR-001 Clean Architecture consolidation proposal
Esaban17 Mar 31, 2026
42f19ab
fix(ci): replace non-existent anchore/syft-action with anchore/sbom-a…
Esaban17 Mar 31, 2026
29dd41c
fix(security): skip CSRF validation for unauthenticated requests
Esaban17 Mar 31, 2026
ab272b7
fix(security): remediate HIGH vulnerabilities in Grype scan
Esaban17 Mar 31, 2026
60ae06c
Merge pull request #8 from gitcombo/feature/devsecops-hardening
Esaban17 Mar 31, 2026
a3235f6
fix(ci): scope npm audit gate to production dependencies only
Esaban17 Mar 31, 2026
68bc702
fix(deps): regenerate lock file to apply picomatch@4.0.2 override
Esaban17 Mar 31, 2026
ca723d4
Merge pull request #7 from gitcombo/feature/adr-001-clean-architecture
Esaban17 Mar 31, 2026
15d9b28
feat(finops): optimize ReDoS regex and GitHubMetricsService N+1 pattern
Esaban17 Mar 31, 2026
1afcd77
Merge pull request #9 from gitcombo/feature/finops-optimization
Esaban17 Mar 31, 2026
48d6af7
docs(adr): document 9 undocumented architectural decisions (ADR-002 t…
Esaban17 Apr 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Database
DATABASE_URL=postgres://postgres:postgres@127.0.0.1/vulnerablenode

# Session
SESSION_SECRET=change-me-to-a-random-string-at-least-32-chars

# Application
NODE_ENV=development
PORT=3000
LOG_LEVEL=info

# Docker override
STAGE=LOCAL
134 changes: 134 additions & 0 deletions .github/workflows/ci-quality.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
name: CI Quality Pipeline

on:
pull_request:
branches: [master]
push:
branches: [master]

jobs:
unit-tests:
name: Unit Tests & Coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 22
cache: 'npm'
- run: npm ci
- name: Run unit tests with coverage
run: npm run test:ci
env:
NODE_OPTIONS: --experimental-vm-modules
- uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage/lcov.info
retention-days: 1

e2e-tests:
name: E2E Tests
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: vulnerablenode
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U postgres"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: 'npm'
- run: npm ci
- name: Run E2E tests
run: npm run test:e2e
env:
NODE_OPTIONS: --experimental-vm-modules
DATABASE_URL: postgres://postgres:postgres@localhost:5432/vulnerablenode
SESSION_SECRET: ci-test-secret-key

sbom-and-scan:
name: SBOM Generation & Vulnerability Scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 22
cache: 'npm'
- run: npm ci

# ── SBOM generation ──────────────────────────────────────────────────────
- name: Generate SBOM with Syft (CycloneDX JSON)
uses: anchore/sbom-action@v0
with:
path: "."
format: "cyclonedx-json"
output-file: "sbom-ci.json"
artifact-name: "sbom"

# ── Vulnerability scan: Grype (Anchore) ──────────────────────────────────
- name: Scan dependencies with Grype
uses: anchore/scan-action@v6
id: grype-scan
with:
path: "."
fail-build: true
severity-cutoff: high
output-format: table

# ── Vulnerability scan: Trivy (Aqua Security) ───────────────────────────
- name: Scan filesystem with Trivy
uses: aquasecurity/trivy-action@master
with:
scan-type: "fs"
scan-ref: "."
format: "table"
severity: "CRITICAL,HIGH"
exit-code: "1"
ignore-unfixed: true

# ── npm audit gate ────────────────────────────────────────────────────────
- name: npm audit (HIGH/CRITICAL gate — production deps only)
run: npm run audit:check

# ── Upload evidence artifacts ─────────────────────────────────────────────
- name: Upload vulnerability reports
if: always()
uses: actions/upload-artifact@v4
with:
name: security-reports
path: reports/vulnerability/
retention-days: 30

sonarcloud:
name: SonarCloud Analysis
runs-on: ubuntu-latest
needs: [unit-tests]
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/download-artifact@v4.3.0
with:
name: coverage-report
path: coverage/
- name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@v3
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36 changes: 36 additions & 0 deletions .github/workflows/deploy-tracker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Deploy Tracker

on:
push:
branches: [master]

jobs:
track-deployment:
runs-on: ubuntu-latest
steps:
- name: Create GitHub Deployment Record
uses: actions/github-script@v7
with:
script: |
// Create a deployment record
const deployment = await github.rest.repos.createDeployment({
owner: context.repo.owner,
repo: context.repo.repo,
ref: context.sha,
environment: 'production',
auto_merge: false,
required_contexts: [],
description: `Deployment from commit ${context.sha.substring(0, 7)}`
});

// Mark it as successful
await github.rest.repos.createDeploymentStatus({
owner: context.repo.owner,
repo: context.repo.repo,
deployment_id: deployment.data.id,
state: 'success',
description: 'Deployment completed successfully',
environment: 'production'
});

console.log(`Created deployment #${deployment.data.id} for ${context.sha.substring(0, 7)}`);
100 changes: 29 additions & 71 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,85 +1,43 @@
# Created by .ignore support plugin (hsz.mobi)
### Node template
# Dependencies
node_modules/

# Environment
.env

# Logs
logs
logs/
*.log
npm-debug.log*
app-custom.log
access.log

# Runtime data
pids
*.pid
*.seed
# Test coverage
coverage/

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Build output
dist/

# Coverage directory used by tools like istanbul
coverage
# OS files
.DS_Store

# nyc test coverage
.nyc_output
# IDE
.idea/
*.iws
/out/
.idea_modules/

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
# Runtime
pids
*.pid
*.seed
.nyc_output
.grunt

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules
lib-cov
jspm_packages

# Optional npm cache directory
.npm

# Optional REPL history
.node_repl_history
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839

# User-specific stuff:
.idea/workspace.xml
.idea/tasks.xml
.idea/dictionaries
.idea/vcs.xml
.idea/jsLibraryMappings.xml

# Sensitive or high-churn files:
.idea/dataSources.ids
.idea/dataSources.xml
.idea/dataSources.local.xml
.idea/sqlDataSources.xml
.idea/dynamic.xml
.idea/uiDesigner.xml

# Gradle:
.idea/gradle.xml
.idea/libraries

# Mongo Explorer plugin:
.idea/mongoSettings.xml

## File-based project format:
*.iws

## Plugin-specific files:

# IntelliJ
/out/

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties

# Claude / MCP config
.claude/
.playwright-mcp/
25 changes: 25 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
echo "Scanning staged files for secrets..."

# Get list of staged files (exclude deleted files)
STAGED=$(git diff --cached --name-only --diff-filter=d)

if [ -z "$STAGED" ]; then
echo "No staged files to check."
exit 0
fi

# Run secretlint on each staged file
echo "$STAGED" | xargs npx secretlint --no-color

EXIT_CODE=$?

if [ $EXIT_CODE -ne 0 ]; then
echo ""
echo "ERROR: Potential secrets detected in staged files."
echo " Remove secrets before committing."
echo " Use 'git commit --no-verify' to bypass (not recommended)."
echo ""
exit 1
fi

echo "No secrets detected. Proceeding with commit."
9 changes: 9 additions & 0 deletions .secretlintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
node_modules/
coverage/
package-lock.json
sbom.json
reports/
public/
logs/
*.min.js
.github/
7 changes: 7 additions & 0 deletions .secretlintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"rules": [
{
"id": "@secretlint/secretlint-rule-preset-recommend"
}
]
}
Loading