How to not insert the values if same question_text exist but not for the first_word.
Example (The question_text is the whole sentence and the first word is the first word in the sentence.)
He is crazy. //insert
He is smart. //insert
He is smart. //exist don't insert
$first_word = current(explode(' ', $_POST['question_text']));
mysql_query("INSERT INTO questions (question_id,question_text,field_name)
VALUES ('','$_POST[question_text]','$first_word')");
You could run this SQL once query to prevent double entries with the same content:
ALTER TABLE questions ADD UNIQUE(question_text);
You can't do that with this query. You need to write another query first to check for the existence of the row you don't want to duplicate.
Also, the code is vulnerable to SQL injection attacks. See here for information on how to fix that: Protect against SQL injection
MySQL has the INSERT ON DUPLICATE KEY UPDATE statement, which you could use. But in the example you posted it would probably not be a good way to do it.
Related
i just switched over from a Mysql server to SQL server. But i just found out that INSERT INGORE INTO doesn't work with sql server.
Original code:
INSERT IGNORE INTO DATA_EXACT_INVENTORY_LOCATIONS (ID, Code, Opslaglocatie, Omschrijving, OpVoorraad)
VALUES ('$inventorylocationID','$inventorylocationsItemCode','$inventoryStorageLocationsCode','$inventorylocationsItemDescription','$inventorylocationsCurrenctStock')
I found out that i can use on duplicate key update, but the problem is that i have sql query's with upto 50 variables. So to use on duplicate key update would be alot of work. So what i was wondering is there a better alternative for INSERT IGNORE INTO that's is just plug and play so i don't have to write all variables again.
You can use not exists:
INSERT DATA_EXACT_INVENTORY_LOCATIONS (ID, Code, Opslaglocatie, Omschrijving, OpVoorraad)
SELECT ID, Code, Opslaglocatie, Omschrijving, OpVoorraad
FROM (VALUES ('$inventorylocationID', '$inventorylocationsItemCode', '$inventoryStorageLocationsCode', '$inventorylocationsItemDescription', '$inventorylocationsCurrenctStock')
) V(ID, Code, Opslaglocatie, Omschrijving, OpVoorraad)
WHERE NOT EXISTS (SELECT 1
FROM DATA_EXACT_INVENTORY_LOCATIONS deil
WHERE deil.id = v.id -- or whatever column gets the duplicate key
);
Alternatively, you could rewrite the code to use MERGE. The SELECT should work in both databases.
Let me also add that you should learn to use parameters. Munging query strings with constant values exposes your code to SQL injection attacks and to hard-to-debug syntax errors.
I have made a makegroup.php site which is supposed to create a group, and put the person in the connection table between UserID and GroupID.
..but I am not sure how to go on. The logged in user is saved in session variable $usid, but how what about GroupID? How do I fetch that right after on another page? Need I make this in steps? Including quick DB scheme.
Thanks in advance.
I guess GrouID is autonumeric?
So you leave db create the id for you.
Also loos like you are trying to concat the $groupname value
$sql = "INSERT INTO group (Groupname) VALUES ('".$groupname."') ";
But you dont want do that because that method is vulnerable to SQL Injection attack
Use parametrized values instead
How can I prevent SQL injection in PHP?
I have the following code, which is vulnerable to SQL injection(I think?):
$IDquery = mysqli_query($connection, "SELECT `ID` FROM users WHERE username=$usernamelogin");
I don't escape the $usernamelogin, and that is not a parameterized query. This obviously needs to be fixed, you don't need to point that out, that isn't what this question is about. Before I fix it, I want to make sure I understand how an SQL injection works as well as possible. So, I tried creating a table named "droptable" and inputting the following into the username input:
x; DROP TABLE droptable;
Which I believe should input this SQL query:
SELECT `ID` FROM users WHERE username=x; DROP TABLE droptable;
However, droptable still exists, and the rows in it are untouched. Could anybody tell me why?
mysqli_query() doesn't support multiple query execution.
You don't have quotes around $usernamelogin so when you supply a string that would produce an error. Either add quotes or supply a number
I know nothing about SQL injection apart from the process to block it.
I was wondering, if an attacker would modify my prepared statement from:
$DB = $Con->prepare("SELECT * FROM Test WHERE username=?");
$DB->bind_param('s',$Username);
$DB->execute();
And his statement he entered was:
x' DROP TABLE Test
How would the bind/prepared statement process this request?
Would it return an error or continue? as the bind_param links specific values to said SQL Statement?
No, the database would simply look for a record that has a username of x' DROP TABLE Test so you would probably end up with an empty result set.
When using bind_param, the values will be escaped for you. You should still validate the data to make sure it's correct, but it's safe from injection
Once you prepare a statement, it is pre-compiled. So any parameters you bind to it are sent as raw data and in no way could modify the SQL statement.
Your example would work fine, it would select all rows with the username x' DROP TABLE Test.
The script is in PHP and as DB I use MySQL. Here is the script itself.
$unsafe_variable = $_GET["user-input"];
$sql=sprintf("INSERT INTO table (column) VALUES('%s')",$unsafe_variable);
mysql_query($sql);
Some people say that if user assigns ;DROP TABLE blah; string to the variable $unsafe_variable it deletes the table.
But I tried this example,
http://localhost/test.php?user-input=DROP%20TABLE%20my_table
But it didn't delete the table but instead inserted a new row (;DROP TABLE blah;) in the table.
Could anybody explain me how it is possible to attack this script with sql injections?
That particular injection wouldn't work since PHP's mysql_query function only allows one query per call. However, the following may work if column has a primary or unique key:
$unsafe_variable = "admin') ON DUPLICATE KEY UPDATE password=MD5(CONCAT('knownsalt', 'newpassword'))#";
Better to use the long-winded mysql_real_escape_string function:
$sql=sprintf("INSERT INTO table (column) VALUES(%s)",
mysql_real_escape_string($unsafe_variable));
mysql_query($sql);
mysql_query() doesn't allow the execution of multiple queries in one function. So you can't INSERT and then DROP the table. But you shouldn't rely on this as 'security'. Use parametrized queries instead. Check out PHP's PDO library.
However, they could change just about anything else, like possibly SELECTing a password field from another table as a subquery to place into that table so they can view the hash.
While mysql_query only allows one query to execute, in general this query is not safe. An example of a dangerous input that would exploit your query is:
'); DROP TABLE my_table; --
The '); at the start will close your query and insert an empty value, but will allow for additional queries to be executed following the INSERT. Then after dropping a table, the -- at the end will mark everything else following (ie. the rest of your query) as a comment.
In order to safely prepare input for use in a query, use mysql_real_escape_string.
The ONLY way you should be handling unsafe variables is with bind parameters.
Please read this page on how to prevent SQL injection from bobby-tables.com.
Nope, sprintf doesn't escape the content use:
$unsafe_variable = mysql_real_escape_string($_GET["user-input"]);
$sql=sprintf("INSERT INTO table (column) VALUES('%s')",$unsafe_variable);
mysql_query($sql);
mysql_real_escape_string($unsafe_variable)
Some people say that if user assigns ;DROP TABLE blah; string to the variable $unsafe_variable it deletes the table.
Patently that's not the case - but if you don't understand why, then you can't tell if your code is safe. Are you going to post every line here to check if its safe?
Without going into a long explanation about what the code above is doing and how to compromise it (SQL injection is already very well documented elsewhere - try Google for a start) you should ALWAYS ensure that any data leaving your PHP code is in the correct representation for where it is going.
For a MySQL database that means either:
1) use the output of mysql_real_escape_string (and make sure you pass the right resource handle)
or
2) use parameter binding.
A proper discussion of code injection attacks could easily fill several hundred pages - a bit much to answer in a S.O. query.
C.
I think the example you would need to try is http://localhost/test.php?user-input=';DROP%20TABLE%20my_table'
the '); closes the values('%s segment, and then issues a new command, drop table...