Content Security Policy (CSP) の report を 10 日くらい集計して、ポリシーを見直す(の途中)


Content Security Policy (CSP) の report を MonogoDB で集計して、ポリシーを見直す(の途中) | Monotalk 1週間程度 CSP レポートを収集して、定義値を変更し、途中で力尽きていたのですが、
再度集計して、様子を伺ってみたいと思います。


現在のポリシー定義

現状のポリシー定義は以下の通りです。

Content-Security-Policy-Report-Only:
default-src 'self'; 
script-src 'self' *.disqus.com pagead2.googlesyndication.com www.google-analytics.com; 
img-src 'self' *.disqus.com *.disquscdn.com *.googleusercontent.com *.google.com googledrive.com
report-uri /report/

CSPのレポートデータの収集と、集計について

adamalton/django-csp-reports: Django app for handling browser reports from Content Security Policy violations という Django-plugin を使って、MongoDB に貯めてます。

ログ出力だけしておいて、その後、整形して MongoDB に取り込んでいましたが、
面倒くさくなってきたので、以下、report 保存用の function を定義して、その中で、
MongoDB に登録するように設定しました。1
1. django-csp-reports に settings.py 経由で登録用 function の設定ができます。登録 function も手抜きですが、settings.py に定義

  • settings.py
    CSP_REPORTS_ADDITIONAL_HANDLERS = ["blog.settings.save_csp_report"]
    
    # Django-CSP-Reports HANDLER function
    import pymongo
    import datetime
    import json
    def save_csp_report(request):
        reports_collection = __get_reports_collection() 
        jsn = request.body
        if isinstance(jsn, bytes):
            jsn = jsn.decode('utf-8')
        json_dict = json.loads(jsn)
        json_dict = json_dict["csp-report"]
        json_dict.update({"create_date" : datetime.datetime.utcnow()})
        reports_collection.insert_one(json_dict)
    
    def __get_reports_collection():
        client = pymongo.MongoClient(host='{your_host}', port={your_port)
        csp_analyze_db = client.csp_analyze
        reports_collection = csp_analyze_db.reports
        return reports_collection    
    

上記で、登録したデータをcsvにexportして、
スプレッドシートで集計します。

  • mongoexport
    mongoexport --db csp_analyze --csv --collection reports --out export.csv --fields \
    create_date,\
    blocked-uri,\
    column-number,\
    disposition,\
    document-uri,\
    effective-directive,\
    line-number,\
    original-policy,\
    referrer,\
    source-file,\
    status-code,\
    violated-directive,\
    script-sample
    

集計と、修正方針

Google データスタジオを使って、violated-directive ごとの、
blocked-uri を集計、その結果を元に、ポリシー定義を修正していきます。

violated-directive ごとのblocked-uri の集計結果

violated-directive : style-src での 集計

inline と、 c.disquscdn.com ドメインに対するエラーが記録されています。
inline の許可は、クロスサイトスクリプティングの脆弱性が発生するため、許可しないほうがよいかと思いますが、
blog で使用している markdown plugin が、どうもゴリゴリでinline style を使っているため、
ここはあきらめて、定義を追加することにします。

violated-directive : frame-src での 集計

以下のドメインに対するエラーが記録されていました。

  • googleads.g.doubleclick.net

  • disqus.com

  • staticxx.facebook.com

  • pstatic.eshopcomp.com

  • xx.xcetkbl.com

disqus.com は disqusなのでいいとして、
googleads.g.doubleclick.netstaticxx.facebook.compstatic.eshopcomp.comxx.xcetkbl.com は少し信用ならない気がしましたので、
なんのドメインなのか確認してみました。

violated-directive : frame-src での 集計

violated-directive : frame-src

eval と、disqus.comc.disquscdn.com ドメインに対するエラーが記録されています。
eval も Google Adsense を使ってる時点で許可しておかないと、
ダメなようです。4
show_ads_impl.js という js が eval 実行しているようです。

violated-directive : connect-src での 集計

violated-directive : connect-src

links.services.disqus.com でのエラーが記録されています。
disqus 関連のドメインなので、対象ドメインを許可します。

violated-directive : img-src での 集計

violated-directive : img-src

data と、googledrive.comssl.google-analytics.com ドメインに対するエラーが記録されています。
data は許可しますが、ドメインはエラー数がそれほど多くないので、一旦設定を見送ります。4
data を許容する根拠はあまりありません。
リンクしているjsなどで出ているので、内部でなにか画像を、base64 エンコードでもしてるのではなかろうかと思われます。

violated-directive : font-src での 集計

violated-directive : font-src

fonts.gstatic.com ドメインに対するエラーが記録されています。5
自サイトで使用していなくても、これは、Google Adsense とかが、場合によっては読み込んでいるようです。
ので、許可します。

円グラフ推しでしたが、許可設定は以上です。


変更後のポリシー定義

出力された定義自体

変更後のポリシー定義は以下のようになりました。
実際は改行は入ってないですが、prettyに改行を入れています。
この定義で、当サイトはほとんどエラーレポートは出なくなりました。6
それでも出ます。

Content-Security-Policy-Report-Only:
default-src 'self'; frame-src 'self' googleads.g.doubleclick.net staticxx.facebook.com *.disqus.com disqus.com; 
script-src 'self' 'unsafe-inline' 'unsafe-eval' pagead2.googlesyndication.com www.google-analytics.com *.disqus.com c.disquscdn.com; style-src 'self' 'unsafe-inline' *.disquscdn.com; 
img-src 'self' *.disqus.com *.disquscdn.com *.googleusercontent.com *.google.com *.googledrive.comgoogledrive.com data:;
connect-src 'self' *.disqus.com;
font-src 'self' fonts.gstatic.com;
report-uri /report/

参考

以下、参考なりました。
CSP のポリシーディレクティブ - Web セキュリティ | MDN


今後

1回のページ表示ごとに、50~100 くらいのレポートが出ていましたが、それはなくなりました。
が、それでも出力されてるので、継続して、Content-Security-Policy-Report-Only で様子見を続けようかと思います。
最終的には、Content-Security-Policy-Report-Only は消したい気持ちはありますが、結構勇気がいるのではないかと。。

やってみての感想は、「今まで、静的解析してなかったプログラム(JAVAでいうとプロジェクト規模)に静的解析してエラーつぶしてみた」。
を初めてやった時に近いものがあります。
最初は、全然意味がわからんが、意味がわからんを調べていくのが勉強なってるという。。
会社で同じことをやりたいかというと、あまりやりたくないですが、やりきると、サイトのためというか、ユーザーためになる(スパイウェアを拾う)のではとも思いました。7
問い合わせを受けるのは、自社なのでいや「あんたのPCのブラウザが勝手にどっかのよくわからないサイトにアクセスするように何か仕込まれてるんですよ」
って回答するコストがかかるだけかもしれないですが。。

しばらく、また放置して様子を伺ってみようと思います。
以上です。

コメント