I'm having a problem using $wbdb. When I insert or update data using $wpdb->insert or $wpdb->update, the SQL injection protection actually inserts the \' into the database, and when outputting that information it has the SQL escape with it. (ie: My Value\'s Escaped).
I know there's gotta be a way to escape this using a wordpress function, but I haven't been able to find it searching google and the wordpress codex. ...So what's that function, or what am I doing wrong (seems like the '\' shouldn't really get to the database in the first place) Thanks!
It looks as if magic_quotes are enabled on the server you are using.
There are a number of SO questions and answers that deal with what they are, why they're bad, and how to get rid of them, so I won't explicitly explain here, but suggest you look at a few of the following:
Magic quotes in PHP
Work around magic quotes, or just make sure they're off?
How can I disable PHP magic quotes at runtime?
How to turn off magic quotes on shared hosting?
PHP protecting itself from SQL injections?
Related
I'm learning about SQL Injection. And sometime I read in some document that we have to use unhex(hex()) function when exploit in URL address.
And my question is, why we have to use it?
First off, it cannot help you with SQL injection. If SQL injection is impossible, then no hex/unhex/whatever function will make it possible.
It can only help to exploit an existing SQL injection, when a site is protected by a very silly protection method like a black list disallowing a single quote in the input. So these functions can help to avoid using a quote or any other "malicious word" that may alert the filter.
But honestly, I cannot imagine a developer in 2018 using a black list filterig against SQL injection instead of prepared statements for the data/a white list for the everything else
I just stumbled across this gem in our code:
my $str_rep="lower(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(field,'-',''),'',''),'.',''),'_',''),'+',''),',',''),':',''),';',''),'/',''),'|',''),'\',''),'*',''),'~','')) like lower('%var%')";
I'm not really an expert in DB, but I have a hunch it can be rewritten in a more sane manner. Can it?
It depends on the DBMS you are using. I'll post some examples (feel free to edit this answer to add more).
MySQL
There is really not much to do; the only way to replace all the characters is nesting REPLACE functions as it has already been done in your code.
Oracle DB
Your clause can be rewritten by using the TRANSLATE function.
SQL Server
Like in MySQL there aren't any functions similar to Oracle's TRANSLATE. I have found some (much longer) alternatives in the answers to this question. In general, however, queries become very long. I don't see any real advantages of doing so, besides having a more structured query that can be easily extended.
Firebird
As suggested by Mark Rotteveel, you can use SIMILAR TO to rewrite the entire clause.
If you are allowed to build your query string via Perl you can also use a for loop against an array containing all the special characters.
EDIT: Sorry I did not see you indicated the DB in the tags. Consider only the last part of my answer.
Your flagged this as Perl, but it's probably not?
Here is a Perl solution anyway:
$var =~ s/[\-\.\_\+\,\:\;\/\|\\\*\~]+//g;
Sorry I don't know the languages concerned, but a couple of things come to mind.
Firstly you could look for a replace text function that does more that just a single character. Many languages have them. Some also do regular expression based find and replace.
Secondly the code looks like it is attempting to strip a specific list of characters. This list may not include all that is necessary which means a relatively high (pain in the butt) maintenance problem. A simpler solution might be to invert the problem and ask what characters do you want to keep? Inverting like this sometimes yields a simpler solution.
I am a noob when it comes to understanding some of the attacks in SQL injection. I am currently seeing this attack in my log and was wondering if anyone can help me understand what it means
SQL Injection:
410'union/**/select/**/1/**/from/**/(select/**/count(*),concat(floor(rand(0)*2),0x3a,(select/**/concat(user,0x3a,password)/**/from/**/pwn_base_admin/**/limit/**/0,1),0x3a)a/**/from/**/information_schema.tables/**/group/**/by/**/a)b/**/where'1'='1.
Dont understand this completely, but the select concat(user,0x3a,password) from pwn_base_admin clearly tries to get a concatenated string of user names and passwords, divided by a ":"
The concat(floor(rand(0)*2),0x3a,( roughly does the same... the result would be something like 1:aUserName:UsersPassword.
If you need further help please give some more details (RDBMS, the part before the "union"...)
Hope this helps
Someone is actively trying to gain unauthorized access to your system - they're hacking in.
I don't know how critical this system is, but if it is of any importance, you should probably take the system offline until you sort out the database access part of the code. The first place to look for solutions is using bind parameters instead of string concatenation for your sql queries.
There are many resources available that describe how to use bind variables for whatever RDBMS you're using, but here is one article I found to get you started:
http://use-the-index-luke.com/sql/where-clause/bind-parameters
What is the SQL MODE in MYSQL (or any RDBMS)? Also what is the best option to have for the SQL MODE and Why?
If i could have a layman explanation with a example it would be great!
Thank you in advance ;-)
The SQL mode affects how MySQL behaves in certain situations. For example, it affects what happens if you try to insert overlong content into a text type column. Let's say you have a column like CHAR(10) CHARACTER SET ascii NOT NULL, and you try to insert 'abcdef abcdef'. That's 13 characters, which is too long. If the current SQL mode includes STRICT_TRANS_TABLES or STRICT_ALL_TABLES, MySQL will not insert the value but will give you an error message. If neither of these is on, then MySQL will truncate the string to 10 characters, i.e. 'abcdef abc', and insert that.
There are lots of other behaviours that are affected by the SQL mode. That was just an example.
I personally use TRADITIONAL, which is shorthand for, well, the link given by dcp will tell you. Basically, it makes MySQL less forgiving when you send it invalid input, which I find preferable because if I send MySQL something that's not valid I'd rather know about it, rather than have MySQL fudge it and not tell me it's done so.
It's always best to refer to the official documentation.
You can also use the FAQ.
In simple terms, it basically controls the type of SQL syntax MySQL should support. As far as what is "best", that depends on your specific needs. For example, lets say you are porting an existing Oracle application to MySQL. You could consider using the Oracle mode to help ease this transition.
In general, it's usually a good idea to use the default settings of the database unless you have good reason not to. When you start tweaking things and get into non-standard configurations, then that's one more thing you (or your DBA's) have to remember to do when you put your application into production. With that said, there are also plenty of reasons to fully exploit the features of your database. After all, with many RDBMS systems, you pay a lot of money for them, so why not use them fully?
I've heard it claimed that the simplest solution to preventing SQL injection attacks is to html encode all text before inserting into the database. Then, obviously, decode all text when extracting it. The idea being that if the text only contains ampersands, semi-colons and alphanumerics then you can't do anything malicious.
While I see a number of cases where this may seem to work, I foresee the following problems in using this approach:
It claims to be a silver bullet. Potentially stopping users of this technique from understanding all the possible related issues - such as second-order attacks.
It doesn't necessarily prevent any second-order / delayed payload attacks.
It's using a tool for a purpose other than that which it was designed for. This may lead to confusion amongst future users/developers/maintainers of the code. It's also likley to be far from optimal in performance of effect.
It adds a potential performance hit to every read and write of the database.
It makes the data harder to read directly from the database.
It increases the size of the data on disk. (Each character now being ~5 characters - In turn this may also impact disk space requirements, data paging, size of indexes and performance of indexes and more?)
There are potential issues with high range unicode characters and combining characters?
Some html [en|de]coding routines/libraries behave slightly differently (e.g. Some encode an apostrophe and some don't. There may be more differences.) This then ties the data to the code used to read & write it. If using code which [en|de]codes differently the data may be changed/corrupted.
It potentially makes it harder to work with (or at least debug) any text which is already similarly encoded.
Is there anything I'm missing?
Is this actually a reasonable approach to the problem of preventing SQL injection attacks?
Are there any fundamental problems with trying to prevent injection attacks in this way?
You should prevent sql injection by using parameter bindings (eg. never concatenate your sql strings with user input, but use place holders for your parameters and let the framework you use do the right escaping). Html encoding, on the other hand, should be used to prevent cross-site scripting.
Absolutely not.
SQL injections should be prevented by parametrized queries. Or in the worst case by escaping the SQL parameter for SQL, not HTML. Each database has its own rules about this, mysql API (and most frameworks) for example provides a particular function for that. Data itself in the database should not be modified when stored.
Escaping HTML entities prevents XSS and other attacks when returning web content to clients' browsers.
How you get the idea that HTML Encoded text only contains ampersands, semi-colons and alphanumerics after decoding?
I can really encode a "'" in HTML - and that is one of the things needed to get yo into trouble (as it is a string delimiter in SQL).
So, it works ONLY if you put the HTML encoded text into the database.
THEN you havequite some trouble with any text search... and presentation of readable text outside (like in SQL manager). I would consider that a really bad architected sitaution as you have not solved the issue just duct-taped away an obvious attack vector.
Numeric fields are still problematic, unless your HTML handling is perfect, which I would not assume given that workaround.
Use SQL parameters ;)
The single character that enables SQL injection is the SQL string delimer ', also known as hex 27 or decimal 39.
This character is represented in the same way in SQL and in HTML. So an HTML encode does not affect SQL injection attacks at all.