※このコードは学習用です。実運用では必ず安全性を確認してください。
はじめに
いつだかの記事で、
「PHPをサーバーに置いたら、スマホでも記録が保存できるようになった」
と書いたことがありました。
正直、もうどの記事だったか自分でも分かりません。
あのときの私は、
仕組みもよく分からないまま、
ChatGPTにもらったコードをコピペして、
ただ「動いた!」と喜んでいました。
本当に、呪文みたいに見えていたコードです。
でも、しばらくしてから知りました。
これ、そのまま公開したら、かなり危険な状態だったらしい。
今回は、そのとき実際に動かしていたコードと、
あとから知って青ざめたポイント、
そして最低限やった安全対策の話をまとめます。
これは解説というより、
初心者が「動いた!」から「怖い…」に変わるまでの記録です。
当時の「意味も分からず動かしたコード」
これが、当時そのまま置いていた save.php です。
<?php
$data = json_decode(file_get_contents("php://input"), true);
$file = 'data.json';
if(file_exists($file)){
$current = json_decode(file_get_contents($file), true);
}else{
$current = [];
}
array_unshift($current, $data);
file_put_contents($file, json_encode($current, JSON_PRETTY_PRINT));
?>
data.json
[]
JavaScript側
fetch('save.php', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(data)
})
当時の私は、
「入力した内容が保存できた!すごい!」
それだけでした。
仕組みは分かっていないけど、
とにかく、スマホから送ったデータが保存される。
それが嬉しくて仕方なかった。
実はこれ、「誰でも書き込める状態」でした
あとから知ったんですが、これ、
世界中の誰でも、自由に書き込める状態でした。
つまり、
- いたずらでデータを消される
- 大量データを送りつけられてサーバーが重くなる
- 想定外のデータでJSONが壊れる
全部、起こり得る状態。
しかも私は、それを公開状態で置いていました。
このあたりから、だんだん楽しい気持ちが変わってきます。
「え、ちょっと待って」
「私、なに置いてたの…?」
怖くなって、アプリを一度消しました
ここまで知ったとき、
私はちょっと怖くなって、
作っていたアプリを一度アンインストールしました。
なんか、触らないほうがいい気がして。
動いたときはあんなに嬉しかったのに、
「危ないかもしれない」と知った瞬間、
急に距離を取りたくなりました。
これ、あとから思うとすごく人間らしい反応だなと思います。
理解していないものが動いているときは楽しいのに、
理解していないまま危険だと知ると、急に怖くなる。
最低限の安全策を教えてもらいました
ChatGPTに聞きながら、最低限これを足すように言われました。
トークン(合言葉)
$token = "my_secret_key_123";
$headers = getallheaders();
if (!isset($headers['X-APP-TOKEN']) || $headers['X-APP-TOKEN'] !== $token) {
http_response_code(403);
exit("Forbidden");
}
JavaScript側
headers: {
'Content-Type': 'application/json',
'X-APP-TOKEN': 'my_secret_key_123'
}
これで、「合言葉を知っている人だけ」書き込めるようになります。
ただし、これもあとから知りました。
開発者ツールを見れば、この合言葉は見えます。
完璧ではないけど、何もないよりはずっとマシ、という状態。
排他ロック(LOCK_EX)
file_put_contents(
$file,
json_encode($current, JSON_PRETTY_PRINT),
LOCK_EX
);
この LOCK_EX を足すだけで、
同時アクセスによるデータ消失が起きにくくなるらしい。
魔法の言葉みたいでした。
JSONが壊れていたときの対策
if(!is_array($current)){
$current = [];
}
万が一データが壊れても、保存できるように。
こういうことを、私は一切考えていませんでした。
.htaccess で data.json を守る
<Files "data.json">
Require all denied
</Files>
これで、ブラウザから直接 data.json が見えないようになります。
※Apache環境のみ有効です。
このコードの限界
ここまでやっても、これは学習用レベルです。
本来必要なことはまだたくさんあります。
- 入力チェック(何でも保存されてしまう)
- 容量制限
- 本格的な認証
- データベースの利用
つまり、
動くコードと、安全なコードはまったく別物でした。
まとめ:嬉しかった気持ちと、怖くなった気持ち
最初はただ、
「保存できた!すごい!」
それだけでした。
でもあとから、
「これ危ないよ」と知って、
怖くなって、アプリを消して、
そこからやっと、
安全ってなんだろう、と考え始めました。
たぶんこれが、
初心者が本当にセキュリティを意識する瞬間なんだと思います。
誰かに言われたからじゃなくて、
自分が怖くなったから。
このコードは、今見るとツッコミどころだらけです。
でもあのときの私にとっては、
確実に、
「はじめてサーバーにデータを保存できた瞬間のコード」
でした。
そして、
「安全って難しい」と知ったきっかけのコードでもあります。
ただやったら、こうだった。
その記録です。

コメント