(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
Related
The following URI triggered an error in the public OData service:
http://services.odata.org/V4/Northwind/Northwind.svc/Suppliers?$filter=Address eq '<A'
Entity type Supplier contains property Address of type Edm.String. So, the value of Address may contain any UTF-8 character from the definition (see section 6. Primitive data types).
The server responds with:
Runtime Error: An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed remotely (for security reasons).
Is the there something wrong with this URI or it is really a problem on the server side (e.g. inappropriate parsing of the $filter query option)?
You should encode your query URL, e.g. with help of
http://prasannaadavi.com/2014/06/handling-special-characters-in-odata-queries.html
How are special characters handled in an oData query?
In your special case you should try encoding "<A" with "<A"
--> found in https://web.archive.org/web/20150101222238/http://msdn.microsoft.com/en-us/library/aa226544(SQL.80).aspx)
When sending a request via Zuul to a client, Zuul seems to change the query String. More specifically, if the client should receive an url-encoded query String, Zuul decodes the query String once. Here is a concrete example:
If "http://localhost:8080/demo/demo?a=http%3A%2F%2Fsomething/" is sent to the client, the client receives as a query String "a=http://something/".
Looking into Zuul`s code, the function "buildZuulRequestQueryParams" uses "HTTPRequestUtils.getInstance().getQueryParams();" which decodes the query String.
Is this a desired feature or a bug?
Zuul actually offers a flag to disable this behavior.
8.9 Query String Encoding
When processing the incoming request, query params are decoded so that they can be available for possible modifications in Zuul filters. They are then re-encoded the backend request is rebuilt in the route filters. The result can be different than the original input if (for example) it was encoded with Javascript’s encodeURIComponent() method. While this causes no issues in most cases, some web servers can be picky with the encoding of complex query string.
To force the original encoding of the query string, it is possible to pass a special flag to ZuulProperties so that the query string is taken as is with the HttpServletRequest::getQueryString method, as shown in the following example:
application.yml.
zuul:
forceOriginalQueryStringEncoding: true
[Note] This special flag works only with SimpleHostRoutingFilter.
Also, you loose the ability to easily override query parameters with
RequestContext.getCurrentContext().setRequestQueryParams(someOverriddenParameters),
because the query string is now fetched directly on the original
HttpServletRequest.
8. Router and Filter: Zuul
I was facing the same issue yesterday. I think it's related to this pull request. A faster way to solve this issue (without wait for PR get merged) is rewrite the classes in your own project using the same package and class name to override the framework class.
I ran into the same issue recently. Submitted a PR to Netflix/Zuul. Basically adding the same ability that's currently available on spring cloud gateway to Netflix. Hoping it'll get addressed soon.
If accepted, you could pretty much add a config to keep the original uri encoding
zuul.keepOriginalQueryStringEncoding=true
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.
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.
I found this. It seems kind of ugly to just throw this into environment.rb. The question is kind of old. I just wanted to ask if there was a better way to do this now.
The problem (if you don't want to click through), is including your custom log message formatter. (The problem I'm solving is that I want to assign a guid to every request, prepend all log messages from that request with the guid, and then return the guid in meta data to the client a.k.a. request id)
Rails logger format string configuration
You can put it in an initializer.
Initializers can be any name and go in config/initializers. Every file in this directory is loaded at startup; it's a great place to put miscellaneous startup code that doesn't seem to fit anywhere else.