お金を扱うのに、帳簿がなかった
銀行や決済の仕組みは、「誰から誰へ、いつ、いくら動いたか」という取引の記録を積み上げ、残高はその合計として計算します。記録を書き換えない限り、残高が勝手に増えることはありません。
当時の安価な自前ASPの多くは、この考え方を持っていませんでした。
論評以下は当時の粗悪なスクリプトに一般的だった弱点の整理です。特定の会社で実際に被害が起きたと断定するものではありません。
弱点1:残高の上書き
UPDATE users SET balance = balance + 30000 WHERE id = 1;
残高の数字を直接書き換えるだけで、取引の履歴が残らない。誰かが数字をいじっても、いつ、なぜ増えたのかを後から追えません。管理者は「この人の報酬、なぜこんなに多いんだろう」と首をかしげるしかありませんでした。
弱点2:SQLインジェクション
入力欄の値をそのままSQL文に埋め込む作りでは、細工した文字列を一度送られるだけで、会員の個人情報も売上データも読み出され、書き換えられます。報酬を1万円から1000万円に変えることも、テーブルごと消すことも可能でした。
弱点3:クッキーの改ざんと自作自演
紹介者のIDを暗号化せずにクッキーへ保存していれば、ブラウザで数字を書き換えるだけで他人の成果を横取りできます。メールアドレスを変えて何重にも登録する、捨てアドレスを大量に作って「無料登録1件◯百円」の報酬を稼ぐといった手口も、重複チェックの甘いシステムでは止められませんでした。
弱点4:バックアップがない
データベースを消されたら終わり。手元のバックアップは手動でたまに取る程度で、改ざんされた状態のデータで上書きしてしまえば、もう元には戻せません。
何が起きたか
こうした穴を突かれると、売上は実在しないのに、支払い義務の数字だけがデータベースに積み上がる状態になります。運営側は支払えず、アフィリエイターは「払え」と迫り、最後は閉鎖へ向かいます。
AIもなく、安全な部品も今ほど手軽に使えなかった時代に、個人や小さな会社がこれらの穴を一つずつ自力でふさぐのは簡単ではありませんでした。ただ、問題の根はそこだけではありません。そもそも帳簿として信頼できる数字を残すという発想が、ビジネスの側になかったのです。
今なら当たり前の対策
- 残高を直接書き換えず、取引の記録だけを追記し、残高は合計で出す。
- SQLはプレースホルダーで組み立て、入力値を直接埋め込まない。
- 重要な記録には改ざんを検知できる署名を付ける。
- バックアップを自動で取り、別の場所に保管する。
どれも特別な技術ではありません。当時それをやらなかったのは、できなかったからというより、やる必要を感じていなかったからでしょう。