在哪里清理PHP $ _POST []输入?

时间:2010-03-08 13:51:50

标签: php codeigniter

我正在使用codeigniter框架。

我应该在哪里清理PHP输入 - 控制器或模型?

9 个答案:

答案 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攻击。

因此,为了回答您的问题(关于上述攻击媒介),您的清理应该是存在漏洞的地方,更具体地说:

  • 您在其中编写带有变量的SQL查询(模型)
  • 你写任何输出(通常是HTML)(视图)

我希望这会有所帮助。

答案 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注入。