Django のセキュリティポリシー

Django の開発チームは、セキュリティ関連の問題の責任ある報告と開示に強くコミットしています。そのため、私たちはその理想に従い、公式の Django ディストリビューション、およびサードパーティのディストリビューションにタイムリーなセキュリティ更新を提供できるようにすることを目指した一連の方針を採用し、それに従っています。

セキュリティ問題の報告

要約: セキュリティに関する問題は、security@djangoproject.com までメールで報告してください

Djangoにおけるほとんどの通常のバグは our public Trac instance に報告されますが、セキュリティ問題は機密性が高いため、それらをこの方法で公に報告することは しないでください

もし Django に関してセキュリティ上の影響を及ぼすと思われる何かを見つけた場合は、問題の説明をメールで security@djangoproject.com に送ってください。そのアドレスに送られたメールは セキュリティチーム に届きます。

Once you've submitted an issue via email, you should receive an acknowledgment from a member of the security team within 3 working days. After that, the security team will begin their analysis. Depending on the action to be taken, you may receive followup emails. It can take several weeks before the security team comes to a conclusion. There is no need to chase the security team unless you discover new, relevant information. All reports aim to be resolved within the industry-standard 90 days. Confirmed vulnerabilities with a high severity level will be addressed promptly.

暗号化されたレポートの送信

暗号化されたメールを送信したい場合 (任意)、security@djangoproject.com の公開キーIDは 0xfcb84b8d1d17f80b です。この公開キーは、一般的に使用されているほとんどのキーサーバーから入手可能です。

Reporting guidelines

Include a runnable proof of concept

Please privately share a minimal Django project or code snippet that demonstrates the potential vulnerability. Include clear instructions on how to set up, run, and reproduce the issue.

Please do not attach screenshots of code.

User input must be sanitized

Reports based on a failure to sanitize user input are not valid security vulnerabilities. It is the developer's responsibility to properly handle user input. This principle is explained in our security documentation.

For example, the following is not considered valid because email has not been sanitized:

from django.core.mail import send_mail
from django.http import JsonResponse


def my_proof_of_concept(request):
    email = request.GET.get("email", "")
    send_mail("Email subject", "Email body", email, ["admin@example.com"])
    return JsonResponse(status=200)

Developers must always validate and sanitize input before using it. The correct approach would be to use a Django form to ensure email is properly validated:

from django import forms
from django.core.mail import send_mail
from django.http import JsonResponse


class EmailForm(forms.Form):
    email = forms.EmailField()


def my_proof_of_concept(request):
    form = EmailForm(request.GET)
    if form.is_valid():
        send_mail(
            "Email subject",
            "Email body",
            form.cleaned_data["email"],
            ["admin@example.com"],
        )
        return JsonResponse(status=200)
    return JsonResponse(form.errors, status=400)

Similarly, as Django's raw SQL constructs (such as extra() and RawSQL expression) provide developers with full control over the query, they are insecure if user input is not properly handled. As explained in our security documentation, it is the developer's responsibility to safely process user input for these functions.

For instance, the following is not considered valid because query has not been sanitized:

from django.shortcuts import HttpResponse
from .models import MyModel


def my_proof_of_concept(request):
    query = request.GET.get("query", "")
    q = MyModel.objects.extra(select={"id": query})
    return HttpResponse(q.values())

Request headers and URLs must be under 8K bytes

To prevent denial-of-service (DoS) attacks, production-grade servers impose limits on request header and URL sizes. For example, by default Gunicorn allows up to roughly:

Other web servers, such as Nginx and Apache, have similar restrictions to prevent excessive resource consumption.

Consequently, the Django security team will not consider reports that rely on request headers or URLs exceeding 8K bytes, as such inputs are already mitigated at the server level in production environments.

runserver should never be used in production

Django's built-in development server does not enforce these limits because it is not designed to be a production server.

The request body must be under 2.5 MB

The DATA_UPLOAD_MAX_MEMORY_SIZE setting limits the default maximum request body size to 2.5 MB.

As this is enforced on all production-grade Django projects by default, a proof of concept must not exceed 2.5 MB in the request body to be considered valid.

Issues resulting from large, but potentially reasonable setting values, should be reported using the public ticket tracker for hardening.

Code under test must feasibly exist in a Django project

The proof of concept must plausibly occur in a production-grade Django application, reflecting real-world scenarios and following standard development practices.

Django contains many private and undocumented functions that are not part of its public API. If a vulnerability depends on directly calling these internal functions in an unsafe way, it will not be considered a valid security issue.

Content displayed by the Django Template Language must be under 100 KB

The Django Template Language (DTL) is designed for building the content needed to display web pages. In particular its text filters are meant for that kind of usage.

For reference, the complete works of Shakespeare have about 3.5 million bytes in plain-text ASCII encoding. Displaying such in a single request is beyond the scope of almost all websites, and so outside the scope of the DTL too.

Text processing is expensive. Django makes no guarantee that DTL text filters are never subject to degraded performance if passed deliberately crafted, sufficiently large inputs. Under default configurations, Django makes it difficult for sites to accidentally accept such payloads from untrusted sources, but, if it is necessary to display large amounts of user-provided content, it’s important that basic security measures are taken.

User-provided content should always be constrained to known maximum length. It should be filtered to remove malicious content, and validated to match expected formats. It should then be processed offline, if necessary, before being displayed.

Proof of concepts which use over 100 KB of data to be processed by the DTL will be considered invalid.

How does Django evaluate a report

These are criteria used by the security team when evaluating whether a report requires a security release:

  • The vulnerability is within a supported version of Django.

  • The vulnerability does not depend on manual actions that rely on code external to Django. This includes actions performed by a project's developer or maintainer using developer tools or the Django CLI. For example, attacks that require running management commands with uncommon or insecure options do not qualify.

  • The vulnerability applies to a production-grade Django application. This means the following scenarios do not require a security release:

    • Exploits that only affect local development, for example when using runserver.

    • Exploits which fail to follow security best practices, such as failure to sanitize user input. For other examples, see our security documentation.

    • Exploits in AI generated code that do not adhere to security best practices.

The security team may conclude that the source of the vulnerability is within the Python standard library, in which case the reporter will be asked to report the vulnerability to the Python core team. For further details see the Python security guidelines.

On occasion, a security release may be issued to help resolve a security vulnerability within a popular third-party package. These reports should come from the package maintainers.

If you are unsure whether your finding meets these criteria, please still report it privately by emailing security@djangoproject.com. The security team will review your report and recommend the correct course of action.

サポートバージョン

Django チームは、特定の時点で複数のバージョンの Django に公式のセキュリティサポートを提供しています:

  • GitHub 上にホスティングされ、Django の次のメジャーリリースになる main development branch は、セキュリティサポートを受けています。安定版リリースに影響を与えない、メイン開発ブランチのみに影響するセキュリティ問題は、開示プロセス を経ずに公に修正されます。

  • Djangoの最新のリリースシリーズ 2 つがセキュリティサポートを受けます。たとえば、Django 1.5 のリリースに向けた開発サイクル中には、Django 1.4 とDjango 1.3 がサポートされます。Django 1.5 がリリースされると、Django 1.3 のセキュリティサポートは終了します。

  • LTS Long-term support release は、指定された期間、セキュリティ更新が行われます。

セキュリティ上の理由で新しいリリースが発行されるとき、付随するお知らせには影響を受けるバージョンのリストが含まれます。このリストは サポートされている Django のバージョンのみで構成されています。古いバージョンも影響を受ける可能性がありますが、それを調査することはせず、それらのバージョンに対してパッチや新しいリリースは発行しません。

Security issue severity levels

The severity level of a security vulnerability is determined by the attack type.

Severity levels are:

  • High (高)

    • リモートコード実行

    • SQL インジェクション

  • Moderate (中)

    • クロスサイトスクリプティング (XSS)

    • クロスサイトリクエストフォージェリ (CSRF)

    • サービス拒否攻撃 (DoS)

    • 認証の不備

  • Low (低)

    • 機密データの露出

    • セッション管理の不備

    • 検証されていないリダイレクト/フォワード

    • 一般的ではない設定オプションが必要な問題

Django のセキュリティ問題の公開プロセス

セキュリティ問題をプライベートな議論から公開開示に移行するプロセスには、複数のステップが含まれています。

公開開示の約1週間前に、2つの通知を送信します:

First, we notify django-announce of the date and approximate time of the upcoming security release, as well as the severity of the issues. This is to aid organizations that need to ensure they have staff available to handle triaging our announcement and upgrade Django as needed.

次に、主にオペレーティングシステムのベンダーや Django のその他の配布者から構成される 個人および組織 のリストに通知します。このメールは Django's release team の誰かの PGP キーで署名され、以下を含みます:

  • 問題の完全な説明と、影響を受ける Django のバージョン。

  • 問題を解決するために必要な手順。

  • Django に適用されるパッチ(もしあれば)。

  • Django チームがこれらのパッチを適用し、新しいリリースを発行し、問題を公に開示する日付。

公開日には、以下の手順を踏みます:

  1. Django のコードベースに、関連するパッチを適用します。

  2. 関連するリリースを発行するために、新しいパッケージを Python Package Index および djangoproject.comのウェブサイト にアップロードし、Django の git リポジトリで新しいリリースをタグ付けします。

  3. 公式の Djang o開発ブログ the official Django development blog に公開エントリを投稿し、該当の問題とその解決策を詳細に記述します。関連するパッチや新しいリリースに言及し、問題を報告した人(公開を希望する場合)に感謝の意を表します。

  4. django-announceoss-security@lists.openwall.com メーリングリストに、ブログ投稿へのリンクを含む通知を投稿します。

報告された問題が特に急を要すると考えられる場合(たとえば、既知の脆弱性が実際に悪用されているなど)、事前通知と公開開示の間隔はかなり短縮されることがあります。

また、私たちに報告された問題が Python / Web エコシステム内の他のフレームワークやツールに影響を及ぼすと考える理由がある場合には、適切なメンテナーに個別に連絡を取り、その問題について話し合い、私たち自身の開示と解決を彼らのものと調整することがあります。

Django チームは、Django で公開されたセキュリティ問題のアーカイブ も管理しています。

事前通知を受け取る対象者

セキュリティ問題の事前通知を受け取る人々と組織の完全なリストは、公開されておらず、今後も公開されることはありません。

また、開示前の機密情報の流れをより良く管理するために、このリストを実質的に可能な限り小さく保つことを目指しています。そのため、当社の通知リストは単に Django のユーザーのリストでは ありません 。そして、Django のユーザーであることは、通知リストに追加されるための十分な理由ではありません。

一般的に、セキュリティ通知を受け取ることができる人は以下の 3 つのグループに分けられます:

  1. オペレーティングシステムのベンダーや Django を提供するその他のディストリビューター。この人たちは、問題の報告や一般的なセキュリティの報告のために適切な(つまり、個人の個人メールアドレスでは ない )連絡先アドレスを提供する必要があります。いずれの場合も、そのようなアドレスは一般のメーリングリストやバグトラッカーに転送しては いけません 。個々のメンテナーやセキュリティ対応担当者のプライベートなメールに転送されるアドレスは許容されますが、プライベートセキュリティトラッカーやセキュリティ対応グループへの転送が強く推奨されます。

  2. 個別のケースに基づいて、これらの通知に対して責任を持って対応し、行動することを約束したパッケージメンテナ。

  3. ケースバイケースで、Django開発チームの判断により、保留中のセキュリティ問題について知らされる必要があると判定された他の団体。通常、このグループのメンバーは、Djangoの最大の利用者や配布者の中で、最も深刻に影響を受ける可能性が高いと考えられる団体の一部で構成され、これらの通知を責任を持って受け取り、機密を保持し、行動する能力を実証することが求められます。

セキュリティ監査団体とスキャニング団体

ポリシーとして、この種の団体を通知リストに追加することはありません。

通知のリクエスト

もしあなたや、あなたが代理を務める組織が、上記にリストされたグループのいずれかに該当すると考えられる場合は、security@djangoproject.com へメールを送信して、Djangoの通知リストに追加されるよう依頼できます。件名には「Security notification request」と記載してください。

リクエストには、以下の情報を 必ず 含める必要があります:

  • あなたのフルネームと、該当する場合は、あなたが代表する組織の名前、およびその組織内でのあなたの役割。

  • 上記の条件の少なくとも1つに、あなたまたはあなたの組織がどのように適合するかの詳細な説明。

  • セキュリティ通知をリクエストしている理由の詳細な説明です。このリストはDjangoのユーザー向けのものでは ない ことを、再度心に留めてください。圧倒的多数のユーザーは、問題の詳細なしでセキュリティリリースがいつ行われるかの事前通知を受け取るために、 django-announce に登録すべきです。詳細な通知をリクエストすべきではありません。

  • 通知リストに追加されることを希望するメールアドレス。

  • そのアドレス宛に送信されたメールを受信・レビューする対象者についての説明、および、(例えば)問題追跡システムにおいて機密問題をファイリングするなど、自動で行われるアクションに関する情報。

  • 個人の場合、あなたのアドレスに関連付けられた公開鍵の ID。あなたから受信したメールを検証したり、必要に応じてあなたに送信するメールを暗号化するために使用できるものが必要です。

送信されたら、あなたのリクエストは Django 開発チームによって検討されます。リクエストの結果については、30日以内に返信で通知されます。

セキュリティ通知を受け取ることは、Django 開発チームの唯一の裁量によって付与される特権であり、この特権はいつでも、説明の有無にかかわらず、取り消すことができることを念頭に置いてください 。

必要な情報をすべて提供してください

初回の連絡で必要な情報を提供しなかった場合、あなたのリクエストを承認するかどうかの決定に影響を与えます。

Back to Top