Avoiding SQL Injection - java

I want to avoid SQL Injections in my Webapp.
It's Java based.
Are PreparedStatements enough?
Do i have to filter out the ' and "? Are there already solutions for this in Java?

My gut response to the question in your second paragraph is that it's usually a bad idea to consider a single aspect "enough" for this sort of issue - at least if you do this to the point that you stop thinking about the principles involved.
Using PreparedStatements does go a long way to stopping SQL injection, just like using slapping down synchronized everywhere goes a long way to stopping data races. And in many individual situations they'll be entirely sufficient. But in both cases they're not magic bullets - you need to be aware of the reasons you're using them, and when and where they're insufficient. For example, if you think PreparedStatements are a magic wrapper that prevents SQL injection, you'll be very disappointed the first time you need to create a dynamic statement (as opposed to merely a parameterised one) based on user input.
Thus the thing that's "enough", is education. Understand how and why the threat works; once you grok that, you'll be able to take the appropriate actions to a given situation (which sometimes is just using a PreparedStatement, but not always). I'm not aware of any particularly good resources on SQL injection though (above and beyond what you can get from Google), so hopefully other answers can point you to the One True Tutorial!

Simply never craft your SQLs manually by concatenating Strings, always use PreparedStatement and parameterize it with ? wildcards. JDBC driver will take care of escaping, so you don't have to do it yourself.
On the other hand escaping is hard. You would be surprised how many ways there are to work around your escaping algorithms. JDBC driver will do the job properly.

Although Prepared Statements helps in defending against SQL Injection, there are possibilities of SQL Injection attacks through inappropriate usage of Prepared Statements. The example below explains such a scenario where the input variables are passed directly into the Prepared Statement and thereby paving way for SQL Injection attacks.
Example:
String strUserName = request.getParameter("Txt_UserName");
PreparedStatement prepStmt = con.prepareStatement("SELECT * FROM user WHERE userId = '+strUserName+'");
More information on preventing SQL injections here.
OWASP is a great place to start for anything security related to software development.
They have java libraries which you can use to prevent XSS and SQL injections.
They also have a webapp which is very unsecure, which you can try to hack, and by that learn how not to do it.

Prepared statements can be enough. If using prepared statements you still have to take care of building the statements with wildcards only. In other words, it's possible to use prepared statements the wrong way. You do not have to filter out any parameters to avoid SQL injection. Nevertheless, you may need to filter out certain values to avoid web based attacks (like XSS), depends on your environment and scope.

Related

How to inject a condition in all SQL queries using jOOQ

I am using jOOQ to generate my SQL queries and I was wondering if there is a way to inject a condition in all the queries that my application does.
For example, I would like to have something like account = {accountNameHere} in all the SELECT that the application does. Since I already have a a high number of different queries, I would like to do that without manually adding the condition to each statement.
Is there a way to do that easily using jOOQ ? Maybe using the VisitListener ?
Yes, a VisitListener will be the most thorough way to inject a custom predicate into all of your SELECT statements (including subqueries, of course). In fact, what you're looking for is sometimes referred to as "row level security" (natively supported in RDBMS like Oracle or SQL Server).
The following blog post explains how to achieve this via a VisitListener:
http://blog.jooq.org/2015/06/17/implementing-client-side-row-level-security-with-jooq

Is it possible to make oracle database procedures to ignore commit statements?

I'm working on Java application that integrates with legacy system written Oracle PL/SQL. Unfortunately i'm not able to change this legacy system. Problem with this system is that it that sometimes COMMIT statements are written into procedures. But this causes that I'm not able to handle transactions correctly on my application level.
So is it possible to make oracle database procedures to ignore commit statements?
I have found that when doing ALTER SESSION DISABLE COMMIT IN PROCEDURE in beginning of connection will cause exception when PL/SQL procedure is trying to commit. But is it possible to make Oracle to ignore commit without changing PL/SQL code?
I don't think you can do that. You'll have to add a parameter to those procedures like"do commit"with a default value true. And you call them with parameter set to false. Pass the parameter value on, if they are nested. That way the legacy code still behaves the same but you get transaction control.
I'm working with Oracle for 9 years now. I also checked undocumented parameters regarding your question and I'm pretty sure, that there is no way to let Oracle ignore a commit of a stored procedure.
But of cause, theroretical you could use Oracle's flashback feature (e.g. flashback database or flashback table), to reset whole database or single tables to a state before your transaction began. But be aware, that this only works as desired, if you are the only one, who changes anything at the objects you flash back. This is usually unrealistic. By the way you also need to consider that the flashback feature is not designed to support such a scenario, so performance of your application will be suboptimal in case you need to flashback anything.
But this may be a way to solve your problem, if you have no other choice.
Probably the best thing is to alter the pl/sql procedures without affecting current functionality. In other words, add a new parameter to allow the user to ignore commits, but default to existing functionality (to commit). I've done this in a similar situation and it worked well.
So, you'd have something like:
create or replace procedure some_proc(
i_num in number, -- existing parameter
i_commit in number default 1) -- perform commit? 0=false, else true
as
begin
-- some DML here
if (i_commit <> 0) then
commit;
end if;
end;
Make sure that this new parameter is added to the end of the param list. So your app would pass in 0 (false) for i_commit.
Hope that helps.
I have found that when doing ALTER SESSION DISABLE COMMIT IN PROCEDURE
in beginning of connection will cause exception when PL/SQL procedure
is trying to commit.
Yeah, the documented behaviour of that statement is to force ORA-00034 exceptions if a procedure attempts to issue a commit. I think it's really intended as a testing thing, to identify procedures with embedded commits.
I think it is widely regarded as bad practice for stored procedures to issue commits. Control of the transaction must belong to the top of the calling stack.
Unfortunately there is no way to ignore those embedded commits. You will either have to re-write the PL/SQL routines, or else code some workarounds in your calling code (e.g. exception handler which issues additional DML to reverse committed changes).
Knowing what the procedure did would have been helpful.
However, assuming that the procedure modifies data in a limited number of tables(That's what we mostly do in PLSQL anyway), you could try running a flashback query on that schema:
FLASHBACK TABLE TABLE_NAME TO TIMESTAMP(TO_DATE('06-SEP-2012 23:59:59','DD-MON-YYYY HH24: MI: SS'));
You can set the time string "06-SEP-2012 23:59:59" to the time just before the procedure is called in your JAVA code.
Its a bad workaround, but worth a try I guess
I'm working on Java application that integrates with legacy system
written Oracle PL/SQL. Unfortunately i'm not able to change this
legacy system.
Hmmm, this smells like politics... "Don't touch this, it works!" I guess. :(
As a matter of fact, it's most likely impossible to ignore a COMMIT statement, as #Tilman Fliegel (and others) already said. And if it was, it would be quite an ugly wart in your codebase.
I'm not that good at politics, but I'd say if you cannot use nor change this, then just don't use this. I mean:
If you cannot change your procedures because they are used by other (old, immutable) systems, then duplicate them, then modify/refactor your copy until you're happy with it. If you're able to make your version retro-compatible, you may even provide a way for other (old) systems to use yours afterwards, when/if they are refactored: just introduce a "legacy mode" input parameter or whatever, cf. other answers.
If you cannot change code because you cannot understand/test it, then this is a major issue. It may even be safer to just trash it and start over from scratch (provided you're able to do so).
But maybe trying to ignore the COMMITs is easier after all. Humans are so hard to refactor... ;)

Should I allow a SQL WHERE clause as a REST API parameter, available on the internet?

The project I'm working on has a REST API written in JRuby/Java, with an endpoint that hits a MySQL database to retrieve a number of records.
We need to allow the client to filter those records using one or more columns, including boolean checks and range values.
The easiest way we can do this is to add a string parameter to the API, then add it into the SQL statement.
Collectively, the development team agree that this is a bad idea but the alternative is to provide an almost identical syntax for filtering, which is translated into SQL. The allure of the SQL injection parameter is strong.
So my question is, are there any circumstances under which this is a safe thing to do?
In particular, might we consider using the WHERE clause safely if it's been fully parsed beforehand, and identified as such. Or at the very least, checking for certain trigger words such as DROP, SELECT etc.
Also if anyone knows of a good library that could act as a go-between (translating or parsing an external expression into a WHERE clause) that would be great.
The OData and GData protocols already implement this functionality in a safe and standard way. You can find server and client implementations for both, for Ruby, PHP, MySQL etc. Check here for the OData libraries
Leaving aside the SQL injection issue, you'll expose your inner implementation (both the database chosen - MySQL and your table structure) directly in the form of your API.
e.g. if you change to some NoSQL-type implementation at the backend, your public-facing API will break immediately. Similarly if you restructure your database. I wouldn't do this even in an environment in which I wasn't worried about the probability/severity of injection attacks.
Besides the security implications, allowing an arbitrary WHERE clause is a bad idea because it takes the "I" out of "API" -- it's not an interface. The API is supposed free the user of the need to know details of the implementation. Like table and column names.
If clients are interacting with your data by constructing their own WHERE clauses, then you can never change the database. There might be code out there with those statements programmed in. If a bug or new feature required you to alter the DB in a way that would break existing client interactions you'd be stuck. The API should provide the filtering capability and translate requests into calls to backend in a way that lets you change the backend without breaking the API.
There are numerous ORM's for this purpose, especially in ruby (activerecord, sequel)
The most basic thing you need to do is escape the string input, which will pretty much prevent sequel injection if you are doing it properly.
It helps to not directly insert parameters directly into the sequel statement if you dont have to either, instead, check their validity and then map them to logical ones (this isn't always possible). For example, if there is an html dropdown list, and when you submit the form it passes some parameter 'firstitem', map 'firstitem' to an id or otherwise that you will then use to search on, versus using the user supplied version (assuming this mapping doesn't involve the db).

Best Practices with PreparedStatements; when to and when not to

I recently have began using prepared statements again in a web application, and I know that it is discouraged to use prepared statements for all the transactions. What I do not know is when it is best to use prepared statements or not.
I have read of when to use and not use them, but none of the examples really tell best practice of using them.
I am trying to figure out which database calls I should be using them for and which ones I should not.
For Example the MySQL website mentions it in "When to use prepared statements" on the following page Prepared Statements-MySQL
The general thumb rule in deciding whether to go for a PreparedStatement or not is:
Use Prepared Statements, unless you
have sufficient reason not to.
Prepared Statements are compiled
before execution therefore lending to
better performance, and increased
security against SQL injection as the
database server takes care of the
encoding of special characters.
Going by the article that you have referenced, the list of reasons where I believe Prepared Statements are less useful than normal queries or stored procedures are:
One-time queries. If your application makes a single query to the database, and this is done infrequently compared to the other queries, it might not make sense to use a Prepared Statement in this case. The rationale is that the Prepared Statement must first be compiled and the 'compiled' form of the statement is cached for later use. For queries that are run infrequently, the compilation is an overhead. But still, it is preferable to use prepared statements, to avoid any SQL injection issues.
Data-intensive operations. Sometimes Prepared Statements are not as effective as stored procedures, especially when a sequence of operations need to be performed in the same transaction. When you have a business process that requires multiple selects, updates and deletes to be executed against a variety of tables, stored procedures are often better than a bunch of prepared statements executed one after the other. This performance penalty can turn serious as several network trips are made for the execution of multiple statements, which is considerably reduced when invoking a stored procedure. This effect is more pronounced in query batching where several objects are created and destroyed in a short duration of time. This often tends to be a contentious issue between database administrators and application developers, as this is an edge-case; DBAs will believe that the batching of operations is better performed via SPs, while application developers believe that PreparedStatements can handle it (its usually better to have all logic in one tier). It eventually boils down to the application on whether using SPs is an advantage or not.
Support for native database operations and types.. This might not hold good for MySQL, but in general the JDBC standard does not support all the operations supported by a database, and all the SQL/native/custom types supported by the database. This is more pronounced in the Oracle database (and possibly IBM DB2?), where programmers can create their own types, which require custom Java code to be written as the JDBC standard does not support User-Defined Types in the database. Similarly, other operations in the database need to not supported (as the MySQL document states) - one cannot create users (execute CREATE USER), modify user privileges (perform GRANT operations) etc. using a Prepared Statement. Stored procedures are better suited to this task, as they would have access to the native operation set of the database, either in a direct or indirect manner.
In order to prevent SQL Injection it is better to use prepared statements in Java
For more information: SQL injections with prepared statements?
PreparedStatements have two major uses:
Preventing SQL injection attacks. This basically means automated sanitizing of inputs from external sources (web browser is external!) which are going to be saved to the database.
Batch processing. If you have a lot of data to enter into/modify in/remove from database at once, PreparedStatement can be used for that. In this case, PreparedStatement optimizes away most of the overhead of such operations and allows you to write fast database batch code.
Both of these reasons are a very compelling ones to justify using PreparedStatement almost always, however depending on how you're using the database you may hit a point where PreparedStatement won't allow you to do what you want.
As an example of such case, I've once written a tool which generated table names on the fly based on runtime properties of certain abstractions which meant that I had to be able to have SQL queries with mutable table names; you can't get those with PreparedStatement so I had to use raw Statements and some preprocessing trickery to get back to utilizing PreparedStatements for SQL injection protection.

Can RowSets be used with PreparedStatements?

I have just found RowSets for database querying with JDBC. They are stateless and cacheable, they look to be superior to ResultSets.
Can PreparedStatements be used with them though? PreparedStatements are a performance booster for querying very large databases, and not something I would want to give up (before something is said, this is not premature optimization, we have a proven speed need!!). I need the fastest query return to a set here, caching is secondary.
The default implementation of RowSet use prepared statements internally.
I would have been surprised if that was not the case.
See the code JDBCRowSetImpl code your self http://www.google.com/codesearch/p?hl=en#TTY8xLpnKOE/src/share/classes/com/sun/rowset/JdbcRowSetImpl.java&q=JDBCRowSetImpl
you will want to look at prepare() method.
Note: Poking around the code is why i love Open Source :D

Categories