いつもお世話になります。
ログイン型の小規模WEBサービスを作りたいと思っています。
ユーザーは特定少数(100人以下)なので、不特定多数に公開するサービスほどセキュリティに神経質になる必要性は少ないのかもしれないですが、それでもやはり脆弱の温床になることは避けたいと思っています。
一度、そのようなシステムをPerlで作ったことはあります。(100時間~くらいかかりました)
そのときはライブラリを極力使わず、可能な限り自分でコーディングしました。
(使ったのは、HTMKL::Templateと文字コード変換系ぐらい)
よくPerlではCGI.pmを使うようですが、「自分でできる部分はライブラリを使わない」をモットーにがんばってました・・・
別にそのときのシステムに不満があるわけではないのですが、そのときはDBを使わず、すべてテキストファイルにさまざまな情報を保存していました。(ユーザーの情報を)
今回、MySQLを使ってみようと思っているのですが、「自作のログインシステムは脆弱性の温床になる」という記事を見かけ躊躇しております。
どうしても自分で把握できない部分(具体的にはライブラリやDBアクセス)への攻撃が想像つきません。
大量の個人情報を扱う、ということはないのですが、やはりこの一言が気になってしまいました。
仮にCGIに脆弱性がなくてもOSの設定に脆弱性があったら元も子もないと思います。
まとめると
・可能な限り外部ライブラリを使わずに自作したい
・ログインシステムは自作してもよいのか(ダメならオープンソース等教えてください)
・脆弱性を生まないためにはどうすればよいのか(参考サイト/書籍を教えてください)
このあたりについて皆様の意見をいただけますと幸いです。
(OSはUbuntuを想定しています)
以下指摘がありましたので別の質問として投稿させていただきます
既に回答くださった方ありがとうございます。今後は別スレでお願いいたします
また、今回の件に限らず、攻撃に対する対策というものがいまいちよくわかっていません。
自宅サーバーを持ってはいますが、ほとんどのソフトをデフォルト設定で使っているような状態です。
(せいぜいデフォルトのポート番号を変更する程度)
(SSH、FTP、HTTP、ファイル共有(Localで使用)、無線LANのAP、ゲーム鯖(Minecraft)等)
どれも不特定多数を相手にするものではありませんが、インターネットからアクセスできる以上、最低限のセキュリティ対策はしたいと思っています。(盗まれて困る情報は皆無ですが、踏み台にされるのが怖い)
攻撃に対する対策について詳しいサイト等ありましたら教えていただけますと幸いです。
(かならずこれは読むべき!!!という書籍がありましたらあわせて紹介していただけると幸いです)
また、今回の件に限らず、攻撃に対する対策というものがいまいちよくわかっていません。
自宅サーバーを持ってはいますが、ほとんどのソフトをデフォルト設定で使っているような状態です。
(せいぜいデフォルトのポート番号を変更する程度)
攻撃に対する対策について詳しいサイト等ありましたら教えていただけますと幸いです。
(絶対にこれがいい!というような書籍がありましたらあわせて紹介していただけると幸いです)
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/05/04 08:28
回答7件
0
ベストアンサー
ライブラリに頼らず、自作にチャレンジすることは良いことだと思います。ただ、恐ろしいほどの茨の道です。私なら必要に迫られない限り絶対にしません。きちんとした物を作るにはかなりの知識が必要になるからです。
ちょっと例をあげます。今回はログイン処理と言うことで、パスワードの保存部分を考えます。パスワードを生のまま保存することはさすがにナンセンスということはわかりますよね?では、なぜ、そのまま保存してはいけないかを説明できるでしょうか?いや、だって外からその生のパスワードが書かれた領域(テキストファイルでもDBでもいいです)は見えないわけですから、生のパスワードのままだって問題ないはずです。じゃあ、面倒だし、生で保存しておきましょう。
と、してはいけません。何が問題かを説明するととても長くなるので省きますが、わかっていないのにやっちゃいけないことの一つです。では、教科書通りハッシュ化するとしましょう。
PHP
1<?php 2// パスワードを設定します 3$password = 'mypassword'; 4 5// ハッシュを取得します。salt は自動生成させます 6$hash = crypt($password); 7?>
上のコードはPHPの公式なマニュアルにも載っている例です。古いPHPのサンプルでも見かけるような物です。ですが、これをつかってはいけません(マニュアルにもpassword_hash()を使うように書いてあります)。何が問題なのかを説明するとこれまたとても長くなるので省きますが、わかっていないのにこれまたやっちゃいけないことの一つです。
ちょっとパスワード保存部分を考えただけでも、色々と注意点が出てきました。このようにログイン認証のセキュリティについては注意すべき点が数多くあり、生半可な知識でできるようなものではありません。多くの人に使われ、それなりに実績があるライブラリを見て、なぜ、それらがその実装を行っているのかを人に説明できるぐらいでないと難しいです。それこそIPAの資料を作成できるぐらいでないと難しいです。
最後に、私は上で何度も「説明できる」ということを前提にしてきました。やり方を知っているでは不十分であり、なぜそうなるかを説明できる方が大事になります。なぜなら、こっちの方が便利かもと言ってやり方を少しでも変えてしまうと、守るべき所が守られず、そこに脆弱性が産まれる可能性が高いからです。一つの脆弱性でシステム全てが破綻することもあります。時には損害賠償にまで発展する場合もあります。広く使われているログイン認証のライブラリのソースや、maisumakunさんやte2jiさんが貼っているIPAの資料などもよく読んで、理解し、人に説明できるぐらいになってください。ただ、中途半端に学んだだけで、これでもう大丈夫だとは決して思わないようにしてください。また、攻撃手段は常に開発され続けており、情報は定期的に集めるようにしてください。ゴールが無い茨の道ですが、できるようになれば、その分野でのかなりの技術者として認められるようになると思います。頑張ってください。
投稿2016/05/04 10:37
編集2016/05/04 10:39総合スコア21737
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/05/05 01:32
退会済みユーザー
2016/05/10 04:33
2016/05/10 09:48 編集
0
ログイン機能関連(セッションも含め)で発生する脆弱性として、
- SQLインジェクション
- セッションの盗聴
- セッション固定攻撃
- CSRF
などが存在しています。そして、作り方によっては「ログインできない」「セッションがすぐ切れる」などのトラブルが起きることもあります。
フレームワーク標準のセッションですらトラブルが起きがちなところですので、(実用品として作る、という観点では)「自前で作る」という選択肢は、かかる手間とリスクに見合うだけの利点が見込めないですので、決しておすすめできません(どういう事情で「自前で作りたい」のでしょうか)。「多くの人が使っている」オープンソースライブラリを使ったほうが多数の目が通っているので、確実に安全です。
Webセキュリティ関連の文書としては、IPAが出しているガイドや、書籍では通称「徳丸本」が参考になります。
投稿2016/05/04 08:17
総合スコア145930
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/05/04 09:21
0
おそらく、書き出すとキリが無いので、取り急ぎ、思いつく対策について、だらだら列挙します。
他の解答の方が、不足部分は補間していただけるかと!?
ネットワーク側
- サーバをどこに置かれるかわかりませんが、ルーターやFireWallなどが、ある場合には、きちんとフィルタ設定しましょう。基本は、ホワイトリストです。サーバの中身にもよりますが、少なくともIN方向には、サービスを行いたいポートと、それに関連するポート(例えばDNSがあればDNSとか)のみにしましょう。可能であれば、OUT側も、必要最小限(curlやwgetと名前解決とか・・・)のみにし、他は閉じましょう。万が一の際のデータ流出口をできるだけ閉じるべきです。
サーバ側
-
ネットワーク側でポートを塞いだとしても、他の経路(同セグメントの別サーバとか)からの、攻撃も考えられますので、iptableなどに正しくフィルタ設定してください。
-
サーバ側で利用しないサービスは停止しましょう。昨今はSSHがあれば、生FTPなど必要ないでしょうし、他MySQLの3306などは、真っ先に閉じておくべきです。
-
サーバ側のSSHについては、すくなくとも認証鍵方式とし、パスワードログインは閉じましょう。場合によっては、rootではなく、別のrootユーザーを作ってもよいでしょう。
-
各サービスの実行権限者を確認しましょう。単純にrootで動作するものなどもあります、できれば専用ユーザーとして、アクセス範囲を狭めましょう。
-
データベースについては、開発中などphpMyAdminなど、用いているかもしえませんが、もし運用で必要なくなったら、この手のツール部分には、アクセス制限をかけてしまいましょう(簡易にBASIC認証追加だけでもできるなら、本来は指定ホスト以外からのアクセスを遮断するとよい)。
コーディング
-
まず、MySQLを使うとのことで、気になるのは、「SQLインジェクション」ですね。これは、同キーワードでよく調べてください。最近は、プレースホルダーなどが使えるので、だいぶ簡易に対策できるようになりましたので、ここは、とにかくよく調べてください。
-
可能であればパスワードは、ハッシュ化したものを、持つようにしましょう。ハッシュ化パスワードの場合には、ユーザのパスワード忘れなどの際には、サーバ側でパスワードわからないので、再発行形式ですが、生パスワードを持つのはあまりお勧めできません。
万が一漏れたパスワードで、他のシステムにも、ログインされるなどの影響があります。
-
そして、ログインシステムは、まずは、よく設計を行ってください。特に自前実装であればです。あらゆるパターン(引数の与え方、サーバ側のAPIがばれた場合でも大丈夫か?クッキー、セッションなど、脆弱性を持ちそうな部分に問題はないか?なぽ)を想定する必要がありますが、フレームワークに頼りっきりで、いざ脆弱性が・・・となったときに、ブラックボックスで中身が全く分からず、なら、自前実装の方が、よいかもしれません。
-
最後に、まずはとにかくシンプルに設計しましょう。いろいろな機能がつくことで、パラメータや、APIが増えていきますが、増えれば増えるほど、対応する事が増えてきます。なので、とにかくシンプルに!
長々と書きましたが、
まだまだあるかと思います。
次の方〜どうぞ〜!
P.S.追記です
自前がいいのか、フレームワークか、という所、ちょっと書きましたが、きちんと書けるのであれば、自前で十分です。フレームワークに頼ってしまうと、中の動作がわからず、いざ対策といった時に、どこから手をつけていいかわかりません。
そして、フレームワーク系は、万一他の同フレームワークでシステムが破られてたときに、同じ攻撃をうける可能性もあります。
よって、フレームワークの中まで、ご自身で手を入れられる自信があるなら、フレームワークOKだと思います(他人の書いたソースコードの問題に対してパッチがあてられるなら)。
もし、よくわからない・・・ということであれば、まずは自前で簡易なものからきちんと作るのがよいでしょう。結果として、フレームワークの中身もわかるようになるはずです。
なお、可能であれば、ある程度スキルのある方に、相談やレビューをしながら、進められるのがよいかと思います。先人たちはいろいろな経験をしていますので、気づかないような所に、アドバイスをくれたりします。
投稿2016/05/04 08:09
編集2016/05/04 08:17総合スコア1283
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/05/04 09:16
0
認証の脆弱性とサーバの脆弱性を同一の質問でされているので回答しにくいですがまとめられた部分に対して回答します。
・可能な限り外部ライブラリを使わずに自作したい
「自分でできる部分はライブラリを使わない」をモットーにされているのであれば、自作すればよいです。ただし、複数個の有名ライブラリを読み理解する必要はあると思いますが。ライブラリを使用するにしてもそこは変わらないので自作すればいいと思います。
・ログインシステムは自作してもよいのか(ダメならオープンソース等教えてください)
上でも書きましたが、自作してもイイと思います。ただし、オープンなライブラリはその分使用者が多いので先人の知恵が詰まっているとは思いますが。故にライブラリはいくつか読み理解しておく方がイイでしょう。git見ればいくらでもサンプルあるし。
・脆弱性を生まないためにはどうすればよいのか(参考サイト/書籍を教えてください)
IPAが参考になると思います。
認証の脆弱性・・・突破されると認証を必要とするサイトのコンテンツにアクセスされる。
サーバの脆弱性・・・突破されると踏み台にされたり、個人情報を抜かれたり。
投稿2016/05/04 08:23
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/05/04 09:26
退会済みユーザー
2016/05/04 10:20
2016/05/04 14:10
0
セキュリティー上の問題がないものを自作するのは困難です。
でも、一度は自分で認証システムを作ってみることは無駄ではありません。
↓のような意見があります。
- Ruby on Rails チュートリアル http://railstutorial.jp/chapters/modeling_users?version=4.2#cha-modeling_users からの引用
...
コラム6.1では、最初に少なくとも一度は自分で認証システムを作ってみることをお勧めする理由について説明しています。コラム6.1 自分で認証システムを作ってみる
事実上、すべてのWebアプリケーションは何らかのログイン/認証システムを必要とします。そのため、多くのWebフレームワークではこのようなログイン/認証システムを実装するための選択肢が多数提供されています。Railsもまた例外ではありません。認証 (authentication) と認可 (authorization) のシステムの例だと、Clearance、Authlogic、Devise、CanCanなどがあります (Railsに限らなければOpenIDやOAuthの上に構築する方法もあります)。なぜ車輪の再発明をするのか、という質問があるのも当然です。自分でわざわざ作らなくても、いつも使える方法をただ利用するだけではいけないのでしょうか。
ある実践的な実験によると、多くのサイトの認証システムは膨大なカスタマイズを必要とするため、サードパーティ製品を変更して導入する場合にはシステムをゼロから作成するよりも多くの仕事を要するという結果が出ています。加えて、既成品のシステムは内部がわかりづらいことが多く、ブラックボックスになっています。自分で作成したシステムであれば、それをとてもよく理解しているはずです。さらに言えば、最近のRailsへの変更 (6.3) により、カスタム認証システムを容易に作成できるようになりました。最後に、あえて最終的にサードパーティの認証システムを導入することになったとしても、自分自身で認証システムを構築した経験があれば、サードパーティ製品を理解して変更することがずっと容易になるはずです。
...
脆弱性については IPA サイトの資料が参考になります。(↓以外にも多数の資料があります)
- 安全なウェブサイトの作り方 https://www.ipa.go.jp/security/vuln/websecurity.html
こんなツールもあります。
- OWASP ZAP ~ フリーの Web アプリケーション脆弱性診断ツール https://www.websec-room.com/2013/04/06/835
投稿2016/05/05 11:47
総合スコア22324
0
おすすめのサイトや書籍を読んだだけで安全なシステムが作れると思っているのでしたら
既存のシステムを使おうが自前で作ろうが安全なシステム等つくれることは絶対無いので
どうせ欠陥があるなら勉強しなくて良い分、既存システムの方がマシといった感じです。
投稿2016/05/04 08:45
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2016/05/04 09:00
2016/05/04 09:30
0
・SSLにしてリクエストを暗号化する。
・ワンタイムパスワードを自作する。
をすれば、かなり堅牢なWEBサービスになるとは思うけど、
SSLはお金かかるし、ワンタイムパスワード自作はかなり大変。
逆にお手軽な手法としては、
ユーザ個別のサービス提供ではなく、
セキュリティだけのためにログインさせたいのであれば、
Basic認証だけで、毎月とか毎週id/passを変えていくというやり方もあります。
100%のセキュリティ確保というのは不可能なので、
持って行かれて困るものは極力サーバに置かない
という対応方針が良いかと思います。
また、WEBアプリにログイン認証を入れるのであれば、
GETではなくPOSTで対応されることをお忘れなく。
投稿2016/05/04 07:58
総合スコア1124
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/05/04 09:04
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。