我正在使用codeigniter框架。
我应该在哪里清理PHP输入 - 控制器或模型?
答案 0 :(得分:22)
所有这些答案都与PHP方法有关,但与CodeIgniter无关。
发布数据
如果在config.php中启用了global_xss,则当您使用$ this-> input-> post('item_name')时,CodeIgniter会自动清除您的POST数据。如果您只希望清洁特定物品,可以使用:
$this->input->post('item_name', TRUE);
无论哪种方式,您都可以免受XSS攻击和其他问题的困扰。
SQL注入
如果您使用ActiveRecord(insert(),update()等)或使用query()绑定,则会自动转义输入数据库的任何内容。
$this->db->query('INSERT INTO bla (?, ?)', array($foo, $bar));
这一切都是逃脱的,所以不再对那里的事情感到不满。您可以编写代码并将安全保留在框架中。
答案 1 :(得分:19)
我曾经是尽可能集中环境卫生的朋友,但对SO(for example here)的广泛讨论改变了我的想法。绝对值得一读。
我向您提交以下做法:
在中央验证程序中,不进行卫生处理,或仅进行“粗略”检查(例如,对于数据类型)和大小(“$ _POST [”category_name“]不应大于200字节。”)
将传入变量标记为不安全(例如$unsafe_id = $_POST["category_name"];
)。将它们存储在您可用的任何控制器/类/构造中。
清理数据使用的位置。例如,如果在exec
电话中使用了传入数据,请直接在电话前进行必要的卫生处理:
$safe_category_name = escapeshellargs($unsafe_category_name);
exec("external_binary -category_name '$safe_category_name'");
如果在mySQL查询中使用相同的数据,则在呼叫前再次清理它:
$safe_category_name = mysql_real_escape_string ($unsafe_category_name);
mysql_query("SELECT * FROM items WHERE category_name = '$safe_category_name'");
(这只是一个例子。如果从头开始一个项目,你将需要使用PDO和预处理语句,这消除了在此上下文中转义传入数据的麻烦。)
如果在网页中输出相同的数据,请再次直接在通话前进行卫生处理:
$safe_category_name = htmlspecialchars($unsafe_category_name);
echo "<span>$safe_category_name</span>";
这种做法
建立一个工作流程,假设存在需要首先处理的不安全变量,这将导致更安全的编程风格IMO。
防止不必要的转换。
帮助消除一种单击方法使输入“安全”的错觉。没有。卫生设施100%取决于背景。
答案 2 :(得分:8)
清理取决于数据的清理程度。
通常有两种类型的消毒:
在第一种情况下,它是为了防止SQL injection攻击,第二种是防止Cross-site scripting攻击。
因此,为了回答您的问题(关于上述攻击媒介),您的清理应该是存在漏洞的地方,更具体地说:
我希望这会有所帮助。
答案 3 :(得分:7)
控制器应该很薄。
应该在模型中清理PHP输入,以便与模型保存的位置有关。即阻止模型中的SQL注入。
应该在视图中清理它与最终输出有关的任何事情。即在视图中阻止XSS。
基本上,所有敏感化都应及时进行,以防止不良数据造成任何伤害。
答案 4 :(得分:1)
控制器就像应用程序网守一样,所以它应该是验证所有输入的地方。
答案 5 :(得分:1)
我会把它放在处理表单提交的控制器中。正如Phil Sturgeon指出你在配置中启用了global_xss选项CodeIgniter无论如何都将处理一个ceratin级别的清理。
作为额外的安全级别,我会使用CodeIgniter的form_validation库。这是一个示例控制器:
function processForm()
{
// fields will need to be validated so load library
$this->load->library('form_validation');
// field name, error message, validaiton rules
$this->form_validation->set_rules('first_name','Name','trim|required');
if($this->form_validation->run() == FALSE)
{
// load form again showing errors
} else {
// update database or proceed to stage 2
}
}
我希望这有帮助! 干杯
答案 6 :(得分:0)
您的请求通常会转到控制器,您应该在控制器中执行此操作,控制器一旦获取此数据并进行清理,然后可以使用安全数据与模型进行交互。
答案 7 :(得分:0)
据我所知,用户输入应该在控制器中进行清理,因为它代表了一个强制性段落,用于查看(您向其显示信息的位置)之间的数据用户和您获得用户输入)和您的模型(存储数据的地方)。
模型应该始终被视为MVC结构中的可插入组件,这意味着您可以(例如)切换模型(数据库实现和/或与之交互的方式)在某一点上。因此,用户数据验证不应绑定到DB的特定实现。只有特定于数据库的清理部分(如果有的话)应保留在模型中。
说这个,最后的决定总是取决于你。请记住:
希望这有帮助。
答案 8 :(得分:-1)
我只会在我看来这样做。没有必要清理它以存储在数据库中。仅仅输出干净的数据就足够了。您还需要转义数据以防止SQL注入。