Reputation: 771
I'm building an application with Laravel 5.5 and I have to run some SQL queries for extended PostgreSQL which are not supported by Eloquent ORM (PostGIS). Instead, I use DB::statement($queryString); to insert data into database. $queryString is built from input variables concatenated with pre-built SQL statement.
Here is the code from my controler (note that actual query is more complex, this is just an example):
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$id= $request->input('id');
$name= $request->input('name');
$geom = $request->input('geom');
$geom = DB::raw("ST_TRANSFORM(ST_GeomFromGeoJSON('".$geom."'), 3857)");
$statement = "INSERT INTO tableName(id, name) VALUES ('".$id."', '".$name."', ".$geom.");";
DB::statement($statement);
return 'Insert Successful';
}
I have two question about this approach:
How can I protect my application from SQL injection attacks?
How can I check if query ran successfully? DB::statement doesn't seem to return anything.
Upvotes: 5
Views: 53035
Reputation: 11
I had similar challenge a few years back and I used a mix of parameter binding s & prepared statements. For the second question, you could also add a try-catch block to see if it generates any exception, apart from wrapping the code inside a transaction - I follow this practice working on Laravel with MongoDB.
Upvotes: 1
Reputation: 5764
In general, according to OWASP, there are four ways to protect against SQL injection.
In your case, for Laravel 5+ where the Eloquent ORM will not work directly, I think the best option is #1, Prepared Statements.
More specifically, in Laravel you can achieve it's built in Query Builder to either iteratively build statements or execute a completely raw SQL statement with
DB:: select ( [raw query string] )
SOURCE
SO Post: Laravel, execute raw queries
Upvotes: 4
Reputation: 358
you can make this after importing
use Illuminate\Support\Facades\DB;
you can right your query like that
$quert=DB::insert('insert into tablename (columnname1,columnname2,) values (?,?)',[$id,$username]);
and if you wanna insert whole data to table but when is there is no data in table except id and user name
$quert=DB::insert('insert into tablename values (?,?)',[$id,$username]);
the question mark is question mark ? :D dont put any input here and you are welcome
edited:
about How can I protect my application from SQL injection attacks? you can make this from middlewares ,using Cross-Site Scripting like
{% raw %} {{}} {% endraw %}
with CSRF
<form ...>
{!! csrf_field() !!}
</form>
for second question you have multi thing
1- easy way
you can return your query if you select it will return selection if it inserted/updated/deleted it will be true if not it will be false
return response()->json([
'Message'=>'what ever you wanna write',
'Data' => $query,
], 200);
2- hard way (i prefered :D)
you can use DB::listen for debugging
DB::listen(function ($query) {
// $query->sql
// $query->bindings
// $query->time
});
Upvotes: 8
Reputation:
1, use parameter bindings to safeguard your queries. Example:
$users = DB::select('select * from users where active = ?', [1]);
https://laravel.com/docs/5.5/database#running-queries
As for #2, wrap your queries in database transactions. That will protect against failures. Example:
DB::transaction(function () {
DB::table('users')->update(['votes' => 1]);
DB::table('posts')->delete();
});
Upvotes: 2