-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature Request: Input Processor/Sanitizer for insert and update statements #117
Comments
HI. I like the idea but only for SQL inyection, not for XSS. IMHO sanitizing XSS is something that should happen in the web layer, not in the persistence level. Filters like ESAPI or HDIV do the job really well and they protect also from CRSF and other attacks (invalid object reference, invalid redirects...). But it is true that using ${} expressions opens a door for SQL injection. So for example, to make sure that an app built with MyBatis is secure you should search for ${} expressions what is quite tedious. What about adding a generic pattern to process all ${} expressions? It would be just adding a some new parameters to control the filtering of values that will end up in a ${} expression. Parameter suggestions: For this parameter options are:
Or using a whitelist (letters, numbers, point and underscore)
Though in SQL we already know quite well which are the invalid control characters, using a whitelist is a good practice in security so I am for the second. This way, making MyBatis safe will just be adding the parameter enableInjectionValidation=true What do you think? |
Lets keep this open for a while to let people review it. |
This is a good start. This pattern matching could be powerful. A few points: I would update the default validation to allow hyphen as people store UUIDs in the database increasingly. I would also include a couple of examples in the documentation for what might be common usages The only other thing that might make it better would be to provide different injection patterns for different values or different insert/select/update statements. IE, for select and delete I might want a default pattern that is a whitelist, since searching should generally only be with letters/numbers/etc, but for insert/update, and maybe a special select, I might need a more lenient pattern than what is globally configured So could you add the enableInjectionValidation/injectionExpression to the insert/select/update/delete declarations as well? You could even add an "expression" tag that defines a reusable injectionExpression. Then you could have something like the following:
|
I agree this is a good start. We could also provide the ability to escape special characters, instead of denying to execute the statement. Guava has a couple of escapers that could serve as examples: XmlEscaper, HtmlEscaper ...but of course there should be a way to provide own settings, because hardcoding escaping to, for example, XML entities is questionable at least. |
@emacarron, any update with such issue ? 3.3.0 seems a long story since last snapshot, will be ready to release the final version ? |
Hi @bwzhang2011 I finally removed the change because I cannot see clearly the use case. Let me explain my point of view. Regarding SQL injection SQL injection happens when you tell the DB engine to execute user input. There are some key points:
The change I made worked only for ${} expressions. They are always strings and not parameters of a prepared statement. So, this covers points number 1 && 2. The main problem is that we do not know if the data is a user input or not. You may use ${} expressions for any reason, not only for parameters. So there is no way that we can provide a generic default behaviour. The rule of thumb is: mark the data as data. In the case of a db the right approach is using prepared statements. Regarding XSS The problem here is similar. It is OK from a persistence perspective to insert HTML or Javascript in a database. The problem happens when this data comes from user input and you are building a Web site . Trying to stop XSS by filtering/validating input is not the right approach given that the problem of injections is not the input itself but passing data to an execution context. And anyway I would never expect this to be solved by the persistence layer. If someone wants to validate/escape input, it should be done in sync with the error handling code. The rule of thumb here is almost the same: mark the data as data. In this case you should use the proper escaping according to the execution context (javascript, html, xml...) when the output happens. |
I can agree with your assessment when it comes to passing data to a db, however, mybatis is not a db, its not the actual execution context, it is a data access layer around the execution context the provides many facilities that would otherwise need to be hand written in order to accomplish, like data object instantion, etc. The point of my original request was to reduce the number of wrappers around the data access layer to hand input sanitizing. IE provide one configuration point via the annotation or xml file that tells the data access layer how to handle a piece of data. The reason I asked for the additional facility of a new parameter on the definitions of the insert/update xml/annotation was because I did not want to have to go and override the handlers for Strings in all contexts, however, that would be another way to do it if you don't feel providing the "juice is worth the squeeze". |
I agree with @emacarron on this. I could be missing something, but can't you use a custom type handler to achieve it?
you just write
and do what you have to do in the type handler code. |
Thats exactly what I said, it could be done with a custom handler, but I thought it would be cleaner and more flexible as a separate mechanism, not just on the column, but for use on a whole statement. I think, though, the argument that custom type handlers can be used instead is a stronger case against it than that its not the appropriate layer. |
…phase - Evaluated param values are stored in `ParameterMapping` and later used in DefaultParameterHandler - There is no change when processing RawSqlSource - Removed unused `injectionFilter` from TextSqlNode (mybatisgh-117) This should fix mybatis#2754 . This might also fix mybatis#206 and mybatis#575 , but with this patch, it still is not possible to invoke a method with parameter inside a parameter reference like `#{_parameter.mymethod(_parameter.value)}`. It might be possible to accept OGNL expression in a param reference (e.g. `#{${_parameter.mymethod(_parameter.value)}}`), but I'm not sure if that's a good idea.
Considering that sanitizing user input, especially from the internet, is important for preventing javascript, sql and other injections, it would be nice if in defining an "insert" or "update" statement in xml or by annotation, I could specify a processor/sanitizer that would validate/cleanup input values.
It could possibly be specified as follows:
The sanitizer would be called when resolving the values of the #{...} tokens before calling setNonNullParameter() for the value type handler.
The sanitizerType/sanitizerMap would work similar to the resultType/resultMap functionality.
The text was updated successfully, but these errors were encountered: