A Japanese Health Insurance Society Web Site Kosmo Communication Web Vulnerable to POODLE

Every Japanese company has its own health insurance society for employees and some IT vendors provide cloud services that naturally contains employee’s sensitive personal information, such as when you are prescribed medicine in which pharmacy.

One of such self service health insurance web portals is still vulnerable to POODLE attack found four years ago. The web portal, called Kosmo Communication Web, is provided by Daiwa Institute of Research Business Innovation, affiliate of Daiwa Securities.

Why I found this web site is vulnerable? That’s because I’m a user of this sevice. I’m working for the company, listed on Tokyo Stock Exchange first section, which is using this cloud service.

The English promotion page of Kosmo Communication Web doesn’t provide useful information while Japaneses page says more than four hundreds Japanese companies uses this cloud service to manage their employees medical history.

When you search the keywords “Kosmo web”, you will find several Japanese large companies use this cloud sevice.

This service doesn’t provide option of two factor authentication for employees to protect their sensitive data. However, the data processor Daiwa Institute of Research Business Innovation is certified with ISO27001 and provides several services concerning securities, banking and asset management.

My company doesn’t allow employees to stop processing their sensitive data on this service and didn’t request employees consents before implementing this cloud service.

This is one example of processing personal sensitive data in Japanese large companies.

When Your Android Phone App Doesn’t Work, Just Install GApps Again

If you unlock your Android phone and install custom ROM and some basic Google apps don’t work properly, just reinstall GApps in recovery mode.

The Open GApps Project

In my case Google standard phone app can make a call but cannot hang up because the calling mode screen doesn’t appear, so the only choice is restarting phone. In addition, it cannot answer any call because the screen doesn’t switch to answering mode.

So I reboot to TWRP recovery, wipe nothing and just reinstall GApps stock version. After rebooting, everything OK. No need to set up Google account or other Android settings.

Google Chromeのディベロッパーツールをカスタマイズする方法のメモ

Google ChromeでWindowsのディベロッパーツールに独自のタブ(パネル)を追加できると最近知ったので備忘のために書いておく。

Google Chrome拡張機能として作成する。

最低限のmanifest.jsonファイルは以下のとおり。permissionは、この拡張機能を実行させたいWebサイトのURLを指定する。

{
	"manifest_version": 2,
	"name": "Hoge Hoge",
	"version": "1.0",
	"devtools_page": "devtools.html",
	"permissions": [
		"https://hogehoge.com/*"
	],
	"icons" : {
		"128": "icon.png"
	}
}

ポイントはdevtools_pageにHTMLファイルを指定すること。このHTMLファイルはmanifest.json他のファイルを同じフォルダに、テキストエディタでいいので新規作成する。ファイル名は何でもいい。ここでは分かりやすくdevtools.htmlという名前にした。

そしてそのdevtools.htmlの中身は以下のとおり。

<!doctype html>
<html>
  <head>
    <script src="./devtools.js"></script>
  </head>
  <body>
  </body>
</html>

何もしていない。ただ同じフォルダにあるdevtools.jsというJavaScriptを呼び出しているだけ。名前はdevtools.jsでなくてもいいが分かりやすいようにこうしておく。

そのdevtools.jsの中身で、パネルを作成することになる。

chrome.devtools.panels.create(  
	"HogeHogePanel",
	"", // icon画像を指定できる
	"./panel.html",
	(panel) => {} // callback
);

このJavaScriptはGoogleディベロッパーツールのElements、Console、Sources、Network等々のタブ(パネル)に、自分の好きなパネルを追加している。

chrome.devtoolsというのはGoogleが提供しているGoogleディベロッパーツールAPIで、Google拡張機能からはすでに存在するオブジェクトとしていつでも呼び出せる。

ここではchrome.devtools.panelsのcreateメソッドを呼び出して、Elements、Console、Sources、Network等々のパネルに、もう1枚パネルを新規作成している。

1つ目の引数がパネルのタイトル。ElementsパネルならElements、ConsoleパネルならConsoleにあたる名前。好きな名前をつければいい。ここではHogeHogePanelという名前にした。
2つ目はアイコンを指定できるが、なくていい。
3つ目がポイント。この拡張機能のフォルダ内に、テキストエディタでも何でも良いのでpanel.htmlというHTMLファイルを作成して指定すればいい。ファイル名はpanel.htmlでなくても何でもいい。
4つ目はコールバック関数の指定だが、筆者は何に使うのか分からなかった。指定なしでもここから書くことは実現できる。

ではそのpanel.htmlには何を書けばいいか。

<!DOCTYPE html>  
<html>  
  <body>
    <div id="container"></div>
    <script src="./panel.js"></script>
  </body>
</html>

このHTMLも基本的にpanel.jsというJavaScriptを呼び出しているだけ。中身は用途によっていろいろだが、ここではpanel.jsの実行結果をこのHTMLに動的に表示させたいので、そのためのコンテナとしてdivタグでcontainerというidの容れ物を作っておくことにする。

ここまでで準備ができた。Googleディベロッパーツールに独自に追加したHogeHogePanelというパネルに、このpanel.htmlが表示され、panel.jsの実行結果をcontainerにJavaScriptで動的に書き込めば、panel.jsの実行結果を動的に確認できるパネルが出来上がる。

あとはpanel.jsにやりたいことをひたすらコーディングしていく。

たとえばブラウザで読み込んだページが、WebサーバにGETメソッドで要求しているデータのURLをすべて列挙する、ネットワークアナライザ的なことがやりたけれは、chrome.devtools.networkというオブジェクトのonRequestFinishedメッソドを使って以下のように書けばいいらしい。

chrome.devtools.network.onRequestFinished.addListener(
	function(request) {
		var geturl = request.request.url;
	}
);

処理はWebページを読み込みつつ非同期で実行されるので、Webサイトへのデータ要求が終わるたびに関数が呼び出されるように、addListenerでリスナーを追加、そのリスナーの中にonRequestFinished、つまりデータ要求が終わるごとに呼び出される関数を書く。

その関数にはデータ要求の結果、戻ってきたデータがrequestオブジェクトとして渡されるので、それを引数にして、無名関数として記述する。 function(request)の部分がそれにあたる。

あとはこのrequestオブジェクトにたくさんある属性の中から、取り出したいデータを取れば良い。

ここでは戻ってきたデータの中に含まれるURLリンクアドレスを取り出したいので、request.request.urlとし、アドレスの文字列をgetrulという変数に代入している。(geturlという変数名は適当に付けただけなので、何でもいい)

Google ChromeがWebサーバに要求しているURLを列挙して何がうれしいのかというと、Google ChromeでWebページを表示させた時に表面上見えているデータ以外に、裏側でそのWebページがWebサーバに要求しているデータのURLアドレスを取り出せるから。

WebページはWebサーバからもどってきたデータをそのまま表示せずに、いったんJavaScript等で加工してからWebページを組み立てて表示させていることがほとんどだが、裏側で要求しているデータを生のままつかまえたい場合は、この方法が役立つ。

panel.jsの中身を地道にコーディングして、処理結果をpanel.htmlに表示するようにできれば、あとは目的のWebページを開いて、かつGoogleディベロッパーツールの画面を、WindowsならCtrl+Shift+Iで表示させればいいだけ。

そうするといちばん右側に、自分の作った「HogeHogePanel」というタブでパネルが追加されている。そのパネルはpanel.htmlなので、そこに自分の欲しいデータが書き出される。

ただ、じゃあpanel.jsがうまく動いているかどうかは、どうやってデバッグすればいいの?という話になるが、それもGoogleディベロッパーツールを使えばいい。

自分が新規作成したHogeHogePanelの動作を確かめるために、そのパネルを表示させた状態で、再びCtrl+Shift+Iを押すと、もう一つGoogleディベロッパーツールが開く。

この2つ目のGoogleディベロッパーツールは、最初に開いたWebページではなく、自分が作ったHogeHogePanelに対するGoogleディベロッパーツールなので、panel.jsに何かエラーがあれば、こちらの2つ目のGoogleディベロッパーツールのConsoleタブにエラー表示される。

なので二重に開いた2つ目のGoogleディベロッパーツールのConsoleタブを見ながら、panel.jsをデバッグできる。

…といったことができるのを、つい最近知った。

VLC media player cannot play some URLs of YouTube movies

VLC media player forum provides a solution for this problem, that’s to copy an updated youtube.lua file to /VideoLAN/VLC/lua/playlist/. However, this doesn’t solve the problem any more in March 2018.

If you get the error message containing word “MRL”, the true solution is to change configurations of Windows firewall.

In case of Windows 7/10, go to advanced settings of Windows firewall and change both of Inbound rules and Outbound rules of all “VLC media player” profiles into “Enabled=Yes” and “Action=Allow”. This means every profile of VLC media player will be turned into green.

顔認識ウェブAPI「Face++」をPHPで使ってみる

無償で使える顔認識Webサービスがあることを最近知ったのでPHPの実装とともにメモ。

https://www.faceplusplus.com/

API KEY、API SECRETの取得方法はウェブで検索すれば見つかる。


define("REQUEST_URL", "https://api-us.faceplusplus.com/facepp/v3/detect");

// ローカルの画像をアップロードするためのパラメータに変換
$cfile = curl_file_create($local_imgpath, 'image/jpeg');

// return_attributesパラメータはカンマ区切りで複数指定できる。ここでは性別だけ。
// api_key, api_secretは自分で取得した文字列に置き換えること
$params = array(
'api_key' => 'xxxxxxxxxxxxxxxxxxxxxxxxxx',
'api_secret' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx',
'image_file' => $cfile,
'return_attributes' => 'gender',
);

$curl = curl_init();
curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: multipart/form-data'));
curl_setopt($curl, CURLOPT_URL, REQUEST_URL);
curl_setopt($curl, CURLOPT_POSTFIELDS, $params);
curl_setopt($curl, CURLOPT_HEADER, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER , FALSE);
curl_setopt($curl, CURLOPT_RETURNTRANSFER , TRUE);
curl_setopt($curl, CURLOPT_TIMEOUT , 15);

$res1 = curl_exec($curl);
$res2 = curl_getinfo($curl);
curl_close($curl);

$json = substr($res1, $res2['header_size']);

// PHPの場合はJSONを連想配列に変換するとやりやすい
$face_data = json_decode($json, TRUE);

// これが検出された複数の顔のデータ
$faces = $face_data["faces"];

// 検出されたときだけ顔データを1つずつ見てみる
if (isset($faces)) {
foreach ($faces as $face) {

$gender = $face["attributes"]["gender"]["value"]; // 性別
$width = $face["face_rectangle"]["width"]; // 幅
$height = $face["face_rectangle"]["height"]; // 高さ
$top = $face["face_rectangle"]["top"]; // 上端
$left = $face["face_rectangle"]["left"]; // 左端

// デバッグのために検出された顔データを表示してみる
echo "DETECTED [$gender] $width x $height ($top, $left) ";

}
}