Hi friends I am just wondering what security should i keep in mind when users on my site post anything using form. I have encrypted codeigniter session and also enabled the feature to store session in database, and my example Model function is like this in below. I have enabled form validation and enabled xss and csrf globally.
I think sql injection is automatically handled by CI's active record function. Please suggest me what else do i have to check before taking this site in production. Thanks
function AddSomeMemberPost(){
$now = date('Y-m-d H:i:s', strtotime('now'));
$data = array(
'topic' => $this->input->post('title'),
'status' => 'draft',
'content' => $this->input->post('body'),
'category_id' => $this->input->post('categoryid'),
'featured' => '0',
'lang' => $this->input->post('lang'),
'pubdate' => $now,
'video' => $this->input->post('tube_video'),
'user_id' => $this->session->userdata('user_id'),
'username' => $this->session->userdata('username')
);
$this->db->insert('my_table', $data);
validation are done this way, Do i need to validate session data btw ? It is going thru model.
$this->form_validation->set_rules('topic', 'Topic', 'required|min_length[8]|max_length[90]');
$this->form_validation->set_rules('content', 'Content', 'required|min_length[8]');
$this->form_validation->set_rules('tags', 'Tag', 'required|miax_length[50]');
$this->form_validation->set_rules('video', 'Youtube Video Link', 'min_length[8]');
It is recommended that you change the PHP error reporting level, which is set in the main /index.php file.
error_reporting(0)
NOTE: You can set this in a hook instead, so you can leave the standard CI files unchanged.
In general, you should clean ALL data before putting it into any SQL (including data used in a session), even when using the built-in CI DB functions. For example, you should always cast numbers before adding them to SQL
$val = (int)$val;
(NOTE: For performance you can check if these values are even in a valid range before attempting to run a query, to save yourself from running queries you know will return nothing. For example, if you're searching for a value that is a positive integer, then you don't need to run a query if $val <= 0)
Related
I have a classical index page with a form where I can filter my records.
One of my fields is year. Let's say that I want the records to be pre-filtered by current year when the user first visit the page (i.e. when the query string is empty)
what have I done:
in my controller I did something like this
if(empty($this->request->query))
{
$this->request->query['year'] = date('Y');
}
and then with the help of friendsofcake/search plugig:
$this->MyTable->find('search', [
'search' => $this->request->getQuery()
]);
In this way the records are filtered and the form is pre compiled with the current year since in my view I have
'valueSources' => 'query'
Now with cake 3.6 direct modification of the query is deprecated (see this issue I opened). In fact I get deprecation warnings when I try to change the query array.
My question:
So I want to know what is the best way to achieve the same behavior without getting warnings. I would also like to know if and why my approach is wrong.
In controller:
$searchValues = $this->request->getQueryParams() ?: ['year' => date('Y')];
$this->MyTable->find('search', [
'search' => $searchValues
]);
$this->set(compact('searchValues'));
In template:
$this->Form->create(['schema' => [], 'defaults' => $searchValues]);
Ideally you would also set proper values in schema as shown here https://api.cakephp.org/3.6/class-Cake.View.Form.ArrayContext.html
Try something like this (not tested):
$this->setRequest($this->getRequest()->withQueryParams([
'year' => date('Y'),
]);
I am using Laravel 5.4. I have a form where I take some inputs from user. The form variables are directly inserted into database. I want to make sure the sure does not enter anything that could harm the database. I have heard of something SQL Injection but I don't know much about it.
This is my function.
public function insert_data(Request $request)
{
$company_details_data = ['job_id' => $maxID,
'company_id' => $company_id,
'job_title' => ucwords($request>input('job_title')),
'vacancy_no' => $request->input('vacancy_no'),
'category_id' => $request->input('category_id'),
'job_type_id' => $request->input('job_type_id'),
'city_id' => $request->input('city_id'),
'travel_required' => $request->input('travel_required'),
'other_locations' => ucwords($request->input('other_locations')),
'no_vacancy' => $request->input('no_vacancy'),
'job_salary' => $request->input('job_salary'),
'date_expiry' => $request->input('date_expiry'),
'job_details' => $request->input('job_details'),
'date_posted' => date('Y-m-d'),
'qualification_required' => $request->input('qualification_required'),
'experience_required' => $request->input('experience_required'),
'skills_required' => $request->input('skills_required'),
'apply_guidance' => $request->input('apply_guidance'),
'duty_responsibilities' => $request->input('duty_responsibilities')
];
General_model::createrecord($company_details_data,'job_details');
}
This is the createrecord() function in my model:
public static function createrecord($data,$tbl)
{
return DB::table($tbl)->insert($data);
}
I want to use htmlspecialchars here but I am using a rich texteditor in my form. If I use htmlspecialchars it will also change the unharmful tags like ,< p >, < br >,etc. Please Help
Without being able to see the methods on your model that take this data and actually push them into the DB its difficult to tell.
Ideally you'd want to sanitize your data prior to handing it to any class. Also you'd want to make sure your models if not already using an existing ORM were using something akin to PDO for your database interactions.
See the answers to the following question as to what sanitizing a request for the DB actually entails.
EDIT:
As others have pointed out, it most likely makes more sense here to use an ORM like Eloquent in laravel that handles a lot of this for you.
What's the best method for sanitizing user input with PHP?
I have a codeigniter application that I am using the Cart class to make an e-commerce store.
I am also using Codeigniter-Auth (a library) to make accounts on this system. I have noticed when I log out while testing the application, the session data for the shopping cart is also destroyed.
I noticed in the library this is how it logs the users in:
$data = array(
'id' => $row->id,
'name' => $row->name,
'email' => $row->email,
'loggedin' => TRUE
);
$this->CI->session->set_userdata($data);
And this is how it logs the user out:
return $this->CI->session->sess_destroy();
How do I tell codeigniter to only destroy the user session and not every session in the system?
Using:
$data = array(
'id' => $row->id,
'name' => $row->name,
'email' => $row->email,
'loggedin' => TRUE
);
$this->session->set_userdata($data); // instead of $this->CI->session->set_userdata($data);
You are actually setting 4 session variables! To unset a specific one, use:
$this->session->unset_userdata('loggedin');
I believe you can just use $this to refer to CodeIgniter's instance. You must also assign a "name" to your session data (variable) to be able to specifically unset it.
$this->session->set_userdata('sample_userlog',$data);
$this->session->unset_userdata('sample_userlog');
Hope this helps.
The documentation states to clear the current session use
$this->session->sess_destroy();
Note: This function should be the last one called, and even flash variables will no longer be available. If you only want some items destroyed and not all, use unset_userdata().
For example $this->CI->session->unset_userdata($data).
I am using the Active Record in Code Igniter and I have the following code in my controller for my profile:
$data = array(
'first_name' => $_POST['first_name'],
'last_name' => $_POST['last_name'],
'email_address' => $_POST['email_address'],
'gravatar_email' => $_POST['gravatar_email']
);
$this->db->where('user_id', $session_data['id']);
$this->db->update('user_profiles', $data);
redirect('profile', 'refresh');
How do I do the redirect only if the update was successful or not? Also I would like to display a message to my user.
First of all, you shouldn't be accessing $_POST directly, there are helpers for that ($this->input->post('name') since they sanitize the data when used properly).
Secondly, you use something like $this->db->affected_rows(); to determine how many rows were changed and then judge what happened.
In your update, you might update 1 element, or x, you need to test for that before doing a redirect.
Hope that helps, when all else fails, read the CI guide, it is very well written.
Reference:
Query Helpers
Input Class / POST / GET etc;
I have read about authentication in Lithium manual, still I have some questions about it.
After Auth::check ('default', $this->request), it will return an array of user data if succeed. I have finished this part according to the manual.
if I want to save some of this array into session (not all of them), how to do it?
Are those data in session encrypted? If not, how could I manipulate it, I want to encrypt it for security concern.
Thanks.
This should give you something to go on regarding encrypting session data - http://nitschinger.at/Session-Encryption-with-Lithium.
As far as telling Auth::check() which fields to save to the session:
Auth::config(array(
'default' => array(
'session' => array(
'persist' => array('username', 'email')
)
)
));
This is in the latest master, and there is more explanation at the top of security\Auth.php.