作品ファイルへの直接アクセス対策について

概要

作品ファイルへの直接アクセスを防ぐことができます。

メディアでの直接アクセス対策は、メディアの閲覧制限についてを参照してください。

詳細

http://www.example.com/freo/index.php/view/15添付ファイルとして登録されたファイルは、http://www.example.com/freo/index.php/file/view/15 から、PHP経由でアクセスできます。

また、http://www.example.com/freo/index.php/page/about に添付ファイルとして登録されたファイルは、http://www.example.com/freo/index.php/file/page/about から、PHP経由でアクセスできます。

つまり、URLに file/ を付加するとPHP経由で添付ファイルにアクセスできます。この方法で添付ファイルにアクセスするとfreoを通してファイルにアクセスされるので、記事の閲覧制限機能も反映されます。(プログラムを経由するので、サーバーへの負荷は少し高くなります。)

その上で、.htaccess などで添付ファイルへのアクセスを禁止しておけば、作品ファイルへの直接アクセスを防ぐことができます。(.htaccess でのアクセス制限は、PHP経由のアクセスが遮断されないため。)

アクセス制限を行う手順

今回、エントリー&ページの添付ファイルとそのサムネイルへは、PHP経由でアクセスされるようにします。ミニ画像はPHP経由でなくてもアクセスできるようにします。以下の手順は、サーバーが .htaccess でのアクセス制限に対応している必要があります。(大抵のサーバーは対応しています。)

まずは .htaccess ファイルを作成し、以下の内容を記述します。(行の最後は改行しておきます。)

Deny from all

これで、このファイルを置いたディレクトリへは、ブラウザ経由でアクセスできなくなります。(templates ディレクトリ内などに格納されている .htaccess を使っても大丈夫です。)

作成した .htaccess を、以下のディレクトリ内にアップロードします。

  • files/entry_files/ (エントリーの添付ファイルを格納するディレクトリ。)
  • files/entry_thumbnails/ (エントリーのサムネイルを格納するディレクトリ。)
  • files/page_files/ (ページの添付ファイルを格納するディレクトリ。)
  • files/page_thumbnails/ (ページのサムネイルを格納するディレクトリ。)

これでエントリーやページの添付ファイルとそのサムネイルにはアクセスできないようになります。(ミニ画像にはアクセスできるようにしています。)実際にブラウザで記事にアクセスし、ファイルが表示されないのを確認してみてください。

あとは、各ファイルを表示する部分のテンプレートを編集して、PHP経由で呼び出されるようにします。

まずは、default/default.html の15行目あたりにある

<!--{if $information_entry.file and $information_entry.image}-->
  <p><a href="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}entry_files/{$information_entry.id}/{$information_entry.file}"><img src="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}entry_images/{$information_entry.id}/{$information_entry.image}" alt="{$information_entry.memo|default:$information_entry.file}" title="{$information_entry.memo|default:$information_entry.file}" width="{$information_entry_image.width}" height="{$information_entry_image.height}" /></a></p>
<!--{elseif $information_entry_thumbnail}-->
  <p><a href="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}entry_files/{$information_entry.id}/{$information_entry.file}"><img src="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}entry_thumbnails/{$information_entry.id}/{$information_entry.file}" alt="{$information_entry.memo|default:$information_entry.file}" title="{$information_entry.memo|default:$information_entry.file}" width="{$information_entry_thumbnail.width}" height="{$information_entry_thumbnail.height}" /></a></p>
<!--{elseif $information_entry.file and $information_entry_file.width and $information_entry_file.height}-->
  <p><img src="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}entry_files/{$information_entry.id}/{$information_entry.file}" alt="{$information_entry.memo|default:$information_entry.file}" title="{$information_entry.memo|default:$information_entry.file}" width="{$information_entry_file.width}" height="{$information_entry_file.height}" /></p>
<!--{elseif $information_entry.file}-->
  <p><a href="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}entry_files/{$information_entry.id}/{$information_entry.file}">{$information_entry.memo|default:$information_entry.file}</a></p>
<!--{/if}-->

この部分を、以下のように変更します。

<!--{if $information_entry.file and $information_entry.image}-->
  <p><a href="{$freo.core.http_file}/file/view/{if $information_entry.code}{$information_entry.code}{else}{$information_entry.id}{/if}.png"><img src="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}entry_images/{$information_entry.id}/{$information_entry.image}" alt="{$information_entry.memo|default:$information_entry.file}" title="{$information_entry.memo|default:$information_entry.file}" width="{$information_entry_image.width}" height="{$information_entry_image.height}" /></a></p>
<!--{elseif $information_entry_thumbnail}-->
  <p><a href="{$freo.core.http_file}/file/view/{if $information_entry.code}{$information_entry.code}{else}{$information_entry.id}{/if}.png"><img src="{$freo.core.http_file}/file/view/{if $information_entry.code}{$information_entry.code}{else}{$information_entry.id}{/if}?type=thumbnail" alt="{$information_entry.memo|default:$information_entry.file}" title="{$information_entry.memo|default:$information_entry.file}" width="{$information_entry_thumbnail.width}" height="{$information_entry_thumbnail.height}" /></a></p>
<!--{elseif $information_entry.file and $information_entry_file.width and $information_entry_file.height}-->
  <p><img src="{$freo.core.http_file}/file/view/{if $information_entry.code}{$information_entry.code}{else}{$information_entry.id}{/if}" alt="{$information_entry.memo|default:$information_entry.file}" title="{$information_entry.memo|default:$information_entry.file}" width="{$information_entry_file.width}" height="{$information_entry_file.height}" /></p>
<!--{elseif $information_entry.file}-->
  <p><a href="{$freo.core.http_file}/file/view/{if $information_entry.code}{$information_entry.code}{else}{$information_entry.id}{/if}">{$information_entry.memo|default:$information_entry.file}</a></p>
<!--{/if}-->

さらに40行目あたりにある

<!--{if $information_page.file and $information_page.image}-->
  <p><a href="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}page_files/{$information_page.id}/{$information_page.file}"><img src="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}page_images/{$information_page.id}/{$information_page.image}" alt="{$information_page.memo|default:$information_page.file}" title="{$information_page.memo|default:$information_page.file}" width="{$information_page_image.width}" height="{$information_page_image.height}" /></a></p>
<!--{elseif $information_page_thumbnail}-->
  <p><a href="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}page_files/{$information_page.id}/{$information_page.file}"><img src="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}page_thumbnails/{$information_page.id}/{$information_page.file}" alt="{$information_page.memo|default:$information_page.file}" title="{$information_page.memo|default:$information_page.file}" width="{$information_page_thumbnail.width}" height="{$information_page_thumbnail.height}" /></a></p>
<!--{elseif $information_page.file and $information_page_file.width and $information_page_file.height}-->
  <p><img src="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}page_files/{$information_page.id}/{$information_page.file}" alt="{$information_page.memo|default:$information_page.file}" title="{$information_page.memo|default:$information_page.file}" width="{$information_page_file.width}" height="{$information_page_file.height}" /></p>
<!--{elseif $information_page.file}-->
  <p><a href="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}page_files/{$information_page.id}/{$information_page.file}">{$information_page.memo|default:$information_page.file}</a></p>
<!--{/if}-->

この部分を、以下のように変更します。

<!--{if $information_page.file and $information_page.image}-->
  <p><a href="{$freo.core.http_file}/file/page/{$information_page.id}.png"><img src="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}page_images/{$information_page.id}/{$information_page.image}" alt="{$information_page.memo|default:$information_page.file}" title="{$information_page.memo|default:$information_page.file}" width="{$information_page_image.width}" height="{$information_page_image.height}" /></a></p>
<!--{elseif $information_page_thumbnail}-->
  <p><a href="{$freo.core.http_file}/file/page/{$information_page.id}.png"><img src="{$freo.core.http_file}/file/page/{$information_page.id}?type=thumbnail" alt="{$information_page.memo|default:$information_page.file}" title="{$information_page.memo|default:$information_page.file}" width="{$information_page_thumbnail.width}" height="{$information_page_thumbnail.height}" /></a></p>
<!--{elseif $information_page.file and $information_page_file.width and $information_page_file.height}-->
  <p><img src="{$freo.core.http_file}/file/page/{$information_page.id}" alt="{$information_page.memo|default:$information_page.file}" title="{$information_page.memo|default:$information_page.file}" width="{$information_page_file.width}" height="{$information_page_file.height}" /></p>
<!--{elseif $information_page.file}-->
  <p><a href="{$freo.core.http_file}/file/page/{$information_page.id}">{$information_page.memo|default:$information_page.file}</a></p>
<!--{/if}-->

さらに100行目あたりにある

<!--{if $entry.file and $entry.image}-->
  <p><a href="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}entry_files/{$entry.id}/{$entry.file}"><img src="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}entry_images/{$entry.id}/{$entry.image}" alt="{$entry.memo|default:$entry.file}" title="{$entry.memo|default:$entry.file}" width="{$entry_images[$entry.id].width}" height="{$entry_images[$entry.id].height}" /></a></p>
<!--{elseif $entry_thumbnails[$entry.id]}-->
  <p><a href="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}entry_files/{$entry.id}/{$entry.file}"><img src="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}entry_thumbnails/{$entry.id}/{$entry.file}" alt="{$entry.memo|default:$entry.file}" title="{$entry.memo|default:$entry.file}" width="{$entry_thumbnails[$entry.id].width}" height="{$entry_thumbnails[$entry.id].height}" /></a></p>
<!--{elseif $entry.file and $entry_files[$entry.id].width and $entry_files[$entry.id].height}-->
  <p><img src="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}entry_files/{$entry.id}/{$entry.file}" alt="{$entry.memo|default:$entry.file}" title="{$entry.memo|default:$entry.file}" width="{$entry_files[$entry.id].width}" height="{$entry_files[$entry.id].height}" /></p>
<!--{elseif $entry.file}-->
  <p><a href="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}entry_files/{$entry.id}/{$entry.file}">{$entry.memo|default:$entry.file}</a></p>
<!--{/if}-->

この部分を、以下のように変更します。

<!--{if $entry.file and $entry.image}-->
  <p><a href="{$freo.core.http_file}/file/view/{if $entry.code}{$entry.code}{else}{$entry.id}{/if}.png"><img src="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}entry_images/{$entry.id}/{$entry.image}" alt="{$entry.memo|default:$entry.file}" title="{$entry.memo|default:$entry.file}" width="{$entry_images[$entry.id].width}" height="{$entry_images[$entry.id].height}" /></a></p>
<!--{elseif $entry_thumbnails[$entry.id]}-->
  <p><a href="{$freo.core.http_file}/file/view/{if $entry.code}{$entry.code}{else}{$entry.id}{/if}.png"><img src="{$freo.core.http_file}/file/view/{if $entry.code}{$entry.code}{else}{$entry.id}{/if}?type=thumbnail" alt="{$entry.memo|default:$entry.file}" title="{$entry.memo|default:$entry.file}" width="{$entry_thumbnails[$entry.id].width}" height="{$entry_thumbnails[$entry.id].height}" /></a></p>
<!--{elseif $entry.file and $entry_files[$entry.id].width and $entry_files[$entry.id].height}-->
  <p><img src="{$freo.core.http_file}/file/view/{if $entry.code}{$entry.code}{else}{$entry.id}{/if}" alt="{$entry.memo|default:$entry.file}" title="{$entry.memo|default:$entry.file}" width="{$entry_files[$entry.id].width}" height="{$entry_files[$entry.id].height}" /></p>
<!--{elseif $entry.file}-->
  <p><a href="{$freo.core.http_file}/file/view/{if $entry.code}{$entry.code}{else}{$entry.id}{/if}">{$entry.memo|default:$entry.file}</a></p>
<!--{/if}-->

それぞれ、hrefsrc の内容を数ヶ所変更しています。

次に、page/default.html の12行目あたりにある

<!--{if $page.file and $page.image}-->
  <p><a href="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}page_files/{$page.id}/{$page.file}"><img src="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}page_images/{$page.id}/{$page.image}" alt="{$page.memo|default:$page.file}" title="{$page.memo|default:$page.file}" width="{$page_image.width}" height="{$page_image.height}" /></a></p>
<!--{elseif $page_thumbnail}-->
  <p><a href="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}page_files/{$page.id}/{$page.file}"><img src="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}page_thumbnails/{$page.id}/{$page.file}" alt="{$page.memo|default:$page.file}" title="{$page.memo|default:$page.file}" width="{$page_thumbnail.width}" height="{$page_thumbnail.height}" /></a></p>
<!--{elseif $page.file and $page_file.width and $page_file.height}-->
  <p><img src="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}page_files/{$page.id}/{$page.file}" alt="{$page.memo|default:$page.file}" title="{$page.memo|default:$page.file}" width="{$page_file.width}" height="{$page_file.height}" /></p>
<!--{elseif $page.file}-->
  <p><a href="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}page_files/{$page.id}/{$page.file}">{$page.memo|default:$page.file}</a></p>
<!--{/if}-->

この部分を、以下のように変更します。

<!--{if $page.file and $page.image}-->
  <p><a href="{$freo.core.http_file}/file/page/{$page.id}.png"><img src="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}page_images/{$page.id}/{$page.image}" alt="{$page.memo|default:$page.file}" title="{$page.memo|default:$page.file}" width="{$page_image.width}" height="{$page_image.height}" /></a></p>
<!--{elseif $page_thumbnail}-->
  <p><a href="{$freo.core.http_file}/file/page/{$page.id}.png"><img src="{$freo.core.http_file}/file/page/{$page.id}?type=thumbnail" alt="{$page.memo|default:$page.file}" title="{$page.memo|default:$page.file}" width="{$page_thumbnail.width}" height="{$page_thumbnail.height}" /></a></p>
<!--{elseif $page.file and $page_file.width and $page_file.height}-->
  <p><img src="{$freo.core.http_file}/file/page/{$page.id}" alt="{$page.memo|default:$page.file}" title="{$page.memo|default:$page.file}" width="{$page_file.width}" height="{$page_file.height}" /></p>
<!--{elseif $page.file}-->
  <p><a href="{$freo.core.http_file}/file/page/{$page.id}">{$page.memo|default:$page.file}</a></p>
<!--{/if}-->

それぞれ、hrefsrc の内容を数ヶ所変更しています。

次に、view/default.html の25行目あたりにある

<!--{if $entry.file and $entry.image}-->
  <p><a href="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}entry_files/{$entry.id}/{$entry.file}"><img src="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}entry_images/{$entry.id}/{$entry.image}" alt="{$entry.memo|default:$entry.file}" title="{$entry.memo|default:$entry.file}" width="{$entry_image.width}" height="{$entry_image.height}" /></a></p>
<!--{elseif $entry_thumbnail}-->
  <p><a href="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}entry_files/{$entry.id}/{$entry.file}"><img src="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}entry_thumbnails/{$entry.id}/{$entry.file}" alt="{$entry.memo|default:$entry.file}" title="{$entry.memo|default:$entry.file}" width="{$entry_thumbnail.width}" height="{$entry_thumbnail.height}" /></a></p>
<!--{elseif $entry.file and $entry_file.width and $entry_file.height}-->
  <p><img src="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}entry_files/{$entry.id}/{$entry.file}" alt="{$entry.memo|default:$entry.file}" title="{$entry.memo|default:$entry.file}" width="{$entry_file.width}" height="{$entry_file.height}" /></p>
<!--{elseif $entry.file}-->
  <p><a href="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}entry_files/{$entry.id}/{$entry.file}">{$entry.memo|default:$entry.file}</a></p>
<!--{/if}-->

この部分を、以下のように変更します。

<!--{if $entry.file and $entry.image}-->
  <p><a href="{$freo.core.http_file}/file/view/{if $entry.code}{$entry.code}{else}{$entry.id}{/if}.png"><img src="{$freo.core.http_url}{$smarty.const.FREO_FILE_DIR}entry_images/{$entry.id}/{$entry.image}" alt="{$entry.memo|default:$entry.file}" title="{$entry.memo|default:$entry.file}" width="{$entry_image.width}" height="{$entry_image.height}" /></a></p>
<!--{elseif $entry_thumbnail}-->
  <p><a href="{$freo.core.http_file}/file/view/{if $entry.code}{$entry.code}{else}{$entry.id}{/if}.png"><img src="{$freo.core.http_file}/file/view/{if $entry.code}{$entry.code}{else}{$entry.id}{/if}?type=thumbnail" alt="{$entry.memo|default:$entry.file}" title="{$entry.memo|default:$entry.file}" width="{$entry_thumbnail.width}" height="{$entry_thumbnail.height}" /></a></p>
<!--{elseif $entry.file and $entry_file.width and $entry_file.height}-->
  <p><img src="{$freo.core.http_file}/file/view/{if $entry.code}{$entry.code}{else}{$entry.id}{/if}" alt="{$entry.memo|default:$entry.file}" title="{$entry.memo|default:$entry.file}" width="{$entry_file.width}" height="{$entry_file.height}" /></p>
<!--{elseif $entry.file}-->
  <p><a href="{$freo.core.http_file}/file/view/{if $entry.code}{$entry.code}{else}{$entry.id}{/if}">{$entry.memo|default:$entry.file}</a></p>
<!--{/if}-->

それぞれ、hrefsrc の内容を数ヶ所変更しています。これで編集は完了です。.htaccess でアクセス制限していても、ファイルが表示されるようになったのを確認してください。

なお、携帯用のテンプレートは初めからPHP経由での呼出になっているので、修正する必要はありません。(キャリアに応じた画像形式変換などを行うため。)

サムネイルやミニ画像にPHP経由でアクセスする

上の例でも触れていますが、サムネイルやミニ画像にアクセスすることもできます。

サムネイルにアクセスするには、URLの最後に ?type=thumbnail を追加します。また、ミニ画像にアクセスするには、URLの最後に ?type=image を追加します。

具体的には以下のようなURLです。

  • http://www.example.com/freo/index.php/file/view/15?type=thumbnail
  • http://www.example.com/freo/index.php/file/view/15?type=image
  • http://www.example.com/freo/index.php/file/page/about?type=thumbnail
  • http://www.example.com/freo/index.php/file/page/about?type=image