简体   繁体   中英

Is this form using radio buttons safe from SQL Injection?

I'm trying to make a dynamic search feature on my website, where the user can choose to look up claim information based on ID, Make, Model, or Date. There is a search bar to type in the data and the radio buttons provide the search filter.

I'm wondering if my simple if-statement approach has vulnerabilities to SQL injection since I'm passing in the variable directly as the column name (PDO won't let you pass this value in as a parameter as I understand it)

HTML CODE:

    <form method="POST" action="find-claims.php">
        <label for="find-claim">Find Claim:</label>
        <input type="search" id="claim-search-bar" name="claim-search-bar"><br/>
        <input type="radio" value="by-id" class="radio-param" name="search-param" checked><label for="by-id">By Claim Id</label>
        <input type="radio" value="by-make" class="radio-param" name="search-param"><label for="by-make">By Vehicle Make</label>
        <input type="radio" value="by-model" class="radio-param" name="search-param"><label for="by-model">By Vehicle Model</label>
        <input type="radio" value="by-date" class="radio-param" name="search-param"><label for="by-date">By Claim Date</label>
        <input type="submit" class="radio-param" value="Submit">
    </form>

PHP CODE:

// Get search data
$searchVal = $_POST["claim-search-bar"];

// Get radio value
$searchType = $_POST["search-param"];

// Store search type into db-naming scheme
$radioVal = "";
if($searchType == "by-id"){
    $radioVal = "claim_id";
}
else if($searchType == "by-make"){
    $radioVal = "make";
}
else if($searchType == "by-model"){
    $radioVal = "model";
}
else if($searchType == "by-date"){
    $radioVal = "date_received";
}

// DB Interaction
try{
    // Connection to DB
    require "../db-info.php";
    $dbh = new PDO("mysql:host=$serverName; dbname=$dbName", $userName, $password);
    $dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

    // Get Claim based off dynamic input
    $getClaim = $dbh->prepare("SELECT * FROM claims WHERE $radioVal = ?");
    $getClaim->bindParam(1, $searchVal);
    $getClaim->execute();
    $claimInfo = $getClaim->fetchAll();

    // Checks if DB returned any data
    if($claimInfo){
        // Display corresponding info
    }
    else{
        echo "sorry no claim found";
    }

    $dbh = null;
    $stmt = null;

} catch(PDOException $e){
    throw new \PDOException($e->getMessage(), (int)$e->getCode());
}

You can store the search values in the array. Along with removing the useless try-catch it will make your code two times less bloated.

// Get search data
$searchVal = $_POST["claim-search-bar"];

// Get radio value
$searchType = $_POST["search-param"];

// Store search type into db-naming scheme
$searchValues = [
    "by-id" => "claim_id",
    "by-make" => "make",
    "by-model" => "model",
    "by-date") => "date_received",
];
$radioVal = $searchValues[$searchType] ?? "claim_id";
// Connection to DB
require "../db-info.php";
// the connection code should really go into include

// Get Claim based off dynamic input
$getClaim = $dbh->prepare("SELECT * FROM claims WHERE $radioVal = ?");
$getClaim->execute([$searchVal]);
$claimInfo = $getClaim->fetchAll();

// Checks if DB returned any data
if($claimInfo){
    // Display corresponding info
}
else{
    echo "sorry no claim found";
}

Because $radioVal is only assigned literal values you wrote in your code, and it is never assigned any untrusted content, it is safe with respect to SQL injection.

However, I recommend you give it a better default other than "" . Because if none of the known values for $searchType are matched, then $radioVal will remain "" and you'll get an SQL statement of:

SELECT * FROM claims WHERE  = ?

That'll be a syntax error. It won't be due to SQL injection, but it won't work.

And by the way, you do not need to sanitize $searchVal . That's the point of using a bound parameter, that it is bound after the query is prepared, so it cannot introduce SQL injection. It doesn't matter if it's sanitized or not.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM