确认浏览器预取导致删除

Posted

技术标签:

【中文标题】确认浏览器预取导致删除【英文标题】:Confirming browser prefetching is causing deletes 【发布时间】:2019-04-01 06:45:24 【问题描述】:

我正在尝试测试一个理论,即浏览器中的预取会导致我的 django 应用程序中出现无法解释的删除。

这是我的views.py中的删除方法:

def delete(request, part_id=None):
    obj = epe.objects.get(id=part_id)
    obj.delete()
    logger.error('Someone deleted record: '+str(part_id))
    return HttpResponseRedirect(reverse('epe_home'))

以及我如何在模板中使用网址:

<td><a href="% url 'epedelete' epe.id %"><input class="btn btn-danger" type="button" value="Delete" /></a></td>

当此方法被激活时,您可以看到我正在记录,但我仍然有无法解释的删除,而没有来自记录器的任何日志。这让我想知道无法解释的删除是否是由我的方法引起的。

我拥有的唯一删除日志来自 mysql 日志,如下所示:

6798 Connect
user@hostname on dbname
6798 Query
SET NAMES utf8
6798 Query
set autocommit=0
6798 Query
set autocommit=1
6798 Query
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED
6798 Query
SELECT `Epe_epe`.`id`, `Epe_epe`.`epe_type`, `Epe_epe`.`epe_type2_id`, `Epe_epe`.`epe_date`, `Epe_epe`.`epe_ani`, `Epe_epe`.`epe_ani2_id`, `Epe_epe`.`epe_apn`, `Epe_epe`.`epe_apn2_id`, `Epe_epe`.`epe_weight`, `Epe_epe`.`epe_drug_type1`, `Epe_epe`.`epe_drug1`, `Epe_epe`.`epe_dose1`, `Epe_epe`.`epe_amount1`, `Epe_epe`.`epe_route1`, `Epe_epe`.`epe_time1`, `Epe_epe`.`epe_drug_type2`, `Epe_epe`.`epe_drug2`, `Epe_epe`.`epe_dose2`, `Epe_epe`.`epe_amount2`, `Epe_epe`.`epe_route2`, `Epe_epe`.`epe_time2`, `Epe_epe`.`epe_drug_type3`, `Epe_epe`.`epe_drug3`, `Epe_epe`.`epe_dose3`, `Epe_epe`.`epe_amount3`, `Epe_epe`.`epe_route3`, `Epe_epe`.`epe_time3`, `Epe_epe`.`epe_drug_type4`, `Epe_epe`.`epe_drug4`, `Epe_epe`.`epe_dose4`, `Epe_epe`.`epe_amount4`, `Epe_epe`.`epe_route4`, `Epe_epe`.`epe_time4`, `Epe_epe`.`epe_drug_type5`, `Epe_epe`.`epe_drug5`, `Epe_epe`.`epe_dose5`, `Epe_epe`.`epe_amount5`, `Epe_epe`.`epe_route5`, `Epe_epe`.`epe_time5`, `Epe_epe`.`epe_drug_type6`, `Epe_epe`.`epe_drug6`, `Epe_epe`.`epe_dose6`, `Epe_epe`.`epe_amount6`, `Epe_epe`.`epe_route6`, `Epe_epe`.`epe_time6`, `Epe_epe`.`epe_iso_start`, `Epe_epe`.`epe_iso_end`, `Epe_epe`.`epe_o2_end`, `Epe_epe`.`epe_start1`, `Epe_epe`.`epe_start2`, `Epe_epe`.`epe_start3`, `Epe_epe`.`epe_start4`, `Epe_epe`.`epe_start5`, `Epe_epe`.`epe_start6`, `Epe_epe`.`epe_start7`, `Epe_epe`.`epe_start8`, `Epe_epe`.`epe_hr1`, `Epe_epe`.`epe_hr2`, `Epe_epe`.`epe_hr3`, `Epe_epe`.`epe_hr4`, `Epe_epe`.`epe_hr5`, `Epe_epe`.`epe_hr6`, `Epe_epe`.`epe_hr7`, `Epe_epe`.`epe_hr8`, `Epe_epe`.`epe_spo2_1`, `Epe_epe`.`epe_spo2_2`, `Epe_epe`.`epe_spo2_3`, `Epe_epe`.`epe_spo2_4`, `Epe_epe`.`epe_spo2_5`, `Epe_epe`.`epe_spo2_6`, `Epe_epe`.`epe_spo2_7`, `Epe_epe`.`epe_spo2_8`, `Epe_epe`.`epe_temp1`, `Epe_epe`.`epe_temp2`, `Epe_epe`.`epe_temp3`, `Epe_epe`.`epe_temp4`, `Epe_epe`.`epe_temp5`, `Epe_epe`.`epe_temp6`, `Epe_epe`.`epe_temp7`, `Epe_epe`.`epe_temp8`, `Epe_epe`.`epe_etco2_1`, `Epe_epe`.`epe_etco2_2`, `Epe_epe`.`epe_etco2_3`, `Epe_epe`.`epe_etco2_4`, `Epe_epe`.`epe_etco2_5`, `Epe_epe`.`epe_etco2_6`, `Epe_epe`.`epe_etco2_7`, `Epe_epe`.`epe_etco2_8`, `Epe_epe`.`epe_rr1`, `Epe_epe`.`epe_rr2`, `Epe_epe`.`epe_rr3`, `Epe_epe`.`epe_rr4`, `Epe_epe`.`epe_rr5`, `Epe_epe`.`epe_rr6`, `Epe_epe`.`epe_rr7`, `Epe_epe`.`epe_rr8`, `Epe_epe`.`epe_comment` FROM `Epe_epe` WHERE `Epe_epe`.`id` = 1508
6798 Query
set autocommit=0
6798 Query
DELETE FROM `Epe_epe` WHERE `Epe_epe`.`id` IN (1508)
6798 Query
commit
6798 Query
set autocommit=1
6798 Quit

上面的delete 方法是我允许在我的应用程序中删除的唯一情况。我知道在 GET 请求中进行破坏性操作可能会导致我看到的无法解释的删除,所以我想弄清楚这里是否是这种情况。有没有其他地方可以出处?

我不确定这是否相关,但我仍在使用与 django 捆绑的开发服务器。我允许多台机器上的多个用户访问我的应用程序以帮助调试过程。在这种情况下无法使用生产级服务器会导致无法解释的删除?

【问题讨论】:

您已经注意到,将 GET 用于破坏性指令是有风险的 - 可能更好地解决这个问题?即使您确实设法将其固定为预取,您当前的方法仍然很危险,并且容易受到拒绝服务和跨站点请求伪造攻击等攻击。 您未显示的多个地方可能会导致此行为。例如,您的 epe 模型有一个 delete() 方法,每当您的视图运行时就会调用该方法。您也有可能在代码的其他地方或数据库中操作对象的 id。看看epe 的模型是什么样子可能会有所帮助。被奇怪删除的对象的 ID 是否有任何模式?他们的 ID 是否对应于以前删除的数据库条目,或者是最高的 ID(比如)? 我将把它留在这里:thedailywtf.com/articles/The_Spider_of_Doom。 GET 请求假定是非破坏性的。这不是浏览器行为异常,而是您的应用程序在做错事。 我们能看到 django 日志吗?您可能没有正确配置 django 日志记录。 @DashCountrol 你能检查我的解决方案并判断它是否有效吗? 【参考方案1】:

您采取的方法似乎是正确的。但是我有另一种方法来找出删除。您可以为 django 模型编写自定义管理器,然后覆盖 delete()。在此处放置一个记录器,这种方法的额外优势是,如果任何其他 django 应用程序或任何其他人试图从该模型中删除一行,那么将使用您的自定义 delete()

您可以关注this article 了解如何使用管理器实现删除或覆盖查询集的删除功能。

【讨论】:

【参考方案2】:

基于 Django 类的通用视图允许对象删除see the docs 因此,如果您使用它们,即使您没有定义(重载)它,您也可以在每个视图中获得删除方法。

【讨论】:

以上是关于确认浏览器预取导致删除的主要内容,如果未能解决你的问题,请参考以下文章

尽管浏览器预取/缓存,如何判断文件是不是真的被下载和保存?

芹菜中的预取任务是不是被确认?

如何删除IE里的证书

浏览器(chrome)资源的优先级, preload和prefetch介绍

html 预浏览(DNS预取)来自http://alistapart.com/article/one-step-ahead-improving-performance-with-prebrowsing

删除锚标签上的确认消息