Django CSRF在POST到外部URL期间保护?

uqxowvwt  于 2023-06-25  发布在  Go
关注(0)|答案(2)|浏览(91)

Context

我正在使用Django框架和Stripe在Python中构建一个网站,用于用户支付。我目前处于本地开发的测试/调试阶段,离生产构建还很远。
目前在用CSRF进行砖墙保护时,还找不到解决方案.我的结帐工作完美,没有CSRF保护。
这里还有其他非常类似的问题,但由于我缺乏CSRF保护本身的知识,我希望有人能启发我在我的特定情况下该怎么做。
这种情况应该有一个常见的实践解决方案,但我已经研究了Django和Stripe的大部分文档,没有运气。
欢迎批评,这是我的第一篇StackOverflow文章。

问题

我有一个视图功能,它可以通过将用户发送到Stripes外部结账页面来购买我网站上的产品。
views.py

@csrf_exempt # CSRF Protection disabled for testing
def create_checkout_session(request):
    if request.method == 'POST':
        try:
            checkout_session = stripe.checkout.Session.create(

                ...

            )
        except Exception as e:

            ...

        return redirect(checkout_session.url)

在测试期间,我使用Django的 @csrf_exempt 装饰器禁用了视图函数上的CSRF保护。我这样做是为了绕过'403 CSRF验证失败'错误。
我首先得到错误的原因是由于Django文档中的this statement
<form method="post">{% csrf_token %}
不应该对以外部URL为目标的POST表单执行此操作,因为这会导致CSRF令牌泄漏,从而导致漏洞。
在删除 @csrf_exempt 装饰器后,我现在卡住了,因为这正是我的提交表单的工作方式,如下面的 products.html 所示,结帐url是由stripe生成的(如www.example.com所示views.py),因此(我认为)是一个外部url:
products.html

<form rel="noreferrer" action="{% url 'checkout' %}" method="POST">
    {% csrf_token %} <!-- forbidden in POST to external URL -->
    <button rel="noreferrer" id="checkout-button" class="btn btn-sm" type="submit">
        Buy
    </button>
</form>

目前质疑以下几点:

  • 有没有其他方法可以在不使用POST的情况下获得相同的结果?
  • 我是否误解了Stripe文档?
  • 结帐URL实际上是“外部”吗?
  • 我是否应该放弃这种方法,并将Stripe的结帐硬编码到我的网站中以获得更好的安全性?

使用的资源:

我尝试过的:

我试图找到类似的解决方案,我发现这里有多个问题与我的问题有关,但没有一个我发现覆盖外部URL的CSRF保护的细节。
Django文档声明在POST到外部url时禁止使用{% csrf_token %},但经过进一步调查,没有详细说明任何解决方法或替代方案。
在得出解决方案并不明显的结论后,我的印象是,我的问题是由我自己引起的,因为我缺乏CSRF保护和Web安全方面的知识。这就把我带到了知识池StackOverflow。

yvfmudvl

yvfmudvl1#

你实际上不需要使用csrf令牌,因为它是一个外部站点,有自己的安全性,我看不出不使用它会对你产生什么影响。Stripe有自己的保护机制,它会给予你一个webhook请求来确认一切正常,而不需要使用csrf令牌。

bxjv4tth

bxjv4tth2#

我假设你在urls.py中有这样的东西:

urlpatterns = [
  // ...
  path('checkout', views.create_checkout_session, name='checkout'),
]

所以当你在模板中有一个像这样的表单:

<form rel="noreferrer" action="{% url 'checkout' %}" method="POST">

单击提交按钮将发布到您的视图。这意味着您应该保留CSRF令牌,不要使用@csrf_exempt装饰器。

On the other hand, if your form used a stripe URL directly like this:
在您的示例中,CSRF令牌被发送回您自己的视图,因此不存在安全问题。然后,视图具有用于发送条带化请求的代码。只是要确保在任何地方都不要在代码中包含CSRF令牌。

相关问题