patternphpMinor
Preventing SQL injection without using prepared statements
Viewed 0 times
withoutsqlstatementspreparedusinginjectionpreventing
Problem
I'm learning OOP and totally new to this way of coding. I've always scripted PHP the procedurial way. Now I've written a working class, which creates a database connection and has the method to create a query which is impossible to SQL-inject by hexing the non-integer data. (I know how to use prepared statements, but i just don't want to use them because there is a slight performance penalty in my case)
Note: When hexing data the right way, its not possible to inject.
Have a look at Zaffy's answer.
My questions:
And I must say, I've read multiple tutorials, but it's really difficult to fully understand howto write OOP style if you've never done before!
databaseconnection.class.php
```
host = $host;
$this->user = $user;
$this->pass = $pass;
$this->dtbs = $dtbs;
$this->conn = new mysqli($this->host, $this->user, $this->pass, $this->dtbs);
if ($this->conn) {
return $this->conn;
} else {
return false;
}
}
public function query($sql, $data) {
$this->data = $data;
$this->sql = $sql;
foreach ($data as $val) {
if (strpos($this->sql, "'%i'") !== false || strpos($this->sql, "'%s'") !== false || strpos($this->sql, '"%i"') !== false || strpos($this->sql, '"%i"') !== false) {
echo "SQL incorrect: There can't be any quotes around the parameters, because this function does that automaticly for you";
exit();
}
$pos = strpos($this->sql, '%');
$type = substr($this->sql, $pos, 2);
if ($type == '%i') {
if (is_int($val)) {
$this->sql = substr_replace($this->sql, $val, $pos, 2);
} else {
Note: When hexing data the right way, its not possible to inject.
Have a look at Zaffy's answer.
My questions:
- What could I've done better?
- Is it 'wrong' to use this class because its not good OOP (besides its function), or does it not really matter, because it works as how i want it to work? (nobody else is going to maintain the script)
And I must say, I've read multiple tutorials, but it's really difficult to fully understand howto write OOP style if you've never done before!
databaseconnection.class.php
```
host = $host;
$this->user = $user;
$this->pass = $pass;
$this->dtbs = $dtbs;
$this->conn = new mysqli($this->host, $this->user, $this->pass, $this->dtbs);
if ($this->conn) {
return $this->conn;
} else {
return false;
}
}
public function query($sql, $data) {
$this->data = $data;
$this->sql = $sql;
foreach ($data as $val) {
if (strpos($this->sql, "'%i'") !== false || strpos($this->sql, "'%s'") !== false || strpos($this->sql, '"%i"') !== false || strpos($this->sql, '"%i"') !== false) {
echo "SQL incorrect: There can't be any quotes around the parameters, because this function does that automaticly for you";
exit();
}
$pos = strpos($this->sql, '%');
$type = substr($this->sql, $pos, 2);
if ($type == '%i') {
if (is_int($val)) {
$this->sql = substr_replace($this->sql, $val, $pos, 2);
} else {
Solution
- never
returnfrom constructor
- avoid having
newstatements in the constructor
- on error, throw an exception instead of
echo+exit
%is used in MySQL'sLIKEsyntax
- you should refactor your
DatabaseConnection::query()method - it's too high cyclomatic complexity
- constants are global immutable state (it's not as bad as mutable globals, but still a bad idea)
- you should be using
spl_autoload_registerinstead of the archaic__autoload
- you are mixing HTML with logic .. bad idea, try this approach instead
- don't use ".class.php" in filenames, because then you will be screwed, when you start adding interfaces (which one would want to autoload too)
Context
StackExchange Code Review Q#123511, answer score: 3
Revisions (0)
No revisions yet.