We have a Java application that communicates with multiple SQL Server databases on the same
box. The number of and names of these databases vary. By and large, we use almost exclusively stored procedures with CallableStatement to access the databases. We are extremely good about avoiding SQL injection and using bind variables.
The only area of concern is that the database name itself is concatenated into the SQL that we pass to the CallableStatement as such:
"{call [" + dbName + ".dbo." + procName + "(?, ?, ?)}"
procName is hard-coded into child classes using a template method pattern, so that string is guaranteed safe.
dbName is defined externally. I have tried setting dbName to all sorts of patterns to escape the syntax and exploit this on my development environment and have been unsuccessful.
I have set it to the following to produce the following SQL calls (table and proc names changed to protect the innocent):
securitytest].nx_proc()};delete from poor_victim_table;
becomes
{call [securitytest].nx_proc()};delete from poor_victim_table;].dbo.proper_proc_name()}
and
securitytest].nx_proc()};exec('delete from poor_victim_table');
becomes
{call [securitytest].nx_proc()};exec('delete from poor_victim_table');].dbo.proper_proc_name(?,?,?,?,?,?,?)}
Results in Incorrect syntax near ')'. and poor_victim_table still has rows. I have used truncate table, drop table and drop database and when they didn't work, I switched to simple delete to rule out security settings.
If I use a proc that takes bind parameters, I always get a mismatch between the number of expected parameters and supplied parameters such as The index 1 is out of range..
securitytest]};exec('delete from poor_victim_table');
becomes
{call [securitytest]};exec('delete from poor_victim_table');].dbo.proper_proc_name(?,?,?,?,?,?,?)}
All roads seem to lead to a runtime error and the SQL does not execute. Of course, this is great. But I want to make sure it's failing because it cannot succeed and not failing because I am failing to try the right combination.
The popular opinion / urban myth is that using a stored procedure makes you immune to SQL injection, but I prefer to not trust absolute statements like that when it comes to security.
After researching this for a while, the best I came up with is this stackoverflow question: SQL injection - no danger on stored procedure call (on iSeries)?. It seems to support using CallableStatement because it protects you from SQL injection unless your proc code itself makes dynamic SQL out of an input parameter.
So, my question to the community is, assuming the SQL code in a proc is safe, does using CallableStatement in JDBC really prevent SQL injection? Or does the SQL Server driver parse the string in a way that prevents it, but other drivers may not? Or am I not trying hard enough?
If it is safe, how is that guarantee made? Is it due to the abstract syntax of using { call blah(?) } which is not real SQL, but gets translated to SQL?
You should be safe, but just like you, i wouldn't trust that, especially if you're interfacing to different databases using different JDBC drivers etc.
If i were you, before the statement you posted, i'd make sure to check if the dbName contains anything but letters, digits, and possibly an underscore. This should allow all valid dbNames, and prevent all kinds of messing with it.
Check your db connection url, i think that is refer static db, so if you write db name in callable statement this will generate problem whenever db name changed, your code like die (most places to change), so don't use db name in query but you can create different objects for different db connection or different helper classes for that.
The popular opinion / urban myth is that using a stored procedure
makes you immune to SQL injection, but I prefer to not trust absolute
statements like that when it comes to security.
And you do well in not trusting such a blanket statement. However, the statement needs to be qualified/qualifyable.
See, a stored procedure is immune to SQL injection when it is well written. It allows you to control what kind of SQL statements are permitted. You can configure your production database so that it doesn't allow execution of DMLs, only stored procedure (thus saving you from someone executing a horrible cartesian joint, by accident or on purpose.)
But beyond a stored procedure being well written, the caller has also the onus to validate and sanitize input, and JDBC provides you a way to do that via "bind" parameters.
A CallableStatement inherits from PreparedStatement, which provides methods for binding parameters. The binding methods escape the incoming parameter values so as to make injection pretty much impossible.
Think of stored procedures (and callable and prepared statements) as a hammer. You can use it well to hammer a nail or to crush your thumb.
Related
Ive been searching through source for a while, and it appears to me that there are no given Rails tools for retrieving the String representation of various HTML content types. Ive also found this to be a very difficult concept to search for in general.
What I want is something like this:
Mime::Mimes::CONTENT_TYPE_JSON = 'application/json'.freeze
or, Mime::Mimes::CONTENT_TYPES[:json] etc.
...because I want to do a lot of things like some_value == 'application/json' or some_value = 'application/json' etc.
I want to use the expression "application/json" often, and I dont want to create new String instances for something that is pretty well within the domain of web application development. Ive thought of creating my own app consts or vars so I dont have to allocate HTML Content Type strings more than once, but also feel this should just be available for me in any web application framework (at least, those written in languages where every string is a new memory allocation).
Is there a better tool or resource within the Rails 5 source that I am missing that allows easy retrieval of content type strings? Do I have to get a gem / create my own for this?
Note: Im away of how heavy of an "optimization" this may appear to be. Let's then entertain this query from a position of being pragmatic about organizational style, for a project that requires elimination of any duplication of domain-specific string literals, and to keep them symbolized or as some frozen const. Let's pretend its a personal project for the sheer joy of experimenting with such style!
There is a shorthand for it:
Mime[:json]
Mime#[] -
https://github.com/rails/rails/blob/e2efc667dea886e71c33e3837048e34b7a1fe470/actionpack/lib/action_dispatch/http/mime_type.rb#L41
which uses
Mime::Type#lookup_by_extension -
https://github.com/rails/rails/blob/e2efc667dea886e71c33e3837048e34b7a1fe470/actionpack/lib/action_dispatch/http/mime_type.rb#L149
If you want to get the actual content type you might need to call a #to_s on it:
Mime[:json].to_s
Creating a new module to facilitate simple storage and retrieval using the ActionPack Mime::Type system would work as follows:
# Build hash of type name to value, e.g., { xml: "application/xml" }
CONTENT_TYPES = {}.tap do |simple_content_types_hash|
# Get each registered Mime Type
Mime::EXTENSION_LOOKUP.each do |mime|
simple_content_type_hash[mime.first.to_sym] = mime.last.instance_variable_get("#string").freeze
end
end.freeze
Note: the above is untested, its just a generalization of what I am looking for. Thanks to #Fire-Dragon-DoL for the tip.
This could be added via an initializer, patched into an existing module, or into a new helper module.
(Sorry, if this is a dumb question....)
Veracode reports my website has a security issue which relates to use connection string from web.config.
Here is my code.
Public Function ExecuteScalar(ByVal sql As String) As Object
Dim obj As Object = Nothing
Try
Dim connStr as String = ConfigurationManager.ConnectionStrings("mydatabase").ConnectionString
Using conn As New SqlConnection(connStr) '''Veracode reports the issue come from this line
conn.Open()
If conn IsNot Nothing Then
'''execute my sql
End If
End Using
Catch ex As Exception
Throw ex
End Try
Return obj
End Function
Veracode said:
This call to
system_data_dll.System.Data.SqlClient.SqlConnection.!newinit_0_1()
allows external control of system settings. The argument to the
function is constructed using user-supplied input, which can disrupt
service or cause an application to behave in unexpected ways. The
first argument to !newinit_0_1() contains tainted data from the
variable connStr. The tainted data originated from earlier calls to
system_web_dll.system.web.httprequest.get_item,
system_data_dll.system.data.common.dbdataadapter.fill,
system_data_dll.system.data.sqlclient.sqlcommand.executescalar, and
fmmobile8_dll.virtualcontroller.vc_wcfentry.
Remediation:
Never allow user-supplied or otherwise untrusted data to control
system-level settings. Always validate user-supplied input to ensure
that it conforms to the expected format, using centralized data
validation routines when possible.
The same isuse was reported by CWE: http://cwe.mitre.org/data/definitions/15.html
OK, the suggestion from Veracode said that I should check the format of connection string before using it to create SqlConnection object.
I also asked Google professor about how to check format of connection string. But the returned results said that we should create SqlConnection object, then open it.
If the response is OK, the connection string also means a valid format. Otherwise, the connection string is invalid.
Unfortunately, Veracode does not accept this answer.
So, my question is that:
Should we check the format of connection string before creating SqlConnection object (as Veracode said)? If yes, how?
The problem is not the format of the connection string, it's that it may be controlled by somebody not intended. For instance an attacker may be able to change your web.config and have your application connect to a fake database to serve fake data. Note that such an attacker might be internal to your organization (a disgruntled IT ops employee), or an external attacker that already gained some level of access.
So the question is whether you trust your web.config file according to your threat model. Probably you do for several reasons (you have good processes to mitigate risks), in which case this would be "mitigated by design" in Veracode terms.
Basically it's just a warning to raise attention that web.config is in a sense external to your application and can be changed by more people than you would initially think of, and changing it by unintended people may lead to unwanted results.
I've had a similar issue with Veracode and they told me to make sure the Web.config file was encrypted.
You can do this via some command line prompt actions on the server where the application is deployed.
aspnet_regiis -pe "connectionStrings" -app "/" -site 1
or if you wanted to expand your security to the appSettings section
aspnet_regiis -pe "appSettings" -app "/" -site 1
You get the site number by opening IIS and going to the Advanced Settings for the site. It is the field labeled "ID"
Here is a MSDN article explaining in more detail:
https://msdn.microsoft.com/en-us/library/zhhddkxy.aspx
I'm building a little token-based authentication library for my (rails based) api server which uses redis to store generated auth tokens. The line I'm worried about is: user_id = $redis.get("auth:#{token}"), where token is what's passed in to authenticate_or_request_with_http_token.
If this were SQL, that'd be a huge red flag - string interpolated SQL queries are pretty insecure. As far as I can tell, however, doing string interpolation on a redis key query isn't insecure.
My source for the above claim is the redis documentation here: http://redis.io/topics/security (under the string escaping and nosql injection header), but I wanted to make sure that this is the case before I get a Bobby Tables attack.
The documentation you are pointing to is quite explicit:
The Redis protocol has no concept of string escaping, so injection is impossible under normal circumstances using a normal client library. The protocol uses prefixed-length strings and is completely binary safe.
There is a small attack vector for these kinds of string injections. While the redis documentation is clear about the difficulty of executing multiple commands on the database, it does not mention that the key separator (':' in your example) usually needs to be escaped when used as the part of a key.
I have seen a redis database using these keys:
oauth_token:123456 (which contained a hash of OAuth token parameters) and
oauth_token:123456:is_temp (which contained a boolean property to indicate whether the OAuth token is a temporary token)
Trusting the user input without escaping might result in GET oauth_token:#{token} accidentally ending up as GET oauth_token:123456:is_temp (when token has been set to 123456:is_temp by the user).
So I highly recommend to properly escape colons from potential user input to make sure your key paths cannot be tricked like this.
NOTE: Someone recommended to fix the example above by using oauth_token:123456 and oauth_token:is_temp:123456, but that is flawed (for the user-provided token is_temp:123456). The correct solution to that problem (without escaping) would be to use keys oauth_token:info:123456 and oauth_token:is_temp:123456 to make sure these keys cannot overlap whatever the user-provided input was (or simply escape colons).
Basically Redis is immune from escaping issues when the input string is used verbatim. For example:
SET mykey <some-attacker-chosen-data>
However Redis is not immune from issues arising by using non validate input in the context of string interpolation, as showed by Sven Herzberg. In order to turn the Sven example into a safe one, it is possible to just use an Hash, and avoid reverting to interpolation. Otherwise either use not common prefixes to use in conjunction with keys interpolation, or use some basic form of sanity check on the input, which is, filtering away the separator used, or better, validate that the input is actually a number (in the specific example).
So while Redis does not suffer from the typical injection attacks of SQL, when used untrusted input in the context of a string interpolation used to create key names, or even worse, Lua scripts, some care should be taken.
so i would like to expose regular expression queries on a field in my model, such that user could ask for
http://localhost:3000/myview.json?field=^hello, (there|world).*
so i know i'll have to change my routes to recognise the wildcard characters etc, and i can easily do a Regexp.new() inside my controller to convert this to a real regular expression (i'm using mongomapper in the back).
the issue is the potentially huge security hole with XSS.
should i be worried about this? how could i safely enable users to query with regular expression strings.
(i'm not too bothered about the user hammering the database... yet)
Regular expressions won't be able to perform arbitrary code execution unless there is something really wrong with Regexp.new. So if we assume that Regexp.new will either make a valid regular expression or fail or do something else sane you are safe already without having to sanitize the incoming string.
I got an exception in a web app I'm developing recently from a url something like:
http://domain.com/script.js?bcsi-ac-16E7C1CCF9EF6357=1C76413C00000002kmNHGZK2deV0Qz25TXynq3fMaPTrBAAAAgAAAD5tGgCEAwAACAAAAPUiAgA=
First of all - what in the world is that? From searching it sounds like maybe it's a cookie / session variable of some kind...
Second of all, the exception was about dynamic assignment of a constant. I tried a simpler url:
http://domain.com/script.js?bcsi-ac
And that gave an exception about the variable or method 'bcsi' not being defined, as if it were trying to evaluate it... WHAT!? I sure as hell hope people can't cause my Rails app to evaluate random code just by passing it to the querystring...
To provide more detail: I'm not doing anything unusual with the querystring data in the route or the controller. I just take the params and pass them into a partial as locals (admittedly not the cleanest way to do it, but simple - and that certainly shouldn't cause it to evaluate a parameter name as code?)
OKAY! Answering my own question again. It turns out passing params in as locals to a partial DOES cause it to evaluate the parameter name as code - obviously it can't use the variable name "bcsi-ac" so it tries to evaluate it.
But the question as to whether that poses a security risk still remains... I don't seem to be able to call methods on things, or actually assign things... but maybe I just haven't tried hard enough. It would seem to me that rails should just throw an exception when passing in a locals hash that includes an invalid variable name.
as a general rule of thumb, any time you allow strings from your url to be evaluated as code you are setting up a huge security risk in your application. you might not be able to call methods on locals as your methods exist server side and the code you are evaluating is client side, but this certainly opens your site up to XSS vulnerabilities among others...