Security postmortem

This page summarizes the security posture of the Currnt platform as observed during the December 2024 freeze. It is categorical disclosure: structural and operational issues are described in terms of their shape and consequence, not in terms of specific secret values, IP addresses, internal hostnames, or live endpoints. The platform was dormant by the time of inspection; the issues here would not have been published if it were not.

The framing is calibrated: this is not a “look how broken it was” piece. The Currnt platform was operationally reliable for many years and many of the issues below are typical of a long-lived web monolith run by a small team with finite attention. Calling them out is part of an honest archive.

1 · End-of-life dependencies

Every layer of the production stack was years past its vendor end-of-life date by 2024:

The application kept working because nothing in the world demanded these upgrade; absent active maintenance, none happened. The implication is the absence of years of security fixes across the stack.

2 · Plaintext secrets in unexpected places

Several secrets that should have been in environment variables or a secret manager were instead in places that are scriptable to read:

None of these surfaces was publicly exposed, but each represents a privilege-escalation path: read access to one location yields the key.

3 · Password hashing

The users.password column is sized as CHAR(40) — exactly the width of a hex-encoded SHA-256 digest. There is no per-user salt column; the application code applies a global pepper but does not use bcrypt, argon2, scrypt, or PBKDF2.

The consequence: in a hypothetical password-database disclosure, every account would be vulnerable to offline brute-force attack at full CPU/GPU speed. Migration to a modern KDF was on the roadmap and never landed.

4 · Authentication-rate limits

The web auth surface (/login) and the API auth surface (/api/v1/auth/login) share the same backend. There is no per-IP, per-account, or global rate limit on either. This is exclusively the kind of issue that matters only in conjunction with #3 above — an attacker with no list of hashes can’t do much with the absence of rate-limiting alone. Combined, they form a credible exposure.

5 · Schema as canonical (no migration tool)

There is no migration-tool source of truth (no Liquibase, no Flyway, no Alembic-equivalent). Schema changes were applied manually as ALTER TABLE statements during low-traffic windows. The implication is more operational than security-shaped, but it matters for security in one way: there is no audit trail of who applied what schema change, when, on what authority. The database is the schema, and the schema’s history is in MySQL’s binlog (if retained) and in the heads of past staff.

6 · SSH key situation

A handful of SSH-key state issues observed during recon, generic enough to mention:

7 · The LinkedIn-scraping fleet

Discussed in product terms on the CRM engine page. In security/legal terms, this pipeline existed in a contested zone (Terms of Service vs hiQ v. LinkedIn-style precedent), and depended on continuous rotation of harvested accounts and residential-proxy IPs to operate.

It is preserved here as part of an honest archive of how the platform actually worked. It is not endorsed.

8 · The AI co-facilitator’s disclosure question

Covered on its own page: board posts authored by an AI process were rendered identically to posts authored by humans, under a single privileged author account. Whether disclosure to board participants was sufficient is a product question, not a security one — but it’s here because it’s the kind of item a thorough audit would flag.

9 · Observability of unknown destination

An OpenTelemetry collector and Fluent-Bit are installed on the application host and shipping logs/metrics outward. The destination was not pinned during recon — it could be GCP-native, or it could be an external endpoint forgotten years ago. Either way, the platform’s logs are leaving the production environment to somewhere, and an audit would want to confirm where.

Summary table

#CategorySeverity if exploitedLikelihood at freeze
1EOL stack across MySQL / ES / Node / Sails / OSCritical (CVEs accumulate over years)Low (no public surface known)
2Plaintext secrets in scripts and DB columnsHigh (privilege escalation given file access)Low (no public file access)
3SHA-256 password hashing, no salt columnCritical given a DB disclosureLow (DB not publicly reachable)
4No auth rate limitMedium combined with #3
5No schema migration toolOperational risk
6Mixed SSH-key stateOperational risk
7LinkedIn-scraping operationsLegal exposure
8AI co-facilitator disclosureReputational
9Unknown observability destinationData leakage