我刚开始学习Rails安全性,我想知道如何在允许用户将CSV文件上传到我们的数据库中时避免安全问题。我们使用Postgres的“stdin复制”功能将CSV中的数据上传到临时表中,然后将其用于upsert到另一个表中。这是基本代码(感谢this post):
conn = ActiveRecord::Base.connection_pool.checkout
raw = conn.raw_connection
raw.exec("COPY temp_table (col1, col2) FROM STDIN DELIMITER '|'")
# read column values from the CSV line by line in the following format:
# attributes = {column_1: 'column 1 data', column_2: 'column 2 data'}
# line = "#{attributes.values.join('|')}\n"
rc.put_copy_data line
# wrap up copy process & insert into & update primary table
我想知道我可以或应该做些什么来清理列值。我们使用的是Rails 3.2和Postgres 9.2。
答案 0 :(得分:4)
无需采取任何行动; COPY
永远不会将值解释为SQL语法。由于引用错误/列数不正确,格式错误的CSV将产生错误。如果您逐行发送自己的数据,则应该排除包含单个\.
后跟新行的行,但除此之外它是相当安全的。
PostgreSQL不会以任何方式清理数据,它只是安全地处理它。因此,如果您在CSV中接受字符串');DROP TABLE customer;--
,则COPY
中的字符串非常安全。 然而,如果您的应用程序从数据库中读取它,则假定“因为它来自数据库而不是用户是安全的”,并将其插入到SQL字符串中,您仍然只是填充。
同样,错误地使用PL / PgSQL函数,其中EXECUTE
与不安全的字符串连接一起使用会产生问题。您必须使用format
和%I
或%L
说明符,使用quote_literal
/ quote_ident
或(对于文字)使用EXECUTE ... USING
。< / p>
这不仅适用于COPY
,如果您对INSERT
操纵数据进行操作,则在从数据库中读回数据后不安全地使用它是相同的。