2

ASP.NET Mono MVC 4 application uses MVC4 built in bundling and minification for css and js files.

If user agent string in request is changed to Eureka/1 using fiddler

User-Agent: Eureka/1

and request is re-issued, whole source code with all comments are sent to client.

How to prevent this so that comments in source code code cannot inspected by client ?

Source: http://www.codeproject.com/Articles/728146/ASP-NET-MVC-bundles-internals

I tried to add debug='false' to web.config but problem persists.

MikeSmithDev
  • 15,731
  • 4
  • 58
  • 89
Andrus
  • 26,339
  • 60
  • 204
  • 378

2 Answers2

4

I was able to remove comments by creating a classes that inherit from IBundleBuilder. This is written for Microsoft ASP.NET Web Optimization Framework 1.1.3 which was updated on 2/20/2014:

public class ScriptBundleBuilder : IBundleBuilder
{
    public virtual string BuildBundleContent(Bundle bundle, BundleContext context, IEnumerable<BundleFile> files)
    {
        var content = new StringBuilder();
        foreach (var file in files)
        {
            FileInfo f = new FileInfo(HttpContext.Current.Server.MapPath(file.VirtualFile.VirtualPath));
            Microsoft.Ajax.Utilities.CodeSettings settings = new Microsoft.Ajax.Utilities.CodeSettings();
            settings.RemoveUnneededCode = true;
            settings.StripDebugStatements = true;
            settings.PreserveImportantComments = false;
            settings.TermSemicolons = true;
            var minifier = new Microsoft.Ajax.Utilities.Minifier();
            content.Append(minifier.MinifyJavaScript(Read(f), settings));
        }

        return content.ToString();
    }

    private string Read(FileInfo file)
    {
        using (var r = file.OpenText())
        {
            return r.ReadToEnd();
        }
    }
} 

public class StyleBundleBuilder : IBundleBuilder
{
    public virtual string BuildBundleContent(Bundle bundle, BundleContext context, IEnumerable<BundleFile> files)
    {
        var content = new StringBuilder();
        foreach (var file in files)
        {   
            FileInfo f = new FileInfo(HttpContext.Current.Server.MapPath(file.VirtualFile.VirtualPath));
            Microsoft.Ajax.Utilities.CssSettings settings = new Microsoft.Ajax.Utilities.CssSettings();
            settings.CommentMode = Microsoft.Ajax.Utilities.CssComment.None;
            var minifier = new Microsoft.Ajax.Utilities.Minifier();
            content.Append(minifier.MinifyStyleSheet(Read(f), settings));
        }

        return content.ToString();
    }

    private string Read(FileInfo file)
    {
        using (var r = file.OpenText())
        {
            return r.ReadToEnd();
        }
    }
} 

And then telling the bundle to use this builder. This example is for a StyleBundle:

public static void RegisterBundles(BundleCollection bundles)
{
    var bundle = new StyleBundle("~/Content/themes/base/css");
    bundle.Builder = new StyleBundleBuilder();
    bundle.Include("~/Content/themes/base/jquery.ui.core.css",
        "~/Content/themes/base/jquery.ui.resizable.css",
        //etc
        );
    bundles.Add(bundle);

    var scriptBundle = new ScriptBundle("~/bundles/modernizr");
    scriptBundle.Builder = new ScriptBundleBuilder();
    scriptBundle.Include("~/Scripts/modernizr-*");
    bundles.Add(scriptBundle);

    BundleTable.EnableOptimizations = true; //for testing
}

This was tested/confirmed in Chrome by changing the user-agent to Eureka/1.0.

For at least some previous versions of the Web Optimization framework (1.0 and prior I think), the only difference was the final parameter. So it would look like public virtual string BuildBundleContent(Bundle bundle, BundleContext context, IEnumerable<FileInfo> files) and requires only minor changes to make work... though you're likely better off just updating.

Concerning this problem and one brought up in another recent SO post about how licensing information gets stripped out during minification... I made a NuGet Package to address these issues.

Community
  • 1
  • 1
MikeSmithDev
  • 15,731
  • 4
  • 58
  • 89
  • This outputs `/* Minification failed. Returning unminified contents. (1,177643): run-time error CSS1062: Expected semicolon or closing curly-brace, found '/' */ ` to start of minified css file. It looks like minification is tried two times. How to remove this error from output? – Andrus Feb 24 '14 at 20:59
  • @Andrus do you not get that error with regular minification (without using the Builder)? That error can happen under normal circumstances depending on your style sheets. – MikeSmithDev Feb 24 '14 at 21:04
  • How to make it work for js files also ? I tried `Microsoft.Ajax.Utilities.JsSettings settings` but JsSettings property does not exist – Andrus Feb 24 '14 at 21:22
  • @Andrus OK give me a second I will update for JS and also for the new 1.1.3 version. I couldn't replicate your issue even after including previously minified files. It could problem with your original files. Sometimes updating the Optimization package fixes these issues. – MikeSmithDev Feb 24 '14 at 21:29
  • @Andrus updated. You'd need to update the Package as well as the 3rd param changed. – MikeSmithDev Feb 24 '14 at 21:45
  • Adding `content.Append(";")` to end of for loop fixes my error. Your code concatenates files without adding separator. Maybe to merge both classes into single one with two methods, there is code duplication – Andrus Feb 25 '14 at 11:13
  • 1
    @Andrus You are correct about the separator -- sorry I didn't notice. I updated answer with `settings.TermSemicolons = true;` which fixes as well. As for code duplication, yes that "Read" method is in both just to make this copy/pastable for someone for scripts or styles, and should be separated out to a centralized location. – MikeSmithDev Feb 25 '14 at 12:30
0

I know the question is regarding changing the behaviour of the bundle process in MVC, but as an alternative, you could create build/deploy scripts that minify your CSS/JS before being published. You could use some of the applications in this answer

Community
  • 1
  • 1
CtrlDot
  • 2,463
  • 14
  • 11