Struts 2 - is there any way to escape HTML in input fields? - struts2

When I allow a user to enter text using s:textfield, he can enter something like <b>Name</b> or something like \Me/. I want that these should be escaped before I am saving them to the database. When we retrieve them, the escaping is done automatically, but I want it to happen also when we are saving it.
I was trying to return a json output from my action class, but due to a name \a/ stored in my database, wrong json was being formed. This would have been avoided if the name had been escaped before being saved into the database.

You can use StringEscapeUtils. You can call escapeJavascript(textfield) in your action and then store it into the database.

#Daud, The problem you explained is called Cross site scripting or XSS.
And I think you should use Filters to clean the request parameters. This is the most sophisticated way. You can call these filters for the actions which are posting some parameters via request.
Visit my blog to see how to avoid XSS threat using Filter approach.
I also faced this issue when our project was tested by well known firm specializing in security testing and they suggested this filter approach.
You can give it a try.

Related

spring security native xss filter

Why Spring Security doesn't provide any XSS filter to clean the form input values?
Accordingly to this ticket, such XSS filter is a low priority:
https://jira.spring.io/browse/SEC-2167?jql=text%20~%20%22xss%22
(although the ticket speaks only about URL querystring. Sanitizing POST params would be also required)
In my opinion it would be really useful that spring would provide such a filter instead of building your own. This filter it's a recurrent problem.
XSS is best handled at output stage via the use of encoding. That is, store everything in your database as is, and yes storing <script> is fine, however once output, encode correctly for the context it is output in. For HTML this would be <script>, however if your output context was plain text you would just output as is <script> (assuming the same character set encoding is used). Side note: Use parameterised queries or equivalent for storing in your database to avoid SQL injection, however the text stored should exactly match what was entered.
Microsoft attempts to block inputs that look like XSS via their request validation feature in ASP.NET. However, this isn't very effective and flaws are found quite often. Similar approaches from other frameworks are doomed to fail.
The reason that this is much better is that it makes things much more simple. Imagine if StackOverflow didn't allow HTML or script tags - the site would not be functional as a place for people to post code snippets.
You can use input validation as second line of defence. For example, if you are asking the user to enter their car registration you would only want to allow alphanumerics and space to be entered. However, for more complex fields it is often difficult to restrict input to a safe set as output context is unknown at this stage.
Say your language filtered < and > characters. However you were outputting user input into the following context.
<img src="foo.jpg" alt="USER-INPUT" />
An XSS attack is possible by entering " onmouseover="alert('xss') because it would be rendered as
<img src="foo.jpg" alt="" onmouseover="alert('xss')" />
Similar problems would ensue if you were outputting to JavaScript server-side. This is why it should be up to the developer to select the correct encoding type when using user controlled values.

Rails 3 - Friendly params in url (GET)

I have a rails 3 app and now i implementing filter for my catalog. Filters form pass data to controller through GET request. As a result i have link like this in my browser after i submit
my form (apply search):
http://localhost:3001/shoes?filter%5BShoeBottomType%5D%5B%5D=2&filter%5BShoeClassification%5D%5B%5D=1&filter%5BShoeClassification%5D%5B%5D=2&filter%5BShoeElation%5D%5B%5D=3&filter%5BShoeElation%5D%5B%5D=4&filter%5BShoeElation%5D%5B%5D=5&filter%5BShoeLiningColor%5D%5B%5D=2&filter%5BShoeLiningColor%5D%5B%5D=3&filter%5BShoeLiningColor%5D%5B%5D=4&filter%5BShoeTopColor%5D%5B%5D=1&filter%5BShoeTopColor%5D%5B%5D=2&filter%5Bonly_action%5D%5B%5D=1&page=2
Is there a way to do URL more beautiful?
PS i dont want use POST request, because I read that it is bad for SEO
TLDR: just leave it.
HTML forms serialize in a straightforward manner; the parameters are named after the HTML elements. The actual issue here is how the form elements are named. It looks like they have names like filter[ShoeBottomType][]; look into your HTML to see the name attributes. Since you're in Rails, I'm guessing you having a filter hash passed to your Rails controller method as a single argument, and since Rails expects hashes to use a certain URL format for hashes and arrays (it has to know how to deserialize it from the request), the form helper writes the form that way. And yours is especially complicated because the hash values are arrays, hence the extra set of brackets. Then it's URL encoded and you end up with an ugly mess.
You could avoid some of this problem by passing the inputs individually back to the controller instead of as a big hash. Something like:
def index
shoe_bottom_types = params[:bottom_types]
shoe_classifications = params[:classifications]
shoe_elations = params[:elations]
...
which will get you to: /shoes?bottomTypes[]=1&bottomTypes[]=2.... That doesn't seem much better, and now your controller is all gross. And I don't see how you're going to get rid of the brackets entirely if you want to have more than one of the same filter. I guess you could get crazy and do your own parsing in your controller, like breaking apart shoeBottomTypes=1|2, but then you'll have to do your own form serialization too. Again, just not worth it.
Backing up for a sec, the SEO stuff doesn't make much sense. Search engines won't fill out your form; they just follow links. The real reason you should use GET is that (presumably), submitting your form doesn't have side effects, since it's just a search. See here; it's important to use the right HTTP methods. If you use POST, you'll get weird warnings on reloads and you won't be able to bookmark the search.
Backing up even further, why do you care, especially now that SEO is out of the picture? Just as a quick demo, I did a google search for the word "thing" and this was the URL:
https://www.google.com/#hl=en&output=search&sclient=psy-ab&q=thing&pbx=1&oq=thing&aq=f&aqi=g2g-s1g1&aql=1&gs_sm=3&gs_upl=764l1877l0l1980l6l6l0l0l0l0l89l432l5l5l0&bav=on.2,or.r_gc.r_pw.r_cp.r_qf.,cf.osb&fp=220ef4545fdef788&biw=1920&bih=1086
So URLs for form submissions can be long. The user won't even look at it.
The only possibility I can think of for why you'd care about the length/ugliness of your URL here is that you want, separately from the form, to create links to certain searches. There are several ways to handle that, but since I don't know whether that's relevant to you, I'll let that be a follow-up.
So bottom line, it looks like I'd expect, and trying to fix it sounds ugly and pointless.
If you do not want to use a POST request, then there is no other way then to put the form values in the URL -- they have to get to the server one way or another.
On the other hand however, I do not see why doing a POST would be bad for SEO and I would love to see the article that stated so.
My suggestion is that you could add some custom routes to beautify your urls.
For example :
http://localhost:3001/shoes/Type/2/Classification/1,2/Elation/3,4,5/LiningColor/2,3,4/TopColor/1,2/only_action/1/page/2
This is far much shorter than your initial URL ;)
The counterpart is that, as far as I know, you have to use always the same order for params in your url.
The routing rule is the following :
match "shoes/Type/:type/Classification/:classification/Elation/:elation/LiningColor/:liningcolor/TopColor/:topcolor/only_action/:only_action/page/:page" => "shoes#show"
You can retrieve the passed values in params array. You have to split the string containing , in order to retrieve the multiple values.

How to access AJAX hash values in ASP.NET MVC?

I'm considering using the hash method to create static urls to content that is managed by ajax calls in a Asp.Net MVC. The proof of concept i'm working on is a profile page /user/profile where one can browse and edit different sections. You could always ask for the following url /user/profile#password to access directly to you profile page, in the change password section
However, i'm wondering if i'm not starting this the bad way, since apparently i can't access the part after the hash in any way, except by declaring a route value for the hash in global.asax. So i'm wondering if this is the right way to access this part of the url?
Am i supposed to declare a route value, or is there another way to work with hash values (a framework, javascript or mvc)?
Edited to add:
In pure javascript, i have no problem using the window.location.hash property, i'm not sure though how standard it is in today's browsers, hence the question about a javascript framework/plugin that would use it.
The thing is that the part that follows the hash (#) is never sent to the server into the HTTP request so the server has absolutely no way of reading it. So no need to waste time in searching for something that doesn't exist.
You could on the other hand tune your routes to generate links that contain the hash part so that client scripts can read it.
Send the hash value document.location.hash as a parameter to the controller action of your choice.
This can be done in the code if needed...
RedirectResult(Url.Action("profile") + "#password");
should work fine

mvc.net DateTime with Time part in URI

I have a set of actions that are returning time-series data with-in ranges specifiable to the minute.
They work fine with querystrings,
i.e.
/mycontroller/myaction?from=20091201 10:31&to=20091202 10:34
with or without URL encoded colons, but I thought it would be nice to have a pretty URL
/mycontroller/myaction/from-20091201 10:31/to-20091202 10:34
but this now strikes fear in the hear of IIS as it doesn't like colons in the URI so I get 'Bad Request' responses.
My question then, is what's a recommended/standard course of action to ensure I can keep the time in there?
Do I need to write a custom ModelBinder to parse my own datetime format? Should the actions just take strings for from and to and parse with a custom format eg "YYYYMMDD-HHmm". Can I specify a custom format somewhere? If so where? Or should I just give this up as folly and stick with querystring parameters?
Oh, and I see a lot of people go on about RESTful URLs; from what I've read there's nothing that says query strings aren't RESTful - it's more about appropriate use of existing HTTP action types.
You're right REST doesn't mean if it's its not in a folder structure its not REST.
The path structure is there to describe the resource. Querystrings can still be used to describe a filtered subset of such a resource. A date range fully qualifies as a filter criteria and should thus be perfectly RESTful being passed in as a querystring.

Alternative to ValidateInput("false") when passing HTML to a controller

I have a pretty simple ASP.NET MVC page and am using TinyMCE to allow users to enter comments. However, when I pass the data to a controller I receive the following error message:
A potentially dangerous Request.Form
value was detected from the client
The consensus is that ValidateInput("false") should be set on the Action method but somehow that does not sit well with me. I have tried to intercept this by ordering my action methods and sanitizing the data through my ActionExecitomgContext ActionParameters however this error keeps occurring time and again. Does anyone know of a way to allow this content through (or properly intercept it) without disabling ValidateInput
Do you have specifics on why it doesn't sit well? ValidateInput("false") on the one action that accepts HTML is the proper way to go. The input validation is an old ASP.NET feature that is on by default for security in depth, but is like a sledge hammer. It doesn't understand the nuances of allowed HTML.
For that one action method, you could write your own ValidateSafeHtmlAttribute action filter and put that on the method instead. Maybe that one internally encapsulates a ValidateInput set to false and then does its own validation specific to your scenario. That'd be my recommendation.

Resources