Is posting SQL code in forums a bad idea? - sql

Is there any risk in posting SQL code from my company in these forums, or in any forums for that matter?
Specifically I am referring to examples of SQL queries. These queries obviously show joins to tables and different fields in my database tables.

The risk is pretty low, if:
you do not publish company's name or web address
there are no SQL injection waiting to be exploited in that SQL of yours
server itself is secure and pached
you do not publish connection credentials with your snippet

As long as it doesn't show proprietary information, SQL is SQL. I would always recommend sharing "fake" information for example data.

It should be easy to obscure relevant names, etc. Think of a good analogy and replace names with that. I don't think people care too much to try and "find you out". We're much more interested in solving your problem.

Only the connection information (username, password, IP, etc) is sensitive - without that information:
SELECT e.*
FROM EMPLOYEES e
...is quite safe. Neither I nor anyone else can delete anything in your tables.
I don't recommend abstracting things too much when posting questions - some details can make all the difference to determine the issue you're encountering.

Related

Having trouble with SQL injection

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 does CNT stand for in naming stored procedures?

There's a stored procedure called "cnt_insertContestEntry" in my company's database. I'm new to database naming conventions. What could CNT possibly mean? Contest? i could ask my co-workers but i don't want to look dumb :p.
I had a hard time making this sound nice, and I'm not sure if I succeeded. It is rather strange to ask people who are unlikely to know the answer when you have people much nearer who are quite likely to know the answer.
In general, if you want to know the answer, ask the person most likely to have it. In my opinion, that is never going to make you look dumb!
"cnt" is commonly used as an abbreviation for "count", often in variable names as a part of Hungarian notation. I don't think that's how it's being used here, though. Your guess sounds reasonable. I'd ask.
What's the name of the project/application? We usually prefix our tables, stored procedures etc, with an abbreviated version of the project name.
e.g. on "The TTP Project",
ttp_users
ttp_doSomething
I agree, go ahead and ask your co-workers. But here are some less efficient ideas:
If it's a Stored Procedure, then examine the procedure and see if it gives you clues.
Look for other procedures that start with cnt_. See if they give you any ideas.
My guess is that cnt stands for contest, and that the original author chose the prefix so that all contest-related stored procedures were grouped together alphabetically. Maybe though, there's only one so far.
CNT as a technical term is usually some variant of "Computer Network Technology" [Reference].
Given the sproc has to do with contest entries, I'd guess that cnt is an abbreviation for CoNTest.
It's not the most obvious naming mechanism, but it would serve to suitably keep similar procedures grouped together within SQL Management Studio.
Just ask, I'd only be annoyed with a coworker if they repeatedly asked the same question. First answer is always free.
Don't lose time searching on the internet/analyzing the function. Any company wants efficient employees & in this case asking your colleagues is way more efficient then guessing. The longer you wait to ask, the more awkward it will be when you do ask after thinking about it for ages.. ;)
Looks like it's being used as a schema identifier, means Contest maybe? Horrific naming standard if so!
What's the data type? If it's numeric, maybe it's count - e.g., the database is de-normalized
It's spelled in lowercase, so probably just short for something unimportant. Count, or Content, or Contest, or Cent. It seems to be a namespace of some kind so it's likely that you have other stored procedures with the same prefix. Maybe it's the initials of the person who wrote it. Did you have a Carl-Nicolay Tenenbaum working for you? (Oh, just made that name up, btw.)
Btw, the only dumb questions are the ones you don't dare to ask. So in case of doubt, ask your colleagues. :-)
In one of my projects we have used prefixes to determine the subsystem of project. Because different subsystems were developed by different developers, these prefixes were like shema identifiers.

Signs of a great SQL developer

Based on their work, how do you distinguish a great SQL developer?
Examples might include:
Seldom uses CURSORs, and tries to refactor them away.
Seldom uses temporary tables, and tries to refactor them away.
Handles NULL values in OUTER JOINs with confidence.
Avoids SQL extensions that are not widely implemented.
Knows how to indent with elegance.
I've found that a great SQL developer is usually also a great database designer, and will prefer to be involved in both the design and implementation of the database. That's because a bad database design can frustrate and hold back even the best developer - good SQL instincts don't always work right in the face of pathological designs, or systems where RI is poor or non-existent. So, one way to tell a great SQL developer is to test them on data modeling.
Also, a great DB developer has to have complex join logic down cold, and know exactly what the results of various multi-way joins will be in different situations. Lack of comfort with joins is the #1 cause of bad SQL code (and bad SQL design, for that matter).
As for specific syntax things, I'd hesitate at directives like:
Does not use CURSORs.
Does not use temporary tables.
Use of those techniques might allow you to tell the difference between a dangerously amateur SQL programmer (who uses them when simple relational predicates would be far better) and a decent starting SQL programmer (who knows how to do most stuff without them). However, there are many situations in real world usage where temp tables and cursors are perfectly adequate ways (sometimes, the only ways) to accomplish things (short of moving to another layer to do the processing, which is sometimes better anyway).
So, use of advanced concepts like these isn't forbidden, but unless you're clearly dealing with a SQL expert working on a really tough problem that, for some reason, doesn't lend itself to a relational solution ... yeah, they're probably warning signs.
I don't think that cursors, temporary tables or other SQL practices are inherently bad or that their usage is a clear sign of how good a database programmer is.
I think there is the right tool for every type of problem. Sure, if you only have a hammer, everything looks like a nail. I think a great SQL programmer or database developer is a person who knows which tool is the right one in a specific situation. IMHO you can't generalize excluding specific patterns.
But a rule of thumb may be: a great database developer will find a more short and elegant solution for complex situations than the average programmer.
Here are a few things that don't apply to run-of-the-mill software developers, but do apply to someone with good SQL skills:
Defines beneficial indexes, but not redundant or unused indexes.
Employs transactions effectively.
Values referential integrity.
Applies normalization to database design.
Thinks in terms of sets, not in terms of loops.
Uses JOIN confidently.
Knows how NULL and tri-value logic works.
Understands the uses and benefits of query parameters.
The examples you give, of not using cursors, temp tables, or knowing 3 alternative queries for a given task, I would not consider indications of being a great SQL developer. Perhaps I would call someone who does those things an "acrobat."
Just to add to the already great answers; The developer can reduce a complex problem to something simple and easy to maintain.
Knows how to use INFORMATION_SCHEMA and table metadata in order to write either generic code or to code generate code in order to save repetitive database tasks.

SQL With A Safety Net

My firm have a talented and smart operations staff who are working very hard. I'd like to give them a SQL-execution tool that helps them avoid common, easily-detected SQL mistakes that are easy to make when they are in a hurry. Can anyone suggest such a tool? Details follow.
Part of the operations team remit is writing very complex ad-hoc SQL queries. Not surprisingly, operators sometimes make mistakes in the queries they write because they are so busy.
Luckily, their queries are all SELECTs not data-changing SQL, and they are running on a copy of the database anyway. Still, we'd like to prevent errors in the SQL they run. For instance, sometimes the mistakes lead to long-running queries that slow down the duplicate system they're using and inconvenience others until we find the culprit query and kill it. Worse, occasionally the mistakes lead to apparently-correct answers that we don't catch until much later, with consequent embarrassment.
Our developers also make mistakes in complex code that they write, but they have Eclipse and various plugins (such as FindBugs) that catch errors as they type. I'd like to give operators something similar - ideally it would see
SELECT U.NAME, C.NAME FROM USER U, COMPANY C WHERE U.NAME = 'ibell';
and before you executed, it would say "Hey, did you realise that's a Cartesian product? Are you sure you want to do that?" It doesn't have to be very smart - finding obviously missing join conditions and similar evident errors would be fine.
It looks like TOAD should do this but I can't seem to find anything about such a feature. Are there other tools like TOAD that can provide this kind of semi-intelligent error correction?
Update: I forgot to mention that we're using MySQL.
If your people are using the mysql(1) program to run queries, you can use the safe-updates option (aka i-am-a-dummy) to get you part of what you need. Its name is somewhat misleading; it not only prevents UPDATE and DELETE without a WHERE (which you're not worried about), but also adds an implicit LIMIT 1000 to SELECT statements, and aborts SELECTs that have joins and are estimated to consider over 1,000,000 tuples --- perfect for discouraging Cartesian joins.
..."writing very complex ad-hoc SQL queries.... they are so busy"
Danger Will Robinson!
Automate Automate Automate.
Ideally, the ops team should not be put into a position where they have to write queries on the fly in a high stress situation – it’s a recipe for disaster! Better for them to build up a library of pre-written scripts that have undergone the appropriate testing to make sure it a) does what you want b) provides an audit trail c) has a possible ‘undo’ type function.
Failing that, giving them a user ID that only has SELECT premissions might help :-)
You might find SQL Prompt from redgate useful. I'm not sure what database engine you're using, as it's only for MSSQL Server
I'm not expecting anything like this to exist. The tool would have to first implement everything that the SQL parser in your database implements, and then it would have to do a data model analysis to predict "bad" queries.
Your best bet might be to write a plugin for a text editor that did some basic checking for suspicious patterns and highlighted them differently than the standard .sql mode. But even that would be quite difficult.
I would be happy with a tool that set off alarm bells whenever I typed in an update statement without a where clause. And perhaps administered a mild electric shock, since it's usually about 1 in the morning after a long day when mistakes like that happen.
It would be pretty easy to build this by setting up a sample database with a extremely small amount of dummy data, which would receive the query first. A couple of things will happen:
You might get a SQL syntax error, which would not load the database much since it's a small database.
You might get back a response which could clearly be shown to contain every row in one or more tables, which is probably not what they want.
Things which pass the above conditions are likely to be okay, so you can run them against the copy of the production database.
Assuming your schema doesn't change much and is not particularly weird, writing the above is likely the quickest solution to your problem.
I'd start with some coding standards - for instance never use the type of join in your example - it often results in bad results (especially in SQL Server if you try to do an outer join that way, you will get bad results). require them to do explicit joins.
If you have complex relationships, you might consider putting them in views and then writing the adhoc queries from the views. Then at least they will never make the mistake of getting the joins wrong.
Can't you just limit the amount of time a query can run for? I'm not sure about MySQL, but for SQL Server, even just the default query analyzer can restrict how long queries will run before they time out. Couple that with limited rights so they can only run SELECT queries, and you should be pretty much covered.

Catching SQL Injection and other Malicious Web Requests

I am looking for a tool that can detect malicious requests (such as obvious SQL injection gets or posts) and will immediately ban the IP address of the requester/add to a blacklist. I am aware that in an ideal world our code should be able to handle such requests and treat them accordingly, but there is a lot of value in such a tool even when the site is safe from these kinds of attacks, as it can lead to saving bandwidth, preventing bloat of analytics, etc.
Ideally, I'm looking for a cross-platform (LAMP/.NET) solution that sits at a higher level than the technology stack; perhaps at the web-server or hardware level. I'm not sure if this exists, though.
Either way, I'd like to hear the community's feedback so that I can see what my options might be with regard to implementation and approach.
Your almost looking at it the wrong way, no 3party tool that is not aware of your application methods/naming/data/domain is going to going to be able to perfectly protect you.
Something like SQL injection prevention is something that has to be in the code, and best written by the people that wrote the SQL, because they are the ones that will know what should/shouldnt be in those fields (unless your project has very good docs)
Your right, this all has been done before. You dont quite have to reinvent the wheel, but you do have to carve a new one because of a differences in everyone's axle diameters.
This is not a drop-in and run problem, you really do have to be familiar with what exactly SQL injection is before you can prevent it. It is a sneaky problem, so it takes equally sneaky protections.
These 2 links taught me far more then the basics on the subject to get started, and helped me better phrase my future lookups on specific questions that weren't answered.
SQL injection
SQL Injection Attacks by Example
And while this one isnt quite a 100% finder, it will "show you the light" on existing problem in your existing code, but like with webstandards, dont stop coding once you pass this test.
Exploit-Me
The problem with a generic tool is that it is very difficult to come up with a set of rules that will only match against a genuine attack.
SQL keywords are all English words, and don't forget that the string
DROP TABLE users;
is perfectly valid in a form field that, for example, contains an answer to a programming question.
The only sensible option is to sanitise the input before ever passing it to your database but pass it on nonetheless. Otherwise lots of perfectly normal, non-malicious users are going to get banned from your site.
One method that might work for some cases would be to take the sql string that would run if you naively used the form data and pass it to some code that counts the number of statements that would actually be executed. If it is greater than the number expected, then there is a decent chance that an injection was attempted, especially for fields that are unlikely to include control characters such as username.
Something like a normal text box would be a bit harder since this method would be a lot more likely to return false positives, but this would be a start, at least.
One little thing to keep in mind: In some countries (i.e. most of Europe), people do not have static IP Addresses, so blacklisting should not be forever.
Oracle has got an online tutorial about SQL Injection. Even though you want a ready-made solution, this might give you some hints on how to use it better to defend yourself.
Now that I think about it, a Bayesian filter similar to the ones used to block spam might work decently too. If you got together a set of normal text for each field and a set of sql injections, you might be able to train it to flag injection attacks.
One of my sites was recently hacked through SQL Injection. It added a link to a virus for every text field in the db! The fix was to add some code looking for SQL keywords. Fortunately, I've developed in ColdFiusion, so the code sits in my Application.cfm file which is run at the beginning of every webpage & it looks at all the URL variables. Wikipedia has some good links to help too.
Interesting how this is being implemented years later by google and them removing the URL all together in order to prevent XSS attacks and other malicious acitivites