2019年 2月 の投稿一覧

[時事] 自動運転ソフトウェアのチェックがお役所すぎる問題

こちらのニュースが話題になってますね。

国土交通省は、自動車メーカーが車に搭載されたシステムのプログラムを更新する場合、国の許可制とする方針を固めた。今後、自動運転技術による高速道路での車線変更といったプログラムの更新が想定されるため、国が事前に安全性を確認できるようにする。今年3月にも、開会中の通常国会に道路運送車両法の改正案を提出し、2020年の施行を目指す。

個人的に何かしらのチェック機構は法整備も含めて必要だと思ってます。
実際に自動車の制御プログラムのセキュリティチェックなどを依頼されている企業の方と会議をする機会があり、割と簡単にハッキング出来て勝手に動かすことができるというエピソードを耳にしました。こういった脆弱性や何かしら内部の人間が悪意を持ったコードを埋め込む可能性が今後出てくる可能性は非常に高いと思います。

クルマがネットワークにつながり、それらの情報をモトに制御される未来がやってくると、命に関わるリスクが高まると言わざるを得ません。特に自動制御プログラムが乗っ取られた日には、大量の自動車を同時に操作した自爆テロなどハリウッド映画的な展開が現実の物になることが簡単に想像できます。そこまで行かなくてもGPSなどと連動すれば位置情報などプライベートな情報も抜き放題です。

それら悪意のあるコードが混入しやすいのは新車として購入する段階よりも、運用フェーズに入ってからだろうと考えればこの対策は当然と言えば当然かもしれません。

続きを読む

[サーバ] お行儀の悪いアタック国ランキング

前回の続きです。
狙われやすいアカウント名ランキングに続きまして、どこの国からアタックを受けているかも調査してみました。…まぁなんとなく結果はわかっていましたが、数値化するのが大事ですよね!(虚空を見つめがら)

結果発表

IPアドレス単位

#カウントIPアドレス国CD国名
143,148218.92.1.163CN中国
243,14758.242.83.7CN中国
343,147218.92.1.174CN中国
443,147218.92.1.173CN中国
531,139112.85.42.196CN中国
627,063218.92.1.181CN中国
721,800112.85.42.238CN中国
820,223112.85.42.197CN中国
913,908218.92.1.172CN中国
1010,678112.85.42.232CN中国
119,605112.85.42.233CN中国
128,584112.85.42.151CN中国
136,73558.242.83.17CN中国
146,666193.201.224.216UAウクライナ共和国
153,559122.194.229.49CN中国
163,359112.85.42.231CN中国
173,228112.85.42.193CN中国
182,558101.91.215.199CN中国
192,548101.91.215.80CN中国
201,818188.92.77.235LVラトビア共和国
211,505122.194.229.18CN中国
221,483106.13.34.94CN中国
231,209188.92.75.248LVラトビア共和国
2498059.46.135.42CN中国
25828146.0.228.106DEドイツ連邦共和国
26719206.189.149.126SGシンガポール
27606112.85.42.235CN中国
2857554.169.36.191SGシンガポール
29408185.246.128.25SEスウェーデン王国
30402103.207.38.197VNベトナム

国単位

#行ラベル合計 / カウント割合
1中国353,34187.5079%
2アメリカ合衆国8,1282.0130%
3ウクライナ共和国6,9391.7185%
4フランス共和国4,7291.1712%
5ラトビア共和国3,0390.7526%
6シンガポール2,8930.7165%
7ドイツ連邦共和国2,2700.5622%
8インド1,9750.4891%
9ロシア1,6290.4034%
10大韓民国1,5040.3725%
11ブラジル連邦共和国1,4430.3574%
12イギリス1,3460.3333%
13オランダ王国1,1760.2912%
14カナダ9220.2283%
15ベトナム8990.2226%
16インドネシア共和国8570.2122%
17イタリア共和国6880.1704%
18ポーランド共和国6340.1570%
19コロンビア共和国6260.1550%
20スウェーデン王国5250.1300%
21日本4940.1223%
22メキシコ合衆国4830.1196%
23香港4450.1102%
24中華民国4410.1092%
25アルゼンチン共和国4280.1060%
26タイ王国3880.0961%
27スペイン2760.0684%
28イラン・イスラム共和国2220.0550%
29南アフリカ2150.0532%
30マレーシア2110.0523%

結論

中国からのアクセスをブロックすれば80%以上のアタックを防げる結果になりました\(^o^)/

ちなみに日本からのアタックは494件、0.1223%でした。
続きを読む

[サーバ] 狙われやすいアカウント名ランキング8000

専門学校の生徒用にAWS(Lightsail)でサーバを一台用意しているのですが、(乗っ取られてはいない物の)意図せずハニーポット状態になっていたので、どのアカウント名が狙われていたか軽く集計してみました。

前提

サーバ自体は2018年12月16日に立ち上げたのですが、現存する最古のデータが1月6日となっていたためざっくり1ヶ月間(27日程度)のデータと思っていただければと。

この間の/var/log/secureを集計すると約45万件のアタックを受けていた計算になります。

$ sudo grep -c 'Failed' /var/log/secure*
/var/log/secure:18982
/var/log/secure-20190113:127392
/var/log/secure-20190120:46130
/var/log/secure-20190127:132703
/var/log/secure-20190203:78543

403,750件

$ sudo grep -c 'Invalid' /var/log/secure*
/var/log/secure:1849
/var/log/secure-20190113:10378
/var/log/secure-20190120:11506
/var/log/secure-20190127:9932
/var/log/secure-20190203:14927

48,592件

続きを読む

[Firebase] Authenticationでメール認証 (Web編) その3

第1回はメールアドレスとパスワードによる認証、第2回はメールアドレス宛にメールを送信し文中のURLをクリックするとログイン状態になる機能の実装に挑戦しました。

今回は次のような仕組みに挑戦してみます。

  1. メールアドレスとパスワードを入力しログイン
  2. ログイン後、メールアドレスの認証が終わってなければ確認メール送信
  3. 確認メール内にあるURLをクリックするとメールアドレスの認証完了

メールアドレスの確認

コンソールの設定

第1回で行った、以下の設定が必要です。「Authentication」から「ログイン方法」タブに移動し「メール/パスワード」を有効にしてください。

JSで認証処理

/js/config.js

共通処理を書いておくJSです。
第2回と全く同じです。

//----------------------------------------------
// Firebaseの初期化
//----------------------------------------------
// コンソールの内容をそのままコピペ
var config = {
  apiKey: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  authDomain: "test-f76bc.firebaseapp.com",
  databaseURL: "https://test-f76bc.firebaseio.com",
  projectId: "test-f76bc",
  storageBucket: "test-f76bc.appspot.com",
  messagingSenderId: "00000000000"
};
firebase.initializeApp(config);

//----------------------------------------------
// ドメインとポート番号
//----------------------------------------------
let domain = document.domain;
let port   = (domain === 'localhost')?  5000:80;

/auth/mail2/index.html

ユーザーが最初にアクセスするログイン画面です。
こちらは第1回で使用した設定用JSONに戻しました。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Hello Firebase Auth</title>
  <link type="text/css" rel="stylesheet" href="https://cdn.firebase.com/libs/firebaseui/3.5.2/firebaseui.css" />
  <style>h1{text-align: center;}</style>
</head>
<body>
  <h1>Hello Firebase Auth</h1>
  <div id="firebaseui-auth-container"></div>

  <script src="https://www.gstatic.com/firebasejs/5.8.1/firebase-app.js"></script>
  <script src="https://www.gstatic.com/firebasejs/5.8.1/firebase-auth.js"></script>
  <script src="https://www.gstatic.com/firebasejs/ui/3.5.2/firebase-ui-auth__ja.js"></script>
  <script src="/js/config.js"></script>
  <script>
    //----------------------------------------------
    // Firebase UIの設定
    //----------------------------------------------
    var uiConfig = {
        // ログイン完了時のリダイレクト先
        signInSuccessUrl: '/auth/mail2/done.html',

        // 利用する認証機能
        signInOptions: [
          firebase.auth.EmailAuthProvider.PROVIDER_ID  //メール認証
        ],

        // 利用規約のURL(任意で設定)
        tosUrl: 'http://example.com/kiyaku/',
        // プライバシーポリシーのURL(任意で設定)
        privacyPolicyUrl: 'http://example.com/privacy'
      };

      var ui = new firebaseui.auth.AuthUI(firebase.auth());
      ui.start('#firebaseui-auth-container', uiConfig);
  </script>
</body>
</html>

/auth/mail2/done.html

今回の話のメインはこちらですね。
ログイン時に渡されるオブジェクトのuser.emailVerifiedfalseであればまだメールアドレスの確認が行われていないことになります。その場合にuser.sendEmailVerification()メソッドを使用し、メールアドレス宛に確認メールを送信しています。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Hello Firebase Auth</title>
</head>
<body>
  <h1>...Please wait</h1>
  <div id="info"></div>

  <script src="https://www.gstatic.com/firebasejs/5.8.1/firebase-app.js"></script>
  <script src="https://www.gstatic.com/firebasejs/5.8.1/firebase-auth.js"></script>
  <script src="/js/config.js"></script>
  <script>
    firebase.auth().onAuthStateChanged( (user) => {
      console.log(user);

      //------------------------------------
      // 未ログイン状態で訪れた場合
      //------------------------------------
      if(user === null){
        showMessage('Not Login', 'ログインが必要な画面です');
        return(false);
      }

      //------------------------------------
      // メアド確認済み
      //------------------------------------
      if( user.emailVerified ) {
        showMessage('Login Complete!', `${user.displayName}さんがログインしました`);
      }
      //------------------------------------
      // メアド未確認
      //------------------------------------
      else {
        user.sendEmailVerification()
          .then(()=>{
            showMessage('Send confirm mail', `${user.email}宛に確認メールを送信しました`);
          })
          .catch((error)=>{
            showMessage('[Error] Can not send mail', `${user.email}宛に確認メールを送信できませんでした: ${error}`);
          });
      }
    });

    function showMessage(title, msg) {
      document.querySelector('h1').innerText    = title;
      document.querySelector('#info').innerHTML = msg;
    }
  </script>
</body>
</html>

実行結果

クリックするとサンプルコードが実行できます。お試し登録やログインなどどうぞ。自分以外のメアドを入れたり悪いことしないでくださいね。(登録された内容は適当なタイミングで削除します)

done.htmlで送信されたメール内のURLをクリックすると、デフォルトで用意されているメールアドレスの確認ページが表示され、user.emailVerifiedの値がそれ以降trueに変化します。もう一度ログインを行うと今度は確認メールが送信されず、ログインが完了した旨が表示されれば成功です。

その他

メールの文面を変更する

デフォルトの確認メールの文面は中々怪しさに溢れているので、Web画面の開発が一段落したらこちらの文面も差し替えた方が良いでしょう。

コンソールの「Authentication」から「テンプレート」タブにアクセスするとカスタマイズができます。

確認ページから遷移させる

メール内のURLをクリックすると以下のような簡単な画面が表示されます。
これだけだと次のアクションをどうすればよいかユーザーが混乱しますので、実際には次のページへ遷移するためのボタンなどを置いた方がユーザーフレンドリーです。

というわけで、done.htmlのコードを修正しました。
sendEmailVerification()に引数として設定用のJSONを渡しています。変数domainportの値はconfig.jsで作成しています。

  actionCodeSettings = {
    url: `http://${domain}:${port}/auth/mail2/done.html`
  };
  user.sendEmailVerification(actionCodeSettings)

このコードを実行すると、今度は以下のように「続行」ボタンが表示されましたね。

なおここで指定するURLのドメインはホワイトリストに登録されている必要があるのでご注意を。
コンソールにログインしたら「Authentication」内の「ログイン方法」タブをクリックし「承認済みドメイン」の項目の右側にある「ドメインの追加」ボタンから設定します。

参考ページ


[Firebase] Authenticationでメール認証 (Web編) その2

前回はメールアドレスとパスワードによる認証でしたが、今回は入力されたメールアドレスにメールを送信し届いたURLをクリックしたらログイン状態になる「メールリンク認証」の実装をします。

メールリンク認証

入力されたメールアドレス宛に確認メールを送り、中のURLをクリックしてログイン状態となるこの仕組をFirebaseでは「メールリンク認証」という言葉を用います。メールリンク認証ではパスワードも求められません。

コンソール上の設定

「Authentication」の「ログイン方法」内にある「メール / パスワード」の項目を開き、「メールリンク」を有効にするにし、保存ボタンをクリックします。

認証部分をJSで書く

/js/config.js

ドメインとポート番号の設定を加えましたが、前回と一緒です。

//----------------------------------------------
// Firebaseの初期化
//----------------------------------------------
// コンソールの内容をそのままコピペ
var config = {
  apiKey: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  authDomain: "test-f76bc.firebaseapp.com",
  databaseURL: "https://test-f76bc.firebaseio.com",
  projectId: "test-f76bc",
  storageBucket: "test-f76bc.appspot.com",
  messagingSenderId: "00000000000"
};
firebase.initializeApp(config);

//----------------------------------------------
// ドメインとポート番号
//----------------------------------------------
let domain = document.domain;
let port   = (domain === 'localhost')?  5000:80;

/auth/mail/index.html

メインはこちらですが、JSONの値を変更しただけですねw forceSameDeviceはメールソフトのURLをクリックした際に同じデバイスであることを要求するかどうかのフラグです。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Hello Firebase Auth</title>
  <link type="text/css" rel="stylesheet" href="https://cdn.firebase.com/libs/firebaseui/3.5.2/firebaseui.css" />
  <style>h1{text-align: center;}</style>
</head>
<body>
  <h1>Hello Firebase Auth</h1>
  <div id="firebaseui-auth-container"></div>

  <script src="https://www.gstatic.com/firebasejs/5.8.1/firebase-app.js"></script>
  <script src="https://www.gstatic.com/firebasejs/5.8.1/firebase-auth.js"></script>
  <script src="https://www.gstatic.com/firebasejs/ui/3.5.2/firebase-ui-auth__ja.js"></script>
  <script src="/js/config.js"></script>
  <script>
    //----------------------------------------------
    // Firebase UIの設定
    //----------------------------------------------
    var uiConfig = {
        // ログイン完了時のリダイレクト先
        signInSuccessUrl: '/auth/mail/done.html',

        // 利用する認証機能
        signInOptions: [
          {
            provider: firebase.auth.EmailAuthProvider.PROVIDER_ID,
            signInMethod: firebase.auth.EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD,
            forceSameDevice: false
          }
        ],

        // 利用規約のURL(任意で設定)
        tosUrl: 'http://example.com/kiyaku/',
        // プライバシーポリシーのURL(任意で設定)
        privacyPolicyUrl: 'http://example.com/privacy'
      };

      var ui = new firebaseui.auth.AuthUI(firebase.auth());
      ui.start('#firebaseui-auth-container', uiConfig);
  </script>
</body>
</html>

/auth/mail/done.html

前回とほぼ一緒です。変更点としてはdisplayNameの他にemailemailVerifiedの表示を行っています。今回はユーザー名の入力が入らないためdisplayNameには何も入りません。メールアドレスの認証が完了しているアカウントの場合emailVerifiedtrueになります。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Hello Firebase Auth</title>
</head>
<body>
  <h1>...Please wait</h1>
  <div id="info"></div>

  <script src="https://www.gstatic.com/firebasejs/5.8.1/firebase-app.js"></script>
  <script src="https://www.gstatic.com/firebasejs/5.8.1/firebase-auth.js"></script>
  <script src="/js/config.js"></script>
  <script>
    firebase.auth().onAuthStateChanged( (user) => {
      let h1   = document.querySelector('h1');
      let info = document.querySelector('#info');

      if(user) {
        h1.innerText   = 'Login Complete!';
        info.innerHTML =   `${user.displayName}さんがログインしました`
                         + '<ul>'
                         +   `<li>${user.email}</li>`
                         +   `<li>${user.emailVerified}</li>`
                         + '<ul>';
        console.log(user);
      }
      else {
        h1.innerText = 'Not Login';
      }
    });
  </script>
</body>
</html>

実行結果

クリックするとサンプルコードが実行できます。お試しに登録やログインなどどうぞ。自分以外のメアドを入れたり悪いことしないでくださいね。(登録された内容は適当なタイミングで削除します)


※今回からAWSではなくFirebase Hostingに置くことにしました

この認証方法だと毎回メールを受信してクリックして…というフローをたどるため面倒ですが、確実にメールアドレスの存在確認ができるという点では良い方法かと思います。あとはdisplayNameがほしい場合は自分で入力フォームを作成して、プロフィールの更新用APIを呼び出す形になるかと思います。

その他

独自ドメインで利用する

Firebase Hostingデフォルトのfoo.firebaseapp.comlocalhostで利用するのであれば特に設定はいらないのですが、独自ドメインで認証を行う場合はホワイトリストにドメインを設定しておく必要があります。「Authentication」内の「ログイン方法」タブをクリックし「承認済みドメイン」の項目の右側にある「ドメインの追加」ボタンから設定します。

この設定をしないとDomain not whitelisted by projectというエラーメッセージが表示され、確認メールを送信する処理が実行されません。

メールのテンプレートを変更する?

デフォルトだと以下のようなメールが届くのですがさすがに分かりづらいですね…。怪しさ満点です。

が、執筆時点でこのテンプレートの変更がコンソールを見ても見当たらないんですよね…。その他のパスワード変更やメールアドレスの存在確認用のテンプレはあるのですが。どなたかお分かりになる方がいらっしゃったら教えていただけると!

後日判明したら追記したいと思います。

続き

参考ページ