PageSourceSearch

https://www.autogon.ai/state-of-app-security/

html autogon.ai collected 2026-09-28 23:20:16 UTC 25,215 bytes, 341 lines download raw bytes

1<!doctype html>
2<html lang="en">
3<head>
4<meta charset="utf-8">
5<meta name="viewport" content="width=device-width, initial-scale=1">
6<meta name="description" content="A passive, aggregate security scan of 618 public apps across 347 African financial institutions. Grades, the edge-vs-app inversion, and application-attack exposure. No institution named.">
7<meta name="robots" content="index,follow">
8<meta name="theme-color" content="#ffffff">
9<link rel="canonical" href="https://www.autogon.ai/state-of-app-security/">
10<meta property="og:type" content="article">
11<meta property="og:site_name" content="Autogon">
12<meta property="og:title" content="The State of App Security in African Finance">
13<meta property="og:description" content="A passive, aggregate security scan of 618 public apps across 347 African financial institutions. Grades, the edge-vs-app inversion, and application-attack exposure. No institution named.">
14<meta property="og:url" content="https://www.autogon.ai/state-of-app-security/">
15<meta name="twitter:card" content="summary_large_image">
16<meta name="twitter:title" content="The State of App Security in African Finance">
17<meta name="twitter:description" content="A passive, aggregate security scan of 618 public apps across 347 African financial institutions. Grades, the edge-vs-app inversion, and application-attack exposure. No institution named.">
18<title>The State of App Security in African Finance — Autogon</title>
19<link rel="preconnect" href="https://fonts.googleapis.com">
20<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
21<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
22<style>
23  :root{
24    --bg:#ffffff; --surf:#f6f6f9; --surf2:#eeeef2; --line:#e7e7ec; --line2:#dcdce2;
25    --ink:#07004d; --ink2:#35333f; --mute:#74727c; --mute2:#9a98a2;
26    --blue:#e07a06; --blue-soft:rgba(224,122,6,.10); --blue-line:rgba(224,122,6,.35);
27    --gA:#4f9d79; --gB:#8aa257; --gC:#c39a46; --gD:#c67744; --gF:#c4534b;
28    --exp:#c4534b; --exp-soft:rgba(196,83,75,.14);
29    --disp:"IBM Plex Sans",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
30    --mono:"JetBrains Mono",ui-monospace,"SF Mono",Menlo,Consolas,monospace;
31  }
32  *{box-sizing:border-box}
33  html{-webkit-text-size-adjust:100%}
34  body{margin:0;background:var(--bg);color:var(--ink2);font-family:var(--disp);
35    font-size:16.5px;line-height:1.68;-webkit-font-smoothing:antialiased;}
36  .wrap{max-width:920px;margin:0 auto;padding:0 26px;}
37  .col{max-width:660px;}
38  a{color:var(--blue);text-decoration:none;}
39  a:hover{text-decoration:underline;text-underline-offset:3px;}
40  h1,h2,h3{color:var(--ink);font-family:var(--disp);font-weight:700;letter-spacing:-.02em;text-wrap:balance;margin:0;}
41  strong{color:var(--ink);font-weight:600;}
42  .eyebrow{font-family:var(--mono);font-size:11.5px;letter-spacing:.24em;text-transform:uppercase;color:var(--blue);font-weight:500;}
43  .mono{font-family:var(--mono);font-variant-numeric:tabular-nums;}
44  .tnum{font-variant-numeric:tabular-nums;}
45
46  header.top{border-bottom:1px solid var(--line);position:sticky;top:0;z-index:20;
47    background:color-mix(in srgb,var(--bg) 88%,transparent);backdrop-filter:blur(10px);}
48  .top .wrap{display:flex;align-items:center;justify-content:space-between;height:58px;}
49  .brand{display:flex;align-items:center;gap:10px;font-family:var(--mono);font-size:13px;color:var(--ink);font-weight:500;}
50  .brand b{font-weight:600}
51  .top .tag{font-family:var(--mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--mute);}
52
53  .hero{padding:76px 0 46px;}
54  .hero h1{font-size:clamp(33px,5.6vw,54px);line-height:1.06;margin:18px 0 0;}
55  .hero .dek{max-width:640px;font-size:19px;line-height:1.6;color:var(--ink2);margin:24px 0 0;}
56
57  .stats{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line);
58    border:1px solid var(--line);border-radius:14px;overflow:hidden;margin:44px 0 0;}
59  .stat{background:var(--surf);padding:22px 20px;}
60  .stat .v{font-family:var(--disp);font-weight:700;font-size:33px;line-height:1;color:var(--ink);font-variant-numeric:tabular-nums;letter-spacing:-.02em;}
61  .stat .v small{font-size:19px;color:var(--mute);font-weight:600;}
62  .stat .k{font-family:var(--mono);font-size:10.5px;letter-spacing:.11em;text-transform:uppercase;color:var(--mute);margin-top:11px;}
63  @media(max-width:640px){.stats{grid-template-columns:repeat(2,1fr)}}
64
65  section{padding:56px 0;border-top:1px solid var(--line);}
66  .kicker{font-family:var(--mono);font-size:11.5px;letter-spacing:.2em;text-transform:uppercase;color:var(--blue);margin:0 0 15px;}
67  h2{font-size:clamp(25px,3.4vw,33px);line-height:1.14;margin:0 0 10px;}
68  section p{color:var(--ink2);max-width:660px;margin:14px 0 0;}
69  section p.lead{font-size:18.5px;color:var(--ink);}
70  .fn{font-family:var(--mono);font-size:12.5px;color:var(--mute);}
71
72  /* grade spectrum */
73  .spectrum{margin:28px 0 0;}
74  .track{display:flex;height:66px;border-radius:12px;overflow:hidden;border:1px solid var(--line);}
75  .seg{position:relative;display:flex;align-items:flex-end;padding:10px 12px;color:#0d0d11;font-family:var(--mono);font-weight:600;font-size:13px;min-width:0;}
76  .seg .lab{position:absolute;top:9px;left:12px;font-size:12px;font-weight:700;}
77  .gA{background:var(--gA)} .gB{background:var(--gB)} .gC{background:var(--gC)} .gD{background:var(--gD)} .gF{background:var(--gF)}
78  .cap{display:flex;justify-content:space-between;gap:18px;margin-top:14px;flex-wrap:wrap;align-items:baseline;}
79  .cap .big{font-size:19px;color:var(--ink);}
80  .cap .big b{color:var(--gD)}
81  .legend{display:flex;gap:15px;flex-wrap:wrap;font-family:var(--mono);font-size:12px;color:var(--mute);}
82  .legend i{width:10px;height:10px;border-radius:3px;display:inline-block;margin-right:6px;}
83
84  /* by-the-numbers band */
85  .band{margin:30px 0 0;display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--line);border:1px solid var(--line);border-radius:14px;overflow:hidden;}
86  .cell{background:var(--surf);padding:24px 22px;}
87  .cell .n{font-family:var(--disp);font-weight:700;font-size:38px;line-height:1;color:var(--ink);font-variant-numeric:tabular-nums;letter-spacing:-.02em;}
88  .cell .n.warn{color:var(--exp)}
89  .cell .t{margin-top:10px;color:var(--ink2);font-size:14.5px;line-height:1.45;}
90  .cell .t b{color:var(--ink)}
91  @media(max-width:640px){.band{grid-template-columns:1fr 1fr}}
92
93  /* inversion chart */
94  .chart{margin:32px 0 0;border:1px solid var(--line);border-radius:14px;background:var(--surf);overflow:hidden;}
95  .chart .h{display:grid;grid-template-columns:150px 1fr;gap:20px;padding:15px 20px;border-bottom:1px solid var(--line);font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--mute);}
96  .chart .h .keys{display:flex;gap:20px}
97  .chart .h .keys span{display:flex;align-items:center;gap:7px}
98  .dot{width:9px;height:9px;border-radius:2px;display:inline-block}
99  .dot.e{background:var(--blue)} .dot.x{background:var(--exp)}
100  .row{display:grid;grid-template-columns:150px 1fr;gap:20px;align-items:center;padding:14px 20px;border-top:1px solid var(--line);}
101  .row:first-of-type{border-top:0}
102  .row .nm{font-family:var(--mono);font-size:13px;color:var(--ink)}
103  .row .nm small{display:block;color:var(--mute);font-size:11px;margin-top:3px}
104  .bars{display:grid;gap:8px}
105  .bg{display:grid;grid-template-columns:1fr 40px;align-items:center;gap:12px}
106  .tk{height:11px;background:#e9e9ee;border-radius:6px;overflow:hidden}
107  .tk>span{display:block;height:100%;border-radius:6px}
108  .fe{background:var(--blue)} .fx{background:var(--exp)}
109  .bg .p{font-family:var(--mono);font-size:12.5px;color:var(--ink2);text-align:right;font-variant-numeric:tabular-nums}
110  @media(max-width:560px){.chart .h,.row{grid-template-columns:1fr;gap:9px}.row .nm small{display:inline;margin-left:7px}}
111
112  /* susceptibility */
113  .susc{margin:28px 0 0;display:grid;gap:12px}
114  .sr{display:grid;
114grid-template-columns:170px 1fr 44px;align-items:center;gap:16px}
115  .sr .l{font-family:var(--mono);font-size:13px;color:var(--ink)}
116  .sr .l small{color:var(--mute);font-size:11px}
117  .sr .t{height:14px;background:#e9e9ee;border-radius:7px;overflow:hidden}
118  .sr .t>span{display:block;height:100%;border-radius:7px;background:var(--exp)}
119  .sr.hl .t>span{background:repeating-linear-gradient(45deg,var(--exp),var(--exp) 8px,#8f3b35 8px,#8f3b35 16px)}
120  .sr .p{font-family:var(--mono);font-size:13px;text-align:right;color:var(--ink);font-variant-numeric:tabular-nums}
121  @media(max-width:560px){.sr{grid-template-columns:130px 1fr 40px;gap:11px}.sr .l small{display:none}}
122
123  /* fomo */
124  .fomo{background:linear-gradient(180deg,var(--surf),var(--bg));border-top:1px solid var(--line);}
125  .fomo h2{max-width:720px}
126  .fomo .lead{font-size:20px;color:var(--ink);max-width:700px}
127
128  /* cta cards */
129  .ctas{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin:30px 0 0}
130  .card{display:block;border:1px solid var(--line);border-radius:14px;background:var(--surf);padding:24px 24px;transition:border-color .15s,background .15s}
131  .card:hover{border-color:var(--blue-line);background:var(--surf2);text-decoration:none}
132  .card .e{font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--blue)}
133  .card h3{font-size:20px;margin:12px 0 0;color:var(--ink)}
134  .card p{color:var(--ink2);font-size:15px;margin:9px 0 0;max-width:none}
135  .card .go{display:inline-block;margin-top:16px;font-family:var(--mono);font-size:13px;color:var(--blue)}
136  .cta-scan{margin:18px 0 0;display:flex;align-items:center;gap:14px;flex-wrap:wrap}
137  .btn{display:inline-block;background:var(--blue);color:#0a1120;font-family:var(--mono);font-weight:600;font-size:13.5px;padding:12px 20px;border-radius:10px}
138  .btn:hover{text-decoration:none;filter:brightness(1.06)}
139  .cta-scan .aside{font-family:var(--mono);font-size:12.5px;color:var(--mute)}
140  @media(max-width:640px){.ctas{grid-template-columns:1fr}}
141
142  .method{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--line);border:1px solid var(--line);border-radius:14px;overflow:hidden;margin:26px 0 0}
143  .method div{background:var(--surf);padding:20px 22px}
144  .method h4{margin:0 0 7px;font-family:var(--mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--blue);font-weight:600}
145  .method p{margin:0;font-size:14.5px;color:var(--ink2)}
146  @media(max-width:560px){.method{grid-template-columns:1fr}}
147  .ethics{font-family:var(--mono);font-size:12.5px;color:var(--mute);border:1px dashed var(--line2);border-radius:12px;padding:16px 18px;margin:22px 0 0;line-height:1.6}
148
149  footer{border-top:1px solid var(--line);padding:40px 0 64px;color:var(--mute)}
150  footer .wrap{display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap;align-items:baseline}
151  footer .mono{font-size:12.5px}
152</style>
153</head>
154<body>
155
156
157<header class="top">
158  <div class="wrap">
159    <a class="brand" href="https://www.autogon.ai" aria-label="Autogon" style="text-decoration:none">
160      <img src="/autogon-full-logo-dark.png" alt="Autogon" style="height:20px;width:auto;display:block">
161      <span style="color:var(--mute)">· Research</span>
162    </a>
163    <span class="tag">Passive scan · Aggregate · Aug 2026</span>
164  </div>
165</header>
166
167<div class="wrap">
168  <div class="hero">
169    <p class="eyebrow">The State of App Security · Africa</p>
170    <h1>African finance runs on the internet. Here is what the internet already knows about it.</h1>
171    <p class="dek">We mapped and passively scanned 618 public applications belonging to 347 African
172      banks, fintechs, payment companies, crypto exchanges and insurers across 21 African countries. One
173      browser-style request each. No logins, no probing, no institution named.</p>
174
175    <div class="stats" role="list">
176      <div class="stat" role="listitem"><div class="v">618</div><div class="k">Public apps scanned</div></div>
177      <div class="stat" role="listitem"><div class="v">347</div><div class="k">Institutions</div></div>
178      <div class="stat" role="listitem"><div class="v">21</div><div class="k">African countries</div></div>
179      <div class="stat" role="listitem"><div class="v">34<small>%</small></div><div class="k">Publish a public API</div></div>
180    </div>
181
182    <div class="spectrum">
183      <div class="track" role="img" aria-label="Grade distribution: A 29 percent, B 21 percent, C 26 percent, D 20 percent, F 4 percent">
184        <div class="seg gA" style="flex:29"><span class="lab">A</span>29%</div>
185        <div class="seg gB" style="flex:21"><span class="lab">B</span>21%</div>
186        <div class="seg gC" style="flex:26"><span class="lab">C</span>26%</div>
187        <div class="seg gD" style="flex:20"><span class="lab">D</span>20%</div>
188        <div class="seg gF" style="flex:4"><span class="lab">F</span></div>
189      </div>
190      <div class="cap">
191        <span class="big"><b>50%</b> of financial apps grade C or below on passive posture.</span>
192        <span class="legend">
193          <span><i class="gA"></i>A</span><span><i class="gB"></i>B</span><span><i class="gC"></i>C</span>
194          <span><i class="gD"></i>D</span><span><i class="gF"></i>F</span>
195        </span>
196      </div>
197    </div>
198  </div>
199</div>
200
201<section>
202  <div class="wrap">
203    <p class="kicker">By the numbers</p>
204    <h2>What one afternoon of passive scanning turned up.</h2>
205    <div class="band">
206      <div class="cell"><div class="n warn">83%</div><div class="t"><b>carry XSS exposure</b> — no Content-Security-Policy, or one defeated by unsafe-inline.</div></div>
207      <div class="cell"><div class="n warn">188</div><div class="t"><b>apps carry 3+ exposures</b> at once — nearly one in three of everything scanned.</div></div>
208      <div class="cell"><div class="n warn">39%</div><div class="t"><b>have no clickjacking protection</b> on the page a user logs in through.</div></div>
209      <div class="cell"><div class="n warn">79</div><div class="t"><b>financial apps run on WordPress</b> — a CMS attack surface under a bank or fintech brand.</div></div>
210      <div class="cell"><div class="n warn">37</div><div class="t"><b>answer any site on earth</b> with a wildcard CORS policy, a few on login pages.</div></div>
211      <div class="cell"><div class="n warn">14</div><div class="t"><b>are serving on invalid or expired certificates</b> right now.</div></div>
212    </div>
213  </div>
214</section>
215
216<section>
217  <div class="wrap">
218    <p class="kicker">Finding 01 — The inversion</p>
219    <h2>The banks and the fintechs are each half-secure, in opposite ways.</h2>
220    <p class="lead">On the <strong>edge</strong> — a recognizable WAF or CDN out front — the fintechs win
221      easily. On the <strong>application itself</strong> — the actual defenses in the app — it flips. The
222      newest, fastest companies lean on a CDN and ship the app almost bare. The banks did the opposite.</p>
223
224    <div class="chart">
225      <div class="h">
226        <span>Institution type</span>
227        <span class="keys"><span><i class="dot e"></i>Detectable edge</span><span><i class="dot x"></i>High app-attack exposure</span></span>
228      </div>
229      <div class="row"><div class="nm">Crypto exchanges<small>43 assets</small></div><div class="bars"><div class="bg"><div class="tk"><span class="fe" style="width:79%"></span></div><div class="p">79%</div></div><div class="bg"><div class="tk"><span class="fx" style="width:14%"></span></div><div class="p">14%</div></div></div></div>
230      <div class="row"><div class="nm">Remittance<small>30 assets</small></div><div class="bars"><div class="bg"><div class="tk"><span class="fe" style="width:63%"></span></div><div class="p">63%</div></div><div class="bg"><div class="tk"><span class="fx" style="width:20%"></span></div><div class="p">20%</div></div></div></div>
231      <div class="row"><div class="nm">Traditional banks<small>174 assets</small></div><div class="bars"><div class="bg"><div class="tk"><span class="fe" style="width:30%"></span></div><div class="p">30%</div></div><div class="bg"><div class="tk"><span class="fx" style="width:22%"></span></div><div class="p">22%</div></div></div></div>
232      <div class="row"><div class="nm">Mobile money<small>50 assets</small></div><div class="bars"><div class="bg"><div class="tk"><span class="fe" style="width:24%"></span></div><div class="p">24%</div></div><div class="bg"><div class="tk"><span class="fx" style="width:24%"></span></div><div class="p">24%</div></div></div></div>
233      <div class="row"><div class="nm">Payment gateways<small>82 assets</small></div><div class="bars"><div class="bg"><div class="tk"><span class="fe" style="width:61%"></span></div><div class="p">61%</div></div><div class="bg"><div class="tk"><span class="fx" style="width:27%"></span></div><div class="p">27%</div></div></div></div>
234      <div class="row"><div class="nm">Fintechs<small>130 assets</small></div><div class="bars"><div class="bg"><div class="tk"><span class="fe" style="width:59%"></span></div><div class="p">59%</div></div><div class="bg"><div class="tk"><span class="fx" style="width:42%"></span></div><div class="p">42%</div></div></div></div>
235      <div class="row"><div class="nm">Neobanks<small>36 assets</small></div><div class="bars"><div class="bg"><div class="tk"><span class="fe" style="width:36%"></span></div><div class="p">36%</div></div><div class="bg"><div class="tk"><span class="fx" style="width:47%"></span></div><div class="p">47%</div></div></div></div>
236      <div class="row"><div class="nm">Lending<small>27 assets</small></div><div class="bars"><div class="bg"><div class="tk"><span class="fe" style="width:41%"></span></div><div class="p">41%</div></div><div class="bg"><div class="tk"><span class="fx" style="width:52%"></span></div><div class="p">52%</div></div></div></div>
237      <div class="row"><div class="nm">Insurtech<small>18 assets</small></div><div class="bars"><div class="bg"><div class="tk"><span class="fe" style="width:44%"></span></div><div class="p">44%</div></div><div class="bg"><div class="tk"><span class="fx" style="width:56%"></span></div><div class="p">56%</div></div></div></div>
238    </div>
239    <p class="fn" style="margin-top:16px">Crypto — the most-attacked category on earth — is the only one that defends both layers: highest edge adoption, lowest exposure. Everyone else picked one, or neither.</p>
240  </div>
241</section>
242
243<section>
244  <div class="wrap">
245    <p class="kicker">Finding 02 — Susceptibility</p>
246    <h2>Who is actually weak to application attacks.</h2>
247    <p>Measured passively, from missing or <em>defeated</em> defenses — never by attacking. A quarter of
248      the apps that send a Content-Security-Policy weaken it with <span class="mono">unsafe-inline</span>,
249      which defeats its XSS protection, so a naive "has a CSP" check would score them safe. This one does
250      not. Share of all 618 apps exposed to each attack:</p>
251    <div class="susc">
252      <div class="sr"><div class="l">XSS <small>no / defeated CSP</small></div><div class="t"><span style="width:83%"></span></div><div class="p">83%</div></div>
253      <div class="sr"><div class="l">Clickjacking <small>no frame guard</small></div><div class="t"><span style="width:39%"></span></div><div class="p">39%</div></div>
254      <div class="sr"><div class="l">MITM / SSL-strip <small>no HSTS · bad TLS</small></div><div class="t"><span style="width:32%"></span></div><div class="p">32%</div></div>
255      <div class="sr"><div class="l">WordPress <small>CMS under a bank brand</small></div><div class="t"><span style="width:13%"></span></div><div class="p">13%</div></div>
256      <div class="sr"><div class="l">CSRF <small>no SameSite</small></div><div class="t"><span style="width:12%"></span></div><div class="p">12%</div></div>
257      <div class="sr"><div class="l">Wildcard CORS <small>some on logins</small></div><div class="t"><span style="width:6%"></span></div><div class="p">6%</div></div>
258      <div class="sr hl"><div class="l">High exposure <small>3+ at once</small></div><div class="t"><span style="width:30%"></span></div><div class="p">30%</div></div>
259    </div>
260  </div>
261</section>
262
263<section>
264  <div class="wrap">
265    <p class="kicker">Finding 03 — The estate everyone under-serves</p>
266    <h2>Finance became an API business, and the API is the part no header protects.</h2>
267    <p class="lead">A third of these institutions now publish a public developer API — 145 developer and
268      API-doc surfaces in all. On the newest fintechs the API ships before the app does.</p>
269    <p>None of what this report measures — not a single header, not the CDN, not the certificate — touches
270      the risk that has moved to the center of the industry. The attacks that break an API are broken
271      object-level authorization, broken function-level authorization, and business-logic abuse: a request
272      that is perfectly well formed and simply should not have been allowed. There is no header for that.
273      There is no CDN rule for it. A signature-matching WAF cannot see it, because there is no signature
274      for "you asked for an account that is not yours."</p>
275  </div>
276</section>
277
278<section class="fomo">
279  <div class="wrap">
280    <p class="kicker">The uncomfortable part</p>
281    <h2>This took one afternoon, passively, from a laptop. An attacker has the same view of your estate right now.</h2>
282    <p class="lead">Nothing here required special access. No exploit, no login, no permission. Just the
283      response a server hands to any browser that asks. Every institution in this report was mapped that
284      way — and so is yours. The only question the data leaves open is where yours lands on the spectrum.</p>
285    <div class="cta-scan">
286      <a class="btn" href="https://www.autogon.ai/protect/">Scan your own app — free →</a>
287      <span class="aside">One request. Passive. See your grade in seconds.</span>
288    </div>
289  </div>
290</section>
291
292<section>
293  <div class="wrap">
294    <p class="kicker">What actually closes the gap</p>
295    <h2>Headers are table stakes. The API layer needs something that learns your app.</h2>
296    <p>A CSP stops a class of injection. A CDN filters known-bad traffic. Neither knows that <em>this</em>
297      user should not be able to read <em>that</em> account, or that a refund should never exceed the
298      original charge. That judgment lives in your app's own logic — so the defense has to learn your app's
299      normal behavior and block the deviation. That is positive security, and it is what Autogon builds.</p>
300    <div class="ctas">
301      <a class="card" href="https://www.autogon.ai/omniguard/">
302        <span class="e">Autogon Omniguard</span>
303        <h3>Application security that learns your app</h3>
304        <p>Learns each app and API's normal behavior and blocks the deviations — the IDOR, BOLA, broken
305          auth and business-logic abuse a signature WAF and a header checklist never see.</p>
306        <span class="go">Explore Omniguard →</span>
307      </a>
308      <a class="card" href="https://www.autogon.ai/positive-security-waf/">
309        <span class="e">Positive security</span>
310        <h3>How allow-list protection works</h3>
311        <p>Why deny-by-default beats block-the-known-bad, in one line of code — observe first, fail-open,
312          every block delivered with proof.</p>
313        <span class="go">See how it works →</span>
314      </a>
315    </div>
316  </div>
317</section>
318
319<section>
320  <div class="wrap">
321    <p class="kicker">Method &amp; ethics</p>
322    <h2>How this was done, and the line it does not cross.</h2>
323    <div class="method">
324      <div><h4>Passive only</h4><p>One browser-style GET plus a TLS handshake per asset. We read response headers, cookies, CORS, TLS state, and the page's own markup. No authentication, no path probing, no payloads, no exploitation.</p></div>
325      <div><h4>Validated twice</h4><p>Every URL passed liveness (with retries) and an identity check — including TLS-certificate confirmation — before scanning. The scanner is validated against known-good and known-weak controls.</p></div>
326      <div><h4>Susceptibility, not exploits</h4><p>"Weak to X" means the defense against X is missing or defeated, inferred from the public response. We never attacked anyone to find out.</p></div>
327      <div><h4>Aggregate, never named</h4><p>No institution is identified as exposed, here or anywhere. A list of which bank has the weakest headers is the opposite of helpful, and building it is not the point.</p></div>
328    </div>
329    <p class="ethics">Scope: public homepages, login landings, and developer docs of financial institutions, gathered from public sources. Figures reflect the latest validated snapshot and may move by a percentage point between runs as live infrastru
329cture changes. Security teams: <a href="https://www.autogon.ai/protect/">scan your own estate</a>, or reach out for the methodology.</p>
330  </div>
331</section>
332
333<footer>
334  <div class="wrap">
335    <span class="mono"><a href="https://www.autogon.ai">Autogon</a> · State of App Security in African Finance</span>
336    <span class="mono">618 apps · 347 institutions · 21 countries · passive scan</span>
337  </div>
338</footer>
339
340</body>
341</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.