Search code examples
webpackconfiguration-filessecret-key

How to prevent confidential data from being included in WebPack bundles


I'm worried that, by ommission, modules containing secrets like database passwords or session keys could be included in WebPack or Browserify bundles.

Even if I don't import those modules directly, I could accidentally import them indirectly from the client-side entrypoint module.

Is there a way to blacklist such files so that those bundlers will refuse to bundle them? As willing as one might be to follow best practices that could avoid problems like this, it would be nice to have such a safety net.


Solution

  • When importing files via loaders, you can choose either to blacklist or whitelist directories through the include and exclude properties. These can be a RegEx or absolute paths.

    A simple example

    The following prevents any JavaScript file from being included in the bundle that exists in the ./secret directory.

     var path = require('path');
            module.exports = {
              // Configuration omitted for brevity
              module :{
                loaders : [
                    { 
                      test: /\.js$/, 
                      loader: "script",
                      exclude : path.resolve(__dirname, './secret')  // Exclude secret directory
                    },
                    { 
                      test: /\.css$/, 
                      loader: "style!css" 
                    }
                ]
              }
            };
    

    Complex example applying filters for all loaders

    If you wanted to prevent files from the ./secret directory from being accidentally imported, and only allow files within that contain src you could do the following.

    var path = require('path');
    var blackList = [ path.resolve(__dirname, './secret') ];
    var whiteList = [ /src/ ]; // Allow only directories containing "src"
    
    var config = { 
    ...
    /// Webpack configuration
    };
    
    // Apply whitelisting and blacklisting for all loaders
    config.module.loaders.forEach(function(loader)
    {
       loader['exclude'] = [...(loader['exclude'] || []), ...blackList];
       loader['include'] = [...(loader['include'] || []), ...whiteList];
    });
    
    module.exports = config;
    

    The example is a bit complex, but it should give you a good idea how to perform it. In a nutshell, loop though your loaders and append additional includes/excludes as needed.

    Bonus: Give type to your secret data

    If you do have confidential data existing in your code base, I suggest providing a type to the filename. For example, if your file was named sqlconnections.js I would rename it to sqlconnections.confidential.js. Then I would add an exclude RegEx pattern of /\.confidential\.js$/ to my loaders. This creates a convention that can be reused across your code base.