2021-04-04に更新

Excel 内のハイパーリンクを踏むと IE 扱いされる

読了目安:10分

Excel 内のハイパーリンクを踏むと、 Chrome で開いているのに IE 扱いされる現象に遭遇しました。

現象

上述の通りですが、

  1. Excel の中でオレオレ証明書の https 始まりのハイパーリンクを設定する
  2. 1.のハイパーリンクを開く

とすると、 .htaccess でユーザエージェントで IE のみリダイレクトして専用ページを開く仕掛けが発動してしまいました。……実際ページを開いているブラウザは Chrome や Vivaldi なのに……。

検証

この現象について少し調べてみました。

試しに、以下のような アクセス元のユーザエージェント + HTTPメソッド を log/test.log というファイルに追記していく PHPコード を作成し、ここに 各Office製品 からハイパーリンク越しでアクセスしてみました。

<?php
$requestHeaders = apache_request_headers();
unset($requestHeaders['Cookie']);
$requestHeaders['Method'] = $_SERVER['REQUEST_METHOD'];
$str = '';
$log = '';
foreach ($requestHeaders as $key => $value) {
    $str .= $key . ': ' . $value . "\n";
}
if(array_key_exists('User-Agent', $requestHeaders)) {
    $log .= 'User-Agent: ' . $requestHeaders['User-Agent'];
}
if(array_key_exists('Accept', $requestHeaders)) {
    $log .= ', Accept: ' . $requestHeaders['Accept'];
}
if(array_key_exists('Referer', $requestHeaders)) {
    $log .= ', Referer: ' . $requestHeaders['Referer'];
}
if(array_key_exists('Method', $requestHeaders)) {
    $log .= ', Method: ' . $requestHeaders['Method'];
}
$log .= ';';
$filepath = __DIR__ . '/log/test.log';
$current = '';
if(file_exists($filepath)) {
    $current = file_get_contents($filepath);
    $current .= "\n\n" . $log;
}
else {
    $current = $log;
}
file_put_contents($filepath, $current);
?>
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div style="padding: 1rem; margin: 1rem;">
        <textarea name="header" id="header" cols="100" rows="20"><?= $str; ?></textarea>
    </div>
    <div style="padding: 1rem; margin: 1rem;">
        <textarea name="ua" id="ua" cols="100" rows="20"></textarea>
    </div>
    <script>
        const ua = navigator.userAgent.toLowerCase();
        const ver = navigator.appVersion.toLowerCase();
        const $ua = document.querySelector('#ua');
        $ua.textContent = `UA: ${ua}
VERSION: ${ver}
`;
    </script>
</body>
</html>

検証結果

Excel 2016 (httpsリンク、オレオレ証明書)

User-Agent: Microsoft Office Protocol Discovery, Method: OPTIONS;

User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; ms-office), Accept: */*, Method: GET;

User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.186 Safari/537.36, Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9, Method: GET;

最後のユーザエージェントは Chrome のものなので問題ないのですが、問題はその前。

  1. OPTIONSメソッド で Microsoft Office Protocol Discovery なるユーザエージェントでリクエストが飛んでくる
  2. GETメソッド で MSIETrident を含む (今回はこの2つで IE 判定をしていた) IE のようなユーザエージェントでリクエストが飛んでくる
  3. Chrome 本体のリクエスト

という順番のようです。特に2番目。 IE そのものとはまた異なりますが、 IE と判定されそうな文字列を含むユーザエージェントです。これによりリダイレクト判定に引っかかり、リダイレクトした後の URL が Chrome に渡されるため、「 IE 扱いされた」挙動となったようです。

……何故こんなことに……。

Excel からオレオレ証明書のhttpsリンクを開こうとすると表示されるポップアップ

Excel からオレオレ証明書のhttpsリンクを開こうとすると表示されるポップアップ

ちなみに。

Excel 2016 (httpリンク)

User-Agent: Microsoft Office Excel 2014, Method: HEAD;

User-Agent: Mozilla/4.0 (compatible; ms-office), Accept: */*, Method: GET;

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36, Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9, Method: GET;

こちらは MSIETrident といった文字列がユーザエージェントに出てこないため、 Chrome で正常に表示ができました。

ちなみに、本来のブラウザのアクセス前に飛ぶリクエストも OPTIONSメソッド ではなく HEADメソッド で飛んできています。

Word 2016 (https, http)

User-Agent: Microsoft Office Word 2014, Method: HEAD;

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36, Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9, Method: GET;

Word 2016 については httpリンク の Excel と同様 MSIETrident といった文字列がユーザエージェントに出てきませんでした。

Word からオレオレ証明書のhttpsリンクを開こうとすると表示されるポップアップ

Word からオレオレ証明書のhttpsリンクを開こうとすると表示されるポップアップ

Excel 2013 (httpsリンク、オレオレ証明書)

User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; Tablet PC 2.0; ms-office), Accept: */*, Method: GET;

User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.116 Safari/537.36, Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9, Method: GET;

Excel 2013 だと OPTIONSメソッド が見当たりません。ただ、 MSIETrident が含まれているのは確認できます。

Excel 2013 (httpリンク)

User-Agent: Microsoft Office Excel 2013 (15.0.5319) Windows NT 10.0, Method: HEAD;

User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.116 Safari/537.36, Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9, Method: GET;

こちらは 2016 と変わらなそうです。

Word 2013 (httpsリンク、オレオレ証明書)

User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; Tablet PC 2.0; ms-office), Accept: */*, Method: GET;

User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.116 Safari/537.36, Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9, Method: GET;

Word 2013 はなんと Excel 2013 と同じ結果に。これだと MSIETrident が含まれています。

Excel 2013 (httpリンク)

User-Agent: Microsoft Office Word 2013 (15.0.5319) Windows NT 10.0, Method: HEAD;

User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; Tablet PC 2.0; ms-office), Accept: */*, Method: GET;

User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.116 Safari/537.36, Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9, Method: GET;

さらに Word 2013 で httpリンク の場合、 HEADメソッドが飛ぶのは Excel2013 と同様ですが、その後に MSIETrident を含む GETリクエストが飛んでいます。

これだとユーザーエージェント判定で引っかかることになりますね……。


手元の環境では、同じ Office製品 でもバージョンで挙動が異なるというかなり困った結果が得られてしまいました……。

Office製品 からのハイパーリンクを気にすることはほとんどないとは思うのですが、このような事象もあるということでメモしておきます。

参考

Originally published at labor.ewigleere.net
ツイッターでシェア
みんなに共有、忘れないようにメモ

arm-band

フロントエンド・バックエンド・サーバエンジニア。LAMPやNodeからWP、Gulpを使ってejs,Scss,JSのコーディングまで一通り。たまにRasPiで遊んだり、趣味で開発したり。

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント