Мой метод Codeigniter для безопасного удаления записей базы данных - PullRequest
0 голосов
/ 07 июня 2011

Я искал об удалении записей БД в Codeigniter и наконец-то создал решение, которое я считаю безопасным.Буду очень признателен за любые отзывы!Я не уверен, правильно ли я это делаю ..

Преимущества:

  • Используется POST-запрос

  • Идентификатор удаляемой записи:
    подтверждено

  • Используется защита CSRF (автоматически
    генерируется Codeigniter)

В моем примере я удаляю отправленные пользователем ссылки (строка таблицы БД содержит заголовок ссылки, URL ссылки, описание ссылки).

HTML: базы данных содержатся в форме.Каждая запись имеет кнопку формы с соответствующим идентификатором ссылки в атрибуте id.

<?php echo form_open('profile/remove_link'); ?>

<?php echo form_hidden('link_id', ''); //value will be populated via jquery ?>

<ul id="user_links">
    <?php foreach($query as $row): ?>

    <li><?php echo $row->link_title; ?></li>
    <li><?php echo auto_link($row->link_url, 'url', TRUE); ?></li>
    <li><?php echo $row->link_description; ?></li>

    <button type="submit" class="remove" id="<?php echo $row->link_id ?>"  value="remove">Remove Link</button>

    <?php endforeach; ?>
</ul>

</form>

JQUERY: Когда пользователь нажимает кнопку remove, соответствующий идентификатор ссылки добавляется к вводу скрытого текста с именем link_id.

$(document).ready(function(){
    $('.remove').click(function() {
        var link_to_remove = $(this).attr("id");
        $("input[name=link_id]").val(link_to_remove);
    }); 
}); 

После нажатия кнопки удаления, он отправляет идентификатор ссылки для удаления на контроллер profile и функцию remove_link

    function remove_link()
    {
        $this->load->model('Profile_model');
        $links_data['query'] = $this->Profile_model->links_read(); //get links from db to add in view

        //Validation
        $this->form_validation->set_rules('link_id', 'Link ID', 'trim|required|xss_clean|max_length[11]|numeric'); //validate link id

        if ($this->form_validation->run() == FALSE) //if validation rules fail
        {           
            $this->load->view('profile/edit_links_view', $links_data);
        }
        else //success
        {
            $link_id =  $this->input->post('link_id'); //get id of link to be deleted
            $seg = 'user_links'; //used to redirect back to user links page
            $this->Profile_model->links_delete($link_id, $seg); //send link id to model function            
        }       
    }

MODEL

    function links_delete($link_id, $seg)
    {
        $this->db->where('user_id', $this->tank_auth->get_user_id());
        $this->db->where('link_id', $link_id);
        $this->db->delete('user_links'); 
        redirect("/profile/$seg/");         
    }

Ответы [ 3 ]

1 голос
/ 07 июня 2011

Если идентификаторы являются уникальными целыми числами в вашей базе данных, вы можете удалить эти правила:

отделка | xss_clean | Числовой

И добавьте это:

is_natural_no_zero

Возвращает FALSE, если элемент формы содержит что-либо, кроме натурального числа, но не ноль: 1, 2, 3 и т. Д.

Числовое правило позволяет использовать некоторые символы, которые вам, вероятно, не нужны, например десятичные и отрицательные. Вот источник (одна строка):

return (bool)preg_match( '/^[\-+]?[0-9]*\.?[0-9]+$/', $str);

Если по какой-то причине вы возвращаете ввод обратно в ваш HTML-вывод перед проверкой или просто параноик, то во что бы то ни стало: xss_clean it up. В противном случае это на самом деле не нужно, так как я не думаю, что есть какой-либо возможный метод атак XSS, который использует только число.

Справка:

Кроме того, вы можете захотеть добавить к вашему запросу предложение LIMIT 1 и обязательно удостовериться, что вы возвращаете значение (возможно, TRUE / FALSE) из вашей модели, чтобы вы знали, был ли запрос успешным, поэтому вы можете отправляйте отзывы пользователю вместо , предполагая, что все прошло хорошо.

1 голос
/ 08 июня 2011

Я бы предложил немного переписать контроллер и модель, чтобы сделать процесс более логичным и обеспечить лучшую производительность:

Контроллер:

function remove_link()
{
    if ($this->input->post('link_id'))
    {
         //Validation
         $this->form_validation->set_rules('link_id', 'Link ID', 'is_natural_no_zero');
         if ($this->form_validation->run())
         {
             $seg = 'user_links'; //do you really need to assign it to variable ??
             $this->load->model('Profile_model');
             if ($this->Profile_model->links_delete($this->input->post('link_id')) //send link id to model function
             {
                 redirect('/profile/user_links'); // redirect user in controller and only when model returns true
             }else{
                 // inform user about error somehow, eg. by setting session flashdata and redirecting back to /profile/user_links
             }
        } 
    } // else statement here was a mistake as in case of form_validation failure nothing happened
    $this->load->model('Profile_model');
    $links_data['query'] = $this->Profile_model->links_read(); //get links from db to add in view
    $this->load->view('profile/edit_links_view', $links_data);
}

Модель:

function links_delete($link_id)
{
    $this->db->where('user_id', $this->tank_auth->get_user_id())
             ->where('link_id', $link_id)
             ->delete('user_links'); // you can chain methods without writing always $this->db->
    return $this->db->affected_rows(); // returns 1 ( == true) if successfuly deleted
}

И в качестве примечания в вашем коде jQuery я предлагаю использовать $ ('# some_id') вместо $ ('input [name = XXXX]') - это сохраняет выполнение некоторого кода JavaScript, таким образом, быстрее

1 голос
/ 07 июня 2011

Единственное, что я вижу неправильно, это то, что вы не проверяете, кто может и не может удалять записи. Это единственная проблема, на которой вы должны сосредоточиться. Разрешения на проверку, разрешено ли лицу, отправляющему запрос на удаление, выполнять такие операции. Кроме этого, это просто вопрос предпочтений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...