我知道您应该始终对用户输入的数据使用预准备语句(或清理)。我们这样做。我的问题是,一旦使用预处理语句输入数据并且数据位于我的数据库中,如果我从数据库中获取数据,自己操作(即没有用户参与),然后将其重新放入,我是否需要再次使用预准备语句?数据库?
我知道如果我从用户那里清理数据,我需要在自己操作它并将其放回数据库时对其进行清理。但这是否也适用于准备好的陈述?
总而言之,来自用户的数据 - >使用预备声明 - >进入数据库。但是,在处理用户提交但准备好的存储前数据时,我是否需要执行以下操作:数据库中的数据 - >使用预备声明 - >进入数据库?
谢谢!
答案 0 :(得分:4)
如果它来自用户,是的,您需要在再次插入时使用预准备语句。
想象一下,您使用准备好的语句获取恶意数据并保存。然后将其拉出来,对其执行某些操作,并将其保存回数据库。除非你碰巧安全,否则它仍然很危险。假设用户提交的数据是非恶意的,这绝不是安全的。如果在您第一次收到数据时认为数据是非恶意数据是不安全的,那么当它在数据库中存在一段时间时,它并不会神奇地变得安全。
答案 1 :(得分:3)
是的,你需要遵循相同的模式。
考虑您有一个varchar列,您已将值插入其中。例如,我们称之为last_name
。
有人可能已将'O'Reilly'
的值插入该列。
如果按照模式
完成准备 - > bind - >执行
存储在数据库中的列中的值将为O'Reilly
,包含该单引号。
如果您稍后从数据库中获取该值,只是因为您从数据库中获取该值,这并不意味着它现在“安全”包含在SQL语句的文本中。
如果要在另一个SQL语句中使用该值,则表示您遇到了用户首次输入值时遇到的相同的问题。
因此,您需要遵循相同的模式prepare -> bind -> execute
(或者,如果字符串值包含在SQL语句的文本中,则需要正确转义它。)
如果您只是引用包含不安全值的列的名称,那么您可以在SQL语句中安全地使用它,例如。
CREATE TEMPORARY TABLE _tmp_last_names
AS
SELECT t.last_name FROM mytable t
;
使用带有绑定占位符的预准备语句的模式不会“清理”数据。它只是一种避免某些数据值存在潜在问题的机制。
为绑定占位符提供的“不卫生”值将存储在数据库中。它将是相同的“不卫生”价值,而不是价值的一些“消毒”版本。
但是如果你已经做了一些其他逻辑(除了prepare - > bind - >执行模式)来“清理”存储在数据库中的所有值,那么重新执行就不是绝对必要的了。同样的逻辑。假设没有其他过程随后用不卫生的价值取代数据库中的卫生价值。
答案 2 :(得分:3)
为什么不对它进行消毒?任何你没有清理数据的地方都是不必要的开放,无论滥用这种开放的方式多么不可能。
如果您正在制作一次性剧本,那么请不要担心消毒。运行它然后将其删除。如果它是你的程序的一部分,那么清理它,因为你很容易。为什么要考虑使用与用于清理用户提交数据的方法不同的保存方法? 对于两个操作都包括以相同的方法保存,无论它是如何启动的,因此所有内容的外观和行为都相似并始终清理,例如
DB()->updateColumn('table', $data)->where('id', $uid);
这只是猜测,但似乎您正在采用的方法并未考虑代码重用的可能性。
答案 3 :(得分:0)
我想补充一点,在所有这些关于消毒(和我自己的搜索)的讨论中,没有解释如何在将MySQL数据放回PHP之前对其进行实际消毒? (诗篇:我没有50个代表能够评论任何人的答案,但我真的很想说这个,因为它是我在这里寻找的东西非常时刻。)