How to prevent SQL Injection in Laravel 5.4 - php

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?

Related

PHP MYSQL/PDO mocking interaction/data

Recently getting back up-to-speed with unit testing. Been scouring the net for a good mock PDO SQL class for interactions/data but can't seem to one that doesn't require you to parse what the raw sql is into the mock obj during the test script.
This might be okay for some, but IMO it takes too much away from the test script (I'm trying to minimize complications to help sell the concept to my team at work)
Ideally I'd expect the test to look more like this:
public static function setUpBeforeClass()
{
// Use PDOMock version in replace of all PDO calls
PDOMock::initMockMode();
// Potentially drive data provider from a file
$data = [
[
'id' => 1,
'total' => 1,
],
[
'id' => 2,
'total' => 1,
],
[
'id' => 3,
'total' => 10,
],
];
PDOMock::setTableData('db.example_table', $data);
}
public function testSqlMock()
{
// Presumming the sumTableValues() method runs a simple sum query over the db.example_table using the regular \PDO class
$total = TestClass::sumTableValues();
$this->assertEquals(12, $total); // assertion passes due to PDOMock class using set data over live mysql data
}
It doesn't really need to have the fancy PDOMock::initMockMode() logic either as I can compromise by adding a setMockMode() in my sqlclass to just use the mocked version instead of \PDO
Hope this makes sense; any ideas/suggestions are greatly appreciated!

Elegant solution to create a Post when request attributes change

I am wondering how I can implement this the best way:
I have a site where a user can make a post, he has 2 checkboxes there for "resumes" and "more documents". Those two are not required, but when they are I need to save a "true" in the database in the column for this.
I thought I could implement it by writing if loops, like:
if both are present this code:
Post::create([ 'resumee' => true, 'more_docs' => true,]);
If only resume is present like this:
Post::create(['resumee' => true, 'more_docs' => false]);
and if only more_docs is present then the other way around.
however I figured there would be a way better approach to implement this, but I am fairly new to laravel so I cant think about any.
My first guess was to do something like this inside the create statement:
Post::create([
'resumee' => true,
if($request->has(more_docs)
'more_docs' => true,
else ....
]);
But all I got were red lines haha. So maybe someone of you more experienced guys have an idea, any help appreciated!
You can use something like this:
Product::create([
// ... other fields
'resumee' => $request->filled('resumee'),
'more_docs' => $request->filled('more_docs'),
]);
If you would like to determine if a value is present on the request and is not empty, you may use the filled method. I think this mthod will more appropriate for your task.

Cakephp need session var in model

I give. Been searching and trying different stuff for hours.
Using Cakephp 2.3.5.
I'll get straight to it.
I want to use a session variable in my Category model, but it doesn't like it when I try any of the following...
$this->Session->read('market_id')
CakeSession::read('market_id')
SessionHelper::read('market_id')
Here is the model snippet where I'm trying to use it...
public $hasAndBelongsToMany = array(
'Vendor' => array(
'className' => 'Vendor',
'joinTable' => 'categories_vendors',
'foreignKey' => 'category_id',
'associationForeignKey' => 'vendor_id',
'unique' => 'keepExisting',
'conditions' => array( 'market_id' => ???? )
)
);
I'm stuck like a wheelbarrow in the mud. I've read countless opinions of why I shouldn't use session data in the model, but this makes perfect sense to me since it will never be called without this value set, and it should never return anything other than the vendors with that market_id. But that value does change.
I'm completely guilty of doing everything I can to avoid messing with my models. The whole skinny controller idea... yea... nice thought, but I just haven't figured it out yet. And so it goes. The first time I try to modify a model... I can't figure out how.
I've read countless opinions of why I shouldn't use session data in the model
That's correct. It will cause tight coupling as well and make it harder to test. And it's not only valid for models but everything. Don't create tight coupled code.
It is better to pass data and objects around. For example:
// Model Method
public function getSomething($someSessionValue) { /*...*/ }
// Controller
$this->SomeModel->getSomething($this->Session->read('something'));
If you need your data in a lot methods you can set it:
public function setSomeModelProperty($value) {
$this->_someProperty = value; // _ because it should be protected, the _ is the convention for that in CakePHP
}
However, I personally would very like go for passing the data to each method. But it depends on the whole scenario.
And you can't do this any way because it will cause a syntax error. You can't use variables or properties in the property declaration.
'conditions' => array( 'market_id' => ???? )
So bind it later by a method like
public function bindVendors($marketId) {
$this->bindModel(/*...*/);
}
when needed.
Or even better, simply use the conditions only when needed and declare them in your find options:
[
'contain' => [
'Vendor' => [
'conditions' => /* conditions here */
]
]
]

How to implement a PHP Form processing logic that is reusable?

I am new to PHP and I have a lots of forms in PHP. The forms make use of the standard HTML Input fields and need to be validated on the serverside. How can I implement this, so that I do not have to write lots of boilerplate HTML over and over again, rather only write the minimal amount of code that generate the "full forms". What is the recommended approach to implement this? Thanks.
If you prefer to do it all yourself, you should at least do it PHP-Classes which will save you from re-writing (if done right ;-)). Handle attributes of the fields through an assoc array, e.g. like this:
<?php
$form = new Form("MyInput", array ("submit" => "myform.php") );
$form->AddField("input_text", array ("label" => "Your name") );
?>
To handle validation, you could use attributes such as
$form->AddField("input_text", array (
"label" => "Your name" ,
"validate" => "required"
) );
(Only examples, there's a lot of code releated to this which you'd need to write once...)
That should be useful for learning purposes...
Next, you could use JS to validate. Pls. note that JS does client-side validation only and you cannot rely on it being executed (user might have turned of JS in his browser), so you still MUST validate in PHP when receiving the data. (And you could use JS-Libraries for that - I've used Parsley and was quite happy with it...)
If you want to skip that experience, use Frameworks or Templating Engines.
I would suggest to create a form template. Consider using a method (of class View):
private static function capture($view_filename, array $view_data)
{
extract($view_data, EXTR_SKIP);
ob_start();
require $view_filename;
return ob_get_clean();
}
And call the static function capture (caution: consider using of __toString() to print objects) Pseudo-code:
echo View::capture('template', array('id' => '1', 'class' => 'userForm', 'inputs' => array(0 => array('label' => 'Name', 'type' => 'text'), 1 => array('label' => 'Password', 'type' => 'password')));

Member based sites security issue in codeigniter

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)

Categories