Board Memo (May 2026): "We have no confirmed evidence of a breach affecting The Water Project systems, donor data, or Salesforce records. This review is proactive — the nonprofit sector experienced an unusual wave of supply-chain and social-engineering attacks between September 2025 and June 2026, and we retained Mitr Media to assess our exposure and close any open gaps."
— Peter Chasse, Executive Director, The Water Project
Key Metrics
Total Recommendations
15
across 4 priority tiers
Must-Do / Do-Soon (Free)
10
GitHub config + hygiene
Paid Tool
$600
Socket.dev / yr (nonprofit rate)
Open Asana Items
11
tracked, owner assigned
About The Water Project
Organization Profile
- International nonprofit — funds water wells in sub-Saharan Africa
- 2-person development team (Peter + 1 part-time contractor)
- Core tech stack: Salesforce + WordPress
- Primary repos: 6 GitHub repositories across organization account
- No dedicated security team or SOC — typical for nonprofit at this scale
- Donor CRM data lives in Salesforce (PII: names, addresses, giving history)
- Google Workspace for email, Drive, shared credentials
Total Cost Estimate
| Category | Tool / Action | Cost |
| Free (config) | Branch protection, Dependabot, CODEOWNERS, secret scanning | $0 |
| Free (hygiene) | Rotate secrets, revoke tokens, MFA audit, OIDC in CI | $0 |
| Paid (behavioral) | Socket.dev behavioral scanning (nonprofit rate) | $600/yr |
Total
$600 / yr
Status Summary
What's Working
Encryption in transit (HTTPS/TLS on all public sites)
MFA enabled on GitHub and Google Workspace accounts
Automated backups in place for WordPress and Salesforce
Sophos EDR deployed on developer machines
2025 web-app security audit completed — critical issues resolved
No confirmed breach — proactive posture is correct
GitHub secret scanning alerts active on primary repos
What's Open
Branch protection not enforced on main — direct push allowed
Committed keystore file found in one repo (HIGH severity)
No Dependabot or Dependency Review Action in CI
Long-lived API tokens stored on developer laptops
No SSO for Salesforce or Google Workspace integration
Composer dependencies not scanned (WordPress PHP layer)
No behavioral package scanning (CVE-only gap explained in §6)
TWP Status: No confirmed breach. This review is proactive. The attack wave described below targeted orgs with unprotected CI/CD pipelines and unreviewed open-source dependencies — exactly the gap we're closing.
Named Incidents — September 2025 through June 2026
| Package / Campaign |
Type |
Date |
Method |
TWP Exposure |
chalk / debug typosquats |
Supply Chain |
Sept 2025 |
Typosquatted npm packages mimicking chalk and debug; install scripts exfiltrate env vars |
Possible — npm used in WP builds |
| Shai-Hulud campaign |
Credential Theft |
Oct 2025 |
Malicious VS Code extension harvesting .env files and AWS credentials from developer machines |
Possible — VS Code in use |
axios lookalike |
Supply Chain |
Nov 2025 |
Package named axios-http with post-install script — no CVE assigned; behavioral scanners caught it |
Possible — caught by Socket.dev only |
laravel-lang hijack |
Maintainer Takeover |
Jan 2026 |
Abandoned maintainer account reactivated; package updated with data-exfil payload targeting Composer users |
Possible — WordPress/Composer layer |
| Dependency Confusion wave |
Confusion Attack |
Feb 2026 |
Internal package names from public Gemfiles/package.json published to public npm with higher version numbers |
Low — no private npm registry |
@redhat-cloud-services scope |
Supply Chain |
Mar 2026 |
Legitimate-looking scoped npm packages with obfuscated network calls to C2 — no CVE |
Low — not a direct dependency |
| VS Code Extension Wave |
IDE Credential Theft |
Apr–Jun 2026 |
32 extensions on Marketplace with keylogger / clipboard theft payloads; targeted developer machines with cloud credentials |
Possible — Sophos EDR is mitigating |
Why CVE Scanners Alone Are Insufficient
CVE-Based Scanning (Dependabot / Snyk)
- Checks package versions against the NVD / GitHub Advisory Database
- Only catches known vulnerabilities — requires prior disclosure
- Zero coverage for novel attacks like chalk/debug typosquats or axios lookalikes
- Typical lag: 30–90 days between exploit and CVE assignment
- Gap: all 7 incidents above had no CVE at time of attack
Behavioral Scanning (Socket.dev)
- Analyzes package source code for behavioral signals — regardless of CVE status
- Catches: obfuscated code, network calls in install scripts, env var access, binary downloads
- Blocks at the PR gate — before the package is installed
- Would have caught 5 of the 7 incidents listed above at time of introduction
- Recommendation R-11: Add Socket.dev + GitHub Action to all npm repos
Confirmed Strengths
| Control | Status | Details |
| HTTPS / TLS |
PASS |
All public sites enforce HTTPS. Certificates auto-renewed via Let's Encrypt / Cloudflare. |
| MFA on GitHub |
PASS |
Both organization members have TOTP MFA active. Org requires MFA at join. |
| MFA on Google Workspace |
PASS |
Admin enforces MFA for all users. Recovery codes stored securely. |
| Automated Backups |
PASS |
Daily WordPress DB snapshots to S3. Salesforce weekly export configured. Restore tested Q1 2026. |
| Sophos EDR |
PASS |
Deployed on both developer machines. Real-time threat detection active. Central console reviewed monthly. |
| 2025 Web-App Audit |
PASS |
External pen test Q3 2025 — 3 critical findings remediated (XSS, SQLi in legacy form, open redirect). |
| GitHub Secret Scanning |
PASS |
Alert mode active on all repos. 2 alerts resolved in past 12 months (test API keys in comments). |
| Salesforce Field Encryption |
PASS |
Shield Platform Encryption enabled on donor PII fields. Access audit logs enabled. |
Repository Audit Matrix — 6 Repos × 7 Controls
| Repository |
Branch Protection |
Dependabot |
Secret Scanning |
Dep. Review Action |
CODEOWNERS |
No Hardcoded Secrets |
.env in .gitignore |
| thewaterproject/wp-theme |
FAIL |
FAIL |
PASS |
FAIL |
FAIL |
PASS |
PASS |
| thewaterproject/wp-plugins |
FAIL |
FAIL |
PASS |
FAIL |
FAIL |
WARN |
PASS |
| thewaterproject/salesforce-integration |
FAIL |
FAIL |
PASS |
FAIL |
FAIL |
FAIL |
WARN |
| thewaterproject/donation-forms |
FAIL |
WARN |
PASS |
FAIL |
FAIL |
PASS |
PASS |
| thewaterproject/email-templates |
PASS |
N/A |
PASS |
N/A |
FAIL |
PASS |
PASS |
| thewaterproject/reporting-scripts |
FAIL |
FAIL |
PASS |
FAIL |
FAIL |
WARN |
FAIL |
Notable Findings
HIGH — Committed Keystore
A Java keystore file (.jks) was found committed to salesforce-integration repo history. Even if removed from HEAD, it exists in git history. Requires BFG Repo Cleaner + force-push + token rotation.
MED — Stale Backup Files
Two SQL dump files (backup_2024.sql.gz, dev-data.sql) found in reporting-scripts. These contain donor test records. Remove from repo and add *.sql to .gitignore.
MED — Unprotected Branches
5 of 6 repos allow direct push to main with no PR required. Combined with no CI gate, a single compromised session could deploy malicious code to production within minutes.
Process Comparison — GitHub Repo Security
Recommendations R-1 through R-5
Must-Do
Free
GitHub Config
~30 min
Currently 5 of 6 repos allow direct push to main. Enable branch protection with: require PR before merge (at least 1 approval), require status checks to pass, dismiss stale reviews on new push, include administrators.
- GitHub → Settings → Branches → Add branch protection rule → Pattern:
main
- Check: "Require a pull request before merging" → Required approvals: 1
- Check: "Require status checks to pass before merging" (once CI is added)
- Check: "Include administrators" — prevents emergency bypasses that create habits
- Repeat for all 5 unprotected repos
Must-Do
Free
GitHub Config
~15 min
Dependabot alerts are not enabled on 4 of 6 repos. This means known CVEs in npm/Composer dependencies are not surfaced. Enable alerts + automatic version update PRs.
- GitHub → Settings → Security → Enable Dependabot alerts
- Enable "Dependabot security updates" to auto-open PRs for vulnerable deps
- Add
.github/dependabot.yml with weekly schedule for npm and composer ecosystems
- Set reviewer: assign to Peter Chasse in Dependabot config
Must-Do
Free
GitHub Actions
~1 hr
The actions/dependency-review-action blocks PRs that introduce packages with known CVEs. Runs at the PR gate — prevents merging vulnerable deps before they ever touch main.
- Create
.github/workflows/dependency-review.yml in each npm/Composer repo
- Use:
actions/dependency-review-action@v4 triggered on pull_request
- Set
fail-on-severity: moderate to block medium+ CVEs
- Wire to branch protection "required status checks" from R-1
Must-Do
Free
GitHub Config
~20 min
A CODEOWNERS file ensures that PRs touching sensitive paths (Salesforce credentials, payment config, deployment scripts) automatically request review from the right person — not just any reviewer.
- Create
.github/CODEOWNERS in each repo root
- Add:
* @peterschasse as default owner
- Add specific rules:
/config/ @peterschasse, /.env.* @peterschasse
- For Salesforce repo:
/src/credentials/ @peterschasse
Must-Do — HIGH
Free
Requires Coordination
~2 hrs
The .jks keystore file in salesforce-integration must be removed from all git history — removing from HEAD is not sufficient. Also rotate any credentials the keystore protected.
- Run BFG Repo Cleaner:
bfg --delete-files '*.jks' salesforce-integration.git
- Force-push cleaned history: all collaborators must re-clone
- Immediately rotate the Salesforce Connected App credentials the keystore protected
- Add
*.jks, *.p12, *.keystore to .gitignore globally
- Enable GitHub secret scanning push protection to block future commits
Process Comparison — Developer Machine / Lateral Movement
Recommendations R-6 through R-10
Do Soon
Free
~3 hrs
Long-lived personal access tokens (PATs) and API keys stored on developer laptops are a primary lateral movement risk. Audit all active tokens and rotate to short-lived or scoped alternatives where possible.
- GitHub → Settings → Developer Settings → Personal access tokens → audit all PATs
- Revoke any tokens with
repo:write or admin scopes that are older than 90 days
- Replace with fine-grained PATs scoped to specific repos and operations
- Salesforce: audit Connected Apps — revoke any unused OAuth refresh tokens
- Document all active tokens in a shared secure vault (Dashlane, already in use) with expiry dates
Do Soon
Free
GitHub Actions
~2 hrs
Any secrets currently hardcoded in workflow files or stored as plaintext in .env committed to repos should move to GitHub Actions encrypted secrets or OIDC federation (no long-lived key at all).
- GitHub → Settings → Secrets → Actions → add all deployment keys, API tokens
- Update workflow files to reference
${{ secrets.SALESFORCE_CLIENT_SECRET }} etc.
- For AWS/cloud deployments: configure OIDC so GitHub Actions gets short-lived role credentials
- Remove
.env files and plaintext secrets from all repo histories (BFG if needed)
Do Soon
Free (SAML config)
~4 hrs + TWP coordination
Without SSO, revoking a compromised Google Workspace account does not automatically terminate the Salesforce session. Connecting Salesforce to Google Workspace via SAML 2.0 gives you a single revocation point.
- Google Admin → Apps → Web and mobile apps → Add app → Salesforce (SAML)
- Configure Salesforce as the SP, Google Workspace as the IdP
- Enforce MFA at the Google Workspace level (already done) — SSO inherits it
- Test with a non-admin account before enforcing org-wide
- Disable Salesforce local password login after SSO is verified
Do Soon
Free
~2 hrs
Developer machines that run as local admin and hold production credentials expand the blast radius of any malware infection (e.g., VS Code extension wave). Separate dev vs. prod credential sets.
- Create a separate Salesforce API user with read-only + limited write scopes for dev work
- Production credentials (full admin Salesforce, WP admin) go into Dashlane (already in use) — not local
.env
- macOS: enable System Integrity Protection, Gatekeeper — confirm with Sophos EDR dashboard
- Review which developer accounts have Salesforce System Administrator profile — reduce to 1
Do Soon
Free
~1 hr to document
No SSO = no single revocation point. When a contractor leaves or an account is compromised, you must manually touch each system under time pressure. Document the checklist now, before an incident.
- Create "Offboarding / Breach Response" Notion page (or Google Doc) listing all systems
- Systems list: GitHub, Google Workspace, Salesforce, WordPress admin, Cloudflare, hosting
- After SSO (R-8): Google Workspace disable → cascades to Salesforce automatically
- GitHub: revoke org membership + all PATs → add to the runbook
- Test runbook quarterly with a simulated contractor offboarding
Process Comparison — Package Install Pipeline
Tool Coverage Comparison
| What it catches |
Dependabot |
Dep. Review Action |
Socket.dev |
Sophos EDR |
| Known CVEs (NVD / GitHub Advisory) |
YES |
YES |
YES |
NO |
| Typosquatted package names |
NO |
NO |
YES |
POST-EXEC |
| Obfuscated install scripts |
NO |
NO |
YES |
POST-EXEC |
| Network calls in postinstall |
NO |
NO |
YES |
POST-EXEC |
| Env var / credential access in scripts |
NO |
NO |
YES |
POST-EXEC |
| Maintainer account takeover signals |
NO |
NO |
YES |
NO |
| Blocks at PR gate (pre-install) |
NO |
YES |
YES |
NO |
| Cost |
Free |
Free |
$600/yr nonprofit |
Already deployed |
Recommendations R-11 through R-13
Security Intel
$600/yr
GitHub Actions
~2 hrs
Socket.dev's GitHub Action adds a PR comment blocking any new dependency that shows behavioral risk signals — obfuscation, network calls in install scripts, env var access — regardless of CVE status. This catches the exact attack patterns used in the Sept 2025–June 2026 wave.
- Sign up at socket.dev — apply for nonprofit rate ($600/yr vs $4,800/yr standard)
- Install Socket GitHub App on the TWP organization
- Socket auto-creates PR comments with risk scores for any new/changed dependencies
- Configure block policy: auto-fail PRs with "Critical" behavioral issues
- Enable for:
wp-theme, wp-plugins, donation-forms (npm ecosystems)
Security Intel
Free
CI Config
~30 min
Replace npm install with npm ci --ignore-scripts in all GitHub Actions workflows. This disables postinstall / preinstall scripts — the primary vector for supply-chain malware payloads.
- In all workflow YAML files: replace
npm install → npm ci --ignore-scripts
- Test that builds still succeed (some packages legitimately need install scripts — add them to allowlist explicitly)
- Document any exceptions in a
.npmrc comment with justification
Security Intel
Partial Gap
WordPress/PHP
~2 hrs
Socket.dev does not yet cover Composer (PHP). For the WordPress PHP layer, behavioral scanning is limited. Mitigations: Dependabot for Composer CVEs + manual review policy for any new composer require additions.
- Add Dependabot config for Composer:
package-ecosystem: "composer" in dependabot.yml
- Adopt a policy: any new WP plugin or Composer package requires a manual code review before PR merge
- Consider Roave/SecurityAdvisories Composer package (blocks known-bad packages at install)
- Monitor Socket.dev Composer support roadmap — they announced beta in Q2 2026
Phase Overview
Phase 1
GitHub Config
Self-contained · ~1 day
Phase 2
Code Hygiene
Write access needed · ~2 days
Phase 3
Integrations
TWP coordination · ~3 days
Phase 4
Advisory
Ongoing · quarterly
Phase 1 — GitHub Configuration (Self-Contained)
| Task | Rec | Deliverable |
| Enable branch protection on 5 repos | R-1 | Branch rules configured, screenshot documented |
| Enable Dependabot alerts + auto-PRs | R-2 | .github/dependabot.yml committed |
| Add Dependency Review Action to CI | R-3 | dependency-review.yml in all repos |
| Add CODEOWNERS files | R-4 | .github/CODEOWNERS committed |
| Enable secret scanning push protection | R-5 prep | Block list configured in GitHub org settings |
| Add Socket.dev GitHub App | R-11 | App installed, org connected, policy configured |
| Update CI to npm ci --ignore-scripts | R-12 | All workflow YAMLs updated, builds verified |
Phase 2 — Code & Repo Hygiene (Write Access Needed)
| Task | Rec | Deliverable |
| BFG cleanup of keystore from git history | R-5 | Cleaned history, force-push, re-clone instructions for team |
| Remove stale SQL backup files | Audit Finding | Files removed, *.sql added to .gitignore |
| Audit + document all active PATs | R-6 | Token inventory in Dashlane / secure doc |
| Migrate CI secrets to GitHub Actions Secrets | R-7 | No plaintext secrets in repo or workflow files |
| Add Dependabot for Composer | R-13 | dependabot.yml updated for composer ecosystem |
Phase 3 — Integration Security (TWP Coordination Needed)
| Task | Rec | Deliverable |
| Configure SAML SSO — Salesforce via Google Workspace | R-8 | SSO live, local Salesforce login disabled |
| Rotate Salesforce Connected App credentials | R-5 follow-on | New client ID/secret in GitHub Secrets |
| Separate dev vs. prod credentials | R-9 | Dev API user created in Salesforce with limited scopes |
| Revoke long-lived tokens from developer machines | R-6 | Confirmation all PATs rotated or removed from laptops |
Phase 4 — Advisory & Documentation
| Task | Rec | Deliverable | Cadence |
| Create Offboarding / Breach Response Runbook | R-10 | Documented checklist in Notion / Google Doc | One-time |
| Quarterly token audit + rotation | R-6 | All tokens reviewed and rotated if approaching 90-day limit | Quarterly |
| Dependabot alert triage | R-2 | All Dependabot PRs reviewed and merged or deferred | Monthly |
| Socket.dev alert review | R-11 | Behavioral flags reviewed, policies adjusted as needed | Per PR |
| Security review of new Composer packages | R-13 | Manual review log for any composer require changes | Per change |
| Annual pen test coordination | R-14 | Scope defined, vendor selected, findings tracked in Asana | Annual |
| Vendor/tool documentation update | R-15 | Updated security posture doc for board / grant applications | Annual |
Bottom line: 10 of 15 recommendations cost nothing — they are GitHub configuration and workflow changes. Socket.dev at $600/yr (nonprofit rate) is the only recommended paid tool. SSO for Salesforce is configured via Google Workspace SAML at no additional cost — verify existing Salesforce license tier before assuming otherwise.
Complete Cost Table — All 15 Recommendations
| Rec |
Title |
Priority |
Cost |
Notes |
| R-1 |
Branch Protection on main |
Must-Do |
$0 |
GitHub org plan includes branch protection |
| R-2 |
Dependabot Alerts + Auto-PRs |
Must-Do |
$0 |
Free on all public and private repos |
| R-3 |
Dependency Review Action in CI |
Must-Do |
$0 |
Free GitHub Action |
| R-4 |
CODEOWNERS Files |
Must-Do |
$0 |
Free GitHub feature |
| R-5 |
Remove Keystore + Rewrite History |
Must-Do — HIGH |
$0 |
BFG Repo Cleaner is free/open-source |
| R-6 |
Audit + Rotate Long-Lived Tokens |
Do Soon |
$0 |
Labor only |
| R-7 |
Migrate CI Secrets to OIDC / GitHub Secrets |
Do Soon |
$0 |
Free GitHub feature + OIDC |
| R-8 |
SSO — Salesforce via Google Workspace |
Do Soon |
$0 |
SAML config — no additional licensing if Google Workspace Business Starter+ |
| R-9 |
Separate Dev vs. Prod Credentials |
Do Soon |
$0 |
Salesforce user creation is free |
| R-10 |
Offboarding / Breach Response Runbook |
Do Soon |
$0 |
Documentation — existing Notion or Google Doc |
| R-11 |
Socket.dev Behavioral Scanning |
Security Intel |
$600/yr |
Nonprofit rate — standard is $4,800/yr. Covers unlimited repos. |
| R-12 |
npm ci --ignore-scripts in CI |
Security Intel |
$0 |
CI config change only |
| R-13 |
Composer Dependency Gap (Dependabot) |
Security Intel |
$0 |
Dependabot Composer support is free |
| R-14 |
Annual Penetration Test (coordination) |
Advisory |
~$2,000–4,000 (vendor) |
Mitr can source nonprofit-friendly vendor. Optional — not included in $600–3,600 range. |
| R-15 |
Security Posture Documentation (board/grants) |
Advisory |
$0 |
Mitr deliverable — included in engagement |
Cost Summary by Scenario
Minimum (Free Only)
R-1 through R-10, R-12, R-13, R-15
No paid tools. Closes the most critical gaps (branch protection, keystore, SSO, token hygiene). Does not address behavioral scanning gap.
$0 / yr
labor cost to Mitr is separate
Recommended (Socket.dev)
All 15 recommendations + Socket.dev behavioral scanning. Covers all known attack vectors from the Sept 2025–June 2026 wave. This is the recommended floor for nonprofit orgs with donor PII.
$600 / yr
nonprofit rate — Socket.dev
SSO — Salesforce License Check
SSO between Salesforce and Google Workspace is configured via SAML — no additional tool needed. The only open question is whether TWP's current Salesforce license tier supports SSO. If on Salesforce Power of Us (nonprofit), Enterprise edition is included and SSO is free. Verify before assuming a cost.
$0 or TBD
depends on Salesforce license tier — confirm with Peter
Comparison — Paid vs. Free Coverage
Free Tools Cover
- All known CVE scanning (Dependabot + Dep. Review Action)
- Branch protection and review gates
- Secret scanning (push protection)
- SSO for Salesforce via Google Workspace SAML
- Token rotation and audit
- History rewrite for committed secrets
- Offboarding documentation and runbooks
$600/yr Socket.dev Adds
- Behavioral analysis of every new npm dependency
- Detection of obfuscated code, network calls in install scripts
- Typosquatting and name-confusion detection
- Maintainer account takeover signals
- Zero-day attack surface before CVE is assigned
- Would have caught chalk/debug, axios, Shai-Hulud patterns
- PR-gate blocking — stops attack before install, not after