ASP.NET MVC Scripting in js files - asp.net-mvc

I still find myself having to declare global variables in my .aspx files (the project was started before razor). For example I have to declare global javascript variables like this in my .aspx files:
var getDistributionListUrl = '<%= Url.Action("GetDistributionList", "PublicDocument") %>';
I can then reference this variable in my .js files.
Is there a better way?

Is there a better way?
There is nothing wrong with this.
Personally I use HTML5 data-* attributes on some DOM elements that I am manipulating later in my scripts. For example:
<div id="foo" data-url="<%= Url.Action("GetDistributionList", "PublicDocument") %>">
Hello
</div>
and then in my js:
$('#foo').click(function() {
var url = $(this).data('url');
...
});
But in 99.99% of the cases those urls are associated with either <form> elements or link hrefs so in my javascript I simply retrieve and use this value when I need to do some progressive enhancement on the given DOM element (like unobtrusively AJAXifying forms or anchors).

Related

ASP.NET MVC XSS protection

According to OWASP XSS page, one needs to use different XSS protection techniques for different contexts. However, in ASP.NET MVC Razor views, we only have the # sign to escape data in the context of HTML element inner content. What about HTML attributes, CSS, javascript contexts and others?
HTML element content
This is safe and will work as expected:
<div>#data</data>
HTML element attribute
This is not safe and can be exploited:
<div style="background: #color"></div>
JavaScript
While this is not safe:
<script>
var value = #value;
</script>
Safe solution is:
<script>
var value = #Json.Encode(value);
</script>
CSS
This is not safe and can be exploited:
<style>
.box { background : #color; }
</style>
A great thing about razor is that it does all the HTML encoding by default. Unless you use #Html.Raw(), it is pretty difficult to make your page vulnerable. You generally have to explicitly make variables render as html.
You also have Html.Encode() if you need it. There is also HttpUtility.JavaScriptStringEncode()
Regarding the updated vulnerable code:
#{var js = "alert(1);";}
<script>var value = #js</script>
I think you would be violating rule 0 with this code. You are inserting arbitrary strings into a script tag, and expecting it not to be executed. I actually get a syntax error (warning) with your example, but it will still run. If you wrapped it in quotes, you would be safe.
#{var js = "\"alert(1);";}
<script>var value = "#js"; alert(value);</script>
output:
"alert(1);
Notice that the quote that I put in the string gets escaped to ", making me unable to break out of the string, so I cannot inject js.
I'd be interested to see if someone has a way of sanitizing this without putting it in quotes, but I am skeptical.
update 2:
Dealing with CSS
The examples you give are not about escaping strings, it is more about inserting untrusted CSS into your page. To do that, you will need something that can parse CSS. For example, it is not that you want the value to be encoded, you just want it not to include the dangerous stuff like url(javascript:), behavior, binding, etc. You'll need a CSS filtering tool for that.
HTML attributes
you are safe if you do this:
<div data-color="#color"></div>
Since razor encodes quotes, you won't be able to terminate the string early. That's as simple as it is to prevent XSS (barring some unknown vulnerability in razor). Your Json.Encode() uses the same idea.
BUT, you are doing somehting risky if you do this:
<div #attribute></div>
Again, it's not that you need an escaped string here, you want something that filters your attributes on any dangerous content. The fact is, that doing things this way is really messy, and I would advise against it. It is bad design because it is screwing up your separation of concerns and making it hard to secure your app from XSS. What you should do instead is add CSS classes if you want to change the style. If you need to set an attribute based on a variable in razor, use something else rather than injecting it into your HTML and hoping to filter it.
ex:
#{
var disabled = isDivDisabled ? "disabled" : "";
}
<div #disabled><div>

Dart: dynamic redirection without reload

Please note I'm not interested in a Polymer-, Angular- or route-based solution here. I'm trying to learn "pure" Dart here, and while I'll likely switch to using one of those frameworks down the road, I need to have a good understanding of the fundamentals first.
In Dart, is it possible to download a whole bunch of HTML "snippets" (see below) all at once (at app startup), and then load them into the browser (either the entire window or just inside a particular <div> element, etc.) dynamically?
For instance, my HTML file might have a <div> element:
<body>
<!-- lots of HTML -->
<div id="container"></div>
<!-- more HTML -->
</body>
And I would like to download two "snippets" (DOM subtrees, HTML templates) of HTML, and dynamically load either one of them into the container div tag. Perhaps one of the snippets looks like this:
<h1>I'm Snippet #1!!!</h1>
<input type="button" name="redPillButton" value="Red Pill!" />
And another snippet my look like:
<h1>I'm Snippet #2!!!</h1>
<input type="button" name="bluePillButton" value="Blue Pill!" />
Can the two snippets be inside their own HTML file, or do I have to put them inside one big file and extract out the "snippet" that I want to load? Either way, how do I accomplish this in a Dart web app?
You can keep each parts in their own file and load them like that :
HttpRequest.getString("part.html").then((html) {
querySelector('#container').innerHtml = html;
});

How to localize javascript files in a Struts 2 app

I wrote an Struts 2 application and want to localize it. Now I am using javascript and I would like to put the scripts out of my HTML template to an own javascript file.
When I do it, my s:text tags are not rendered (of course).
Question is how can I localize my javascript files with Struts 2 in a clean way? I would like to avoid to use another technique than the properties files i currently use.
Thanks,
Christian
If you want to stick with your resource bundles back at server, one way possible would be to save your javascript files as .jsp file and serve them with an action so this way your struts tags in your javascript files will get a chance to retrieve the data from server and return the file upon request.
Personally I prefer to keep client messages in javascript files and server messages in resource bundles. This way you can save a .jsp processing IMHO.
You can use a hidden field in your JSP and pass its id to the external JavaScript file and get its value like follows.
In your JSP,
<s:hidden id="warning" value="%{getText('propertyKey')}"/>
(hidden field poplated with the value of the property key in the resource bundle)
Call your external JS method from the same JSP,
<s:a href="%{deleteSelected}">
<img src="<s:url value='/images/delete.gif'/>" border="none"
onclick="javascript:return displayWarning('warning')"/>
</s:a>
In external JavaScript file,
function displayWarning(message) {
var ret = true;
ret = confirm(document.getElementById(message).value);
return ret;
}
<script type="text/javascript">
var mytxt='<s:text name="my.text.prop" />';
alert(mytxt);
</script>
This is also possible, but you cant have them inside a function.You should assign relevant properties to global JS variable at the time of page load. Almost same concept slimier to use hidden variables.

Serving static content to my action using MVC's convention approach

I'm looking at outsourcing some in-page help on a large web application I am creating and would like to make it really easy for this content to added to our pages when we're ready for it.
So I was thinking I could create a system where I can add text files to the same folder where an action expects it's view to be and read out the content of that file the content in that file can be passed back to the view to display. Either that or create a helper that would do the same.
Example
Controllers
HomeController.cs
Views
Home
Index.aspx
Index.txt
Index.aspx would then have access to the content in Index.txt.
How would I start going about creating this system. Are there any built in classes in .NET MVC that I could take advantage of?
A similar question was asked yesterday: Including static html file from ~/Content into ASP.NET MVC view.
Basically you can read the text from the file and include it inside your view by using File.ReadAllText so you would have something like this inside your index.aspx file
<%= File.ReadAllText(Server.MapPath("~/Views/Home/index.txt")) %>
I'd create a parallel hierarchy in the Content folder and put the files there, probably as HTML. Then you can simply load them via AJAX in the view using the parallel hierarchy convention.
Content
Help
Home
index-help.html
about-help.html
Foo
index-help.html
bar-help.html
Then in your views
<div class="help">
<noscript>
<a href='#Url.Content( "~/content/help/home/index-help.html" )'>Click for Help</a>
</noscript>
</div>
<script type="text/javascript">
$(function() {
$('.help').load( '#Url.Content( "~/content/help/home/index-help.html" )' );
});
</script>
You may also be able to extract the controller/action from RouteData in the view if your routes are consistent and move this to your _Layout.cshtml file with the path being provided by route data.
#{
var controller = ViewContext.RouteData["controller"] as string;
var action = ViewContext.RouteData["action"] as string;
var url = Url.Content( string.Format( "~/content/help/{0}/{1}-help.html", controller, action ) );
<div class="help">
<noscript>
<a href="#url>Click for Help</a>
</noscript>
</div>
<script type="text/javascript">
$(function() {
$('.help').load( "#url" );
});
</script>
}
One possible solution would be to store them as xml file instead, that are serialized from the model the view is expecting. You could then create an Action Filter populate the model being returned with the data from the XML file. I hope that helps.

How can I get just href part of Html.ActionLink result text

As you know,
<%=Html.ActionLink("Back to List", "Index") %>
generates html like this : Back To List
But I need just href part.
I will use it in JS code and I do not want to write manually.
Can I gerenate what I need part ?
Try this
<%=Url.Action("Action","Controller")%>
Mathias's answer is what I use. ASP.NET MVC 2 gives you strongly types Url.Action too.
I find this most useful in javascript so:
<script type="text/javascript">
var urlToPostTo = '<%= Url.Action<HomeController>(h => h.ContactUs()) %>';
var someData = 'Some valuable data!';
$.post(urlToPostTo, someData, function()
{
alert('Successfully posted some data to some url');
});
</script>
This allows you to avoid putting hardcoded paths in your markup, leaving you with a slightly more maintainable solution.
That said, I'm still hoping that these will be compile time checked as normal when MVC 2 is finally released.

Resources