A beginner’s introduction to Webpack

Psssst! I’m working on a Vue.js Course. Stay in the loop, sign up here and immediately get my Vue.js free ebook and soon the Vue.js Cheat Sheet!🔥

What is Webpack?

Webpack is a tool that lets you compile JavaScript modules. It’s also known as a module bundler.

Given a large number of files, it generates a single file (or a few files) that run your app.

It can perform many operations:

  • helps you bundle your resources.
  • watches for changes and re-runs the tasks.
  • can run Babel transpilation to ES5, allowing you to use the latest JavaScript features without worrying about browser support.
  • can transpile CoffeeScript to JavaScript
  • can convert inline images to data URIs.
  • allows you to use require() for CSS files.
  • can run a development webserver.
  • can handle hot module replacement.
  • can split the output files into multiple files to avoid having a huge JS file to load in the first page hit.
  • can perform tree shaking.

Webpack is not limited to being used on the front-end, but is useful in backend Node.js development as well.

There are many predecessors of Webpack and lots of similarities in what those tools and Webpack do. The main difference is that those tools are known as task runners, while Webpack was born as a module bundler.

Webpack is a more focused tool. You just need to specify an entry point to your app (it could even be an HTML file with script tags) and webpack analyzes the files and bundles them in a single JavaScript output file that includes everything you need to run the app.

Installing Webpack

Webpack can be installed globally or locally for each project.

Global install

Here’s how to install it globally with Yarn:

yarn global add webpack webpack-cli

with npm:

npm i -g webpack webpack-cli

once this is done, you should be able to run

webpack-cli

Local Install

Webpack can be installed locally as well. It’s the recommended setup, because Webpack can be updated per-project, and you have less resistance in using the latest features just for a small project rather than updating all the projects you have that use Webpack.

With Yarn:

yarn add webpack webpack-cli -D

with npm:

npm i webpack webpack-cli --save-dev

Once this is done, add this to your package.json file:

{ 
  //... 
  "scripts": { 
    "build": "webpack" 
  } 
}

Once this is done, you can run Webpack by typing

yarn build

in the project root.

Webpack configuration

By default, Webpack (starting from version 4) does not require any config if you respect these conventions:

  • the entry point of your app is ./src/index.js
  • the output is put in ./dist/main.js.
  • Webpack works in production mode

You can customize every little bit of Webpack of course, when you need. The Webpack configuration is stored in the webpack.config.js file, in the project root folder.

The entry point

By default the entry point is ./src/index.js This simple example uses the ./index.js file as a starting point:

module.exports = {
  /*...*/
  entry: './index.js'
  /*...*/
}

The output

By default the output is generated in ./dist/main.js. This example puts the output bundle into app.js:

module.exports = {
  /*...*/
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'app.js'
  }
  /*...*/
}

Using Webpack allows you to use import or require statements in your JavaScript code not just to include other JavaScript, but any kind of file (for example CSS).

Webpack aims to handle all our dependencies, not just JavaScript, and loaders are one way to do that.

For example, in your code you can use:

import 'style.css'

by using this loader configuration:

module.exports = {
  /*...*/
  module: {
    rules: [
      { test: /\.css$/, use: 'css-loader' },
    }]
  }
  /*...*/
}

The regular expression targets any CSS file.

A loader can have options:

module.exports = {
  /*...*/
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: 'css-loader',
            options: {
              modules: true
            }
          }
        ]
      }
    ]
  }
  /*...*/
}

You can require multiple loaders for each rule:

module.exports = {
  /*...*/
  module: {
    rules: [
      {
        test: /\.css$/,
        use:
          [
            'style-loader',
            'css-loader',
          ]
      }
    ]
  }
  /*...*/
}

In this example, css-loader interprets the import 'style.css' directive in the CSS. style-loader is then responsible for injecting that CSS in the DOM, using a <style> tag.

The order matters, and it’s reversed (the last is executed first).

What kind of loaders are there? Many! You can find the full list here.

A commonly used loader is Babel, which is used to transpile modern JavaScript to ES5 code:

module.exports = {
  /*...*/
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }
    ]
  }
  /*...*/
}

This example makes Babel preprocess all our React/JSX files:

module.exports = {
  /*...*/
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: 'babel-loader'
      }
    ]
  },
  resolve: {
    extensions: [
      '.js',
      '.jsx'
    ]
  }
  /*...*/
}

See the babel-loader options here.

Plugins

Plugins are like loaders, but on steroids. They can do things that loaders can’t do, and they are the main building blocks of Webpack.

Take this example:

module.exports = {
  /*...*/
  plugins: [
    new HTMLWebpackPlugin()
  ]
  /*...*/
}

The HTMLWebpackPlugin plugin does the job of automatically creating an HTML file and adding the output JS bundle path, so the JavaScript is ready to be served.

There are lots of plugins available.

One useful plugin, CleanWebpackPlugin, can be used to clear the dist/ folder before creating any output, so you don’t leave files around when you change the names of the output files:

module.exports = {
  /*...*/
  plugins: [
    new CleanWebpackPlugin(['dist']),
  ]
  /*...*/
}

The Webpack mode

This mode (introduced in Webpack 4) sets the environment on which Webpack works. It can be set to development or production (defaults to production, so you only set it when moving to development).

module.exports = {
  entry: './index.js',
  mode: 'development',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'app.js'
  }
}

Development mode:

  • builds very fast
  • is less optimized than production
  • does not remove comments
  • provides more detailed error messages and suggestions
  • provides a better debugging experience

Production mode is slower to build, since it needs to generate a more optimized bundle. The resulting JavaScript file is smaller in size, as it removes many things that are not needed in production.

I made a sample app that just prints a console.log statement.

Here’s the production bundle:

Here’s the development bundle:

Running Webpack

Webpack can be run from the command line manually if installed globally. But generally you write a script inside the package.json file, which is then run using npm or yarn.

For example this package.json scripts definition we used before:

"scripts": {
  "build": "webpack"
}

allows us to run webpack by running

npm run build

or

yarn run build

or simply

yarn build

Watching changes

Webpack can automatically rebuild the bundle when a change in your app happens, and it keeps listening for the next change.

Just add this script:

"scripts": {
  "watch": "webpack --watch"
}

and run

npm run watch

or

yarn run watch

or simply

yarn watch

One nice feature of the watch mode is that the bundle is only changed if the build has no errors. If there are errors, watch will keep listening for changes, and try to rebuild the bundle, but the current, working bundle is not affected by those problematic builds.

Handling images

Webpack allows you to use images in a very convenient way, using the file-loader loader.

This simple configuration:

module.exports = {
  /*...*/
  module: {
    rules: [
      {
        test: /\.(png|svg|jpg|gif)$/,
        use: [
          'file-loader'
        ]
      }
    ]
  }
  /*...*/
}

Allows you to import images in your JavaScript:

import Icon from './icon.png'

const img = new Image()
img.src = Icon
element.appendChild(img)

Where img is an HTMLImageElement. Check out the Image docs.

file-loader can handle other asset types as well, like fonts, CSV files, XML, and more.

Another nice tool to work with images is the url-loader loader.

This example loads any PNG file smaller than 8KB as a data URL.

module.exports = {
  /*...*/
  module: {
    rules: [
      {
        test: /\.png$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 8192
            }
          }
        ]
      }
    ]
  }
  /*...*/
}

Process your SASS code and transform it to CSS

Using sass-loadercss-loader and style-loader:

module.exports = {
  /*...*/
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: [
          'style-loader',
          'css-loader',
          'sass-loader'
        ]
      }
    ]
  }
  /*...*/
}

Generate Source Maps

Since Webpack bundles the code, Source Maps are mandatory to get a reference to the original file that raised an error. For example:

You tell Webpack to generate source maps using the devtool property of the configuration:

module.exports = {
  /*...*/
  devtool: 'inline-source-map',
  /*...*/
}

devtool has many possible values, the most used probably are:

  • none: adds no source maps
  • source-map: ideal for production, provides a separate source map that can be minimized, and adds a reference into the bundle, so development tools know that the source map is available. Of course you should configure the server to avoid shipping this, and just use it for debugging purposes
  • inline-source-map: ideal for development, inlines the source map as a Data URL

Psssst! I’m working on a Vue.js Course. Stay in the loop, sign up here and immediately get my Vue.js free ebook and soon the Vue.js Cheat Sheet!🔥


Originally published at flaviocopes.com.

How I used a simple Google query to mine passwords from dozens of public Trello boards

A few days ago on 25th April, while researching, I found that a lot of individuals and companies are putting their sensitive information on their public Trello boards. Information like unfixed bugs and security vulnerabilitiesthe credentials of their social media accountsemail accountsserver and admin dashboards — you name it, is available on their public Trello Boards which are being indexed by all the search engines and anyone can easily find them.

How did I discover this?

I searched for Jira instances of companies running Bug Bounty Programs with the following search query:

inurl:jira AND intitle:login AND inurl:[company_name]

Note: I used a Google dork query, sometimes referred to as a dork. It is a search string that uses advanced search operators to find information that is not readily available on a website. — WhatIs.com

I entered Trello in place of [company name]. Google presented a few results on Trello Boards. Their visibility was set to Public, and they displayed login details to some Jira instances. It was around 8:19 AM, UTC.

I was so shocked and amazed 😲

So why was this a problem? Well, Trello is an online tool for managing projects and personal tasks. And it has Boards which are used to manage those projects and tasks. The user can set the visibility of their boards to Private or Public.

After finding this flaw, I thought — why not check for other security issues like email account credentials?

I went on to modify my search query to focus on Trello Boards containing the passwords for Gmail accounts.

inurl:https://trello.com AND intext:@gmail.com AND intext:password

And what about SSH and FTP?

inurl:https://trello.com AND intext:ftp AND intext:password
inurl:https://trello.com AND intext:ssh AND intext:password

🔎 What else I found

After spending a few hours using this technique, I uncovered more amazing discoveries. All while I kept on changing my search query.

Some companies use Public Trello boards to manage bugs and security vulnerabilities found in their applications and websites.

People also use Public Trello boards as a fancy public password manager for their organization’s credentials.

Some examples included the server, CMSCRM, business emails, social media accounts, website analytics, Stripe, AdWords accounts, and much more.

Examples of public Trello boards which contain sensitive credentials

Here’s another example:

An NGO sharing login details to their Donor Management Software (database) which contained a lot of PII (personally identifiable information), and details like donor and financial records

Until then I was not focusing on any specific company or Bug Bounty Programs.

But nine hours after I discovered this Trello vulnerability, I had found the contact details of almost 25 companies that were leaking some very sensitive information. So I reported them. Finding contact details for some of them was a tedious and challenging task.

I posted about this in a private Slack of bug bounty hunters and a infosec Discord server. I also tweeted about this right after discovering this Trello technique. The people there were as amazed and astonished as I was.

Then people started telling me that they were finding cool things like business emails, Jira credentials, and sensitive internal information of Bug Bounty Programs through the Trello technique I shared.

Almost 10 hours after discovering this Trello technique, I started testing companies running Bug Bounty Programs specifically. I then began with checking a well-known ridesharing company using the search query.

inurl:https://trello.com AND intext:[company_name]

I instantly found a Trello board that contained login details of an emplyee’s business email account, and another that contained some internal information.

To verify this, I contacted someone from their Security Team. They said they had received a report about the Board containing email credentials of an employee right before mine and about the other board containing some internal information. The security team asked me to submit a complete report to them because this is a new finding.

Unfortunately, my report got closed as a Duplicate. The ridesharing company later found out that they had already had received a report about the Trello board I found.

In the coming days, I reported issues to 15 more companies about their Trello boards that were leaking highly sensitive information about their organizations. Some were big companies, but many don’t run a Bug Bounty Program.

One of the 15 companies was running a Bug Bounty Program, however, so I reported to them through it. Unfortunately, they didn’t reward me because it was an issue for which they currently don’t pay. 🤷

Update — 18 May 2018:

And just the other day, I found a bunch of public Trello Boards containing really sensitive information (including login details!) of a government. Amazing!

The Next Web and Security Affairs has also reported about this.

Thanks for reading my story.

Disable TLS 1.0 And 1.1 On Windows Server.

If you have a business need to disable these protocols on your engine servers in your environment Below is a snippet of the required registry changes you will need to make. You should be aware that you would have no reasonable expectation for the engine server to be able to interact with target systems that still use these protocols.

TLS 1.0

This subkey controls the use of TLS 1.0.

Applicable versions: As designated in the Applies To list that is at the beginning of this topic.

Registry path: HKLM SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocos

To disable the TLS 1.0 protocol, create an Enabled entry in the appropriate subkey. This entry does not exist in the registry by default. After you have created the entry, change the DWORD value to 0. To enable the protocol, change the DWORD value to 1.

TLS 1.0 subkey table

Subkey Description Default
Client Controls the use of TLS 1.0 on the client. Enabled
Server Controls the use of TLS 1.0 on the server. Enabled
DisabledByDefault Flag to disable TLS 1.0 by default. Enabled

TLS 1.1

This subkey controls the use of TLS 1.1.

Applicable versions: As designated in the Applies To list that is at the beginning of this topic excluding those versions prior to Windows Server 2008 R2 and Windows 7.

Registry path: HKLM SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols

To disable the TLS 1.1 protocol, create an Enabled entry in the appropriate subkey. This entry does not exist in the registry by default. After you have created the entry, change the DWORD value to 0. To enable the protocol, change the DWORD value to 1.

TLS 1.1 subkey table

Subkey Description Default
Client Controls the use of TLS 1.1 on the client. Enabled
Server Controls the use of TLS 1.1 on the server. Enabled
DisabledByDefault Flag to disable TLS 1.1 by default. Enabled

 

Enabling WPA2-Enterprise in Windows Vista and Windows 7

It is important to manually configure WPA2-Enterprise for your wireless network profile in Windows Vista and Windows 7. You must not be in the process of associating to the SSID because the configurations will not save correctly. Follow the steps below to configure WPA2-Enterprise.

  1. In Windows, navigate to Control Panel > Network and Internet > Network and Sharing Center.
  2. Click Manage Wireless networks.
  3. Click Add.
  4. Choose Manually create a network profile.
  5. On the next page, enter the following:
  • Network name: This is the SSID name. It is case sensitive.
  • Security type: Choose WPA2-Enterprise.
  • Encryption type: Choose AES.
  • Check Start this connection automatically if you want Windows to connect to this network automatically.
  • Check Connect even if the network is not broadcasting if the SSID is hidden and you want Windows to connect to this network automatically.

Click Next.

If the RADIUS server has a certificate that may not be trusted by the wireless client or is not a member of the domain in which the RADIUS server resides, on the “Successfully added” page, click Change connection settings.

  1. Choose the Security tab.
  1. Click Settings.
  2. Uncheck Validate server certificate if the wireless client may not trust the RADIUS server certificate.
  3. For the Authentication Method, choose EAP-MSCHAP v2.
  4. Click Configure.
  5. Uncheck Automatically use my Windows logon on name and password if the computer is not on the domain.
  6. Click OK.

It may be required to specify user or computer authentication based on whether the client is part of the domain or if machine or user authentication is a condition of the RADIUS policy.

To choose user or computer authentication, from the Security tab,

 a) Click Advanced settings.

b) Select the 802.1X settingstab.

c) Check Specify authentication mode.

d) Choose User or computer authentication. Or choose an alternate option if required.

e) Click OK to close out.

Note: Your computer will use your Windows logon credentials and domain unless you uncheck the box as shown in the Step 12 screenshot.

WPA2-Enterprise with 802.1X Authentication

https://documentation.meraki.com/MR/Encryption_and_Authentication/Wireless_Encryption_and_Authentication_Overview

RADIUS: Configuring PEAP EAP-MSCHAPv2

/Wireless_LAN/Encryption_and_Authentication/Enterprise_(802.1X)/RADIUS:_WPA2-Enterprise_With_PEAP-MSCHAPv2_Using_Microsoft_NPS

How to run Firefox when your profile is missing or inaccessible

If you see a “Profile Missing” error message that says, Your Firefox profile cannot be loaded. It may be missing or inaccessible it usually means that Firefox can’t find or access the profile folder. This article explains what to do if you see this error.

FXprofile-cannot-be-loaded

Table of Contents

  • If you moved, renamed, or deleted your Firefox profile folder
    • Profile was moved or renamed
    • Profile was deleted

If you moved, renamed, or deleted your Firefox profile folder

Firefox stores your user data and settings in a special profile folder and pulls information from this folder every time you start Firefox. The default profile folder location is under the %APPDATA%\Mozilla\Firefox\Profiles folder, which you can find using these instructions.

Profile was moved or renamed

If you know where your profile is, try one of the following methods to help Firefox find it.

  • Move the profile folder back to its original location.
  • Restore the profile’s original name if you’ve changed it.
  • Create a new profile using the Profile Manager. Give it a descriptive name, click on the Choose Folder button, and then select the profile folder you moved or renamed, before you finish the Create a new profile wizard.

Profile was deleted

If you deleted or lost your profile folder and have no way of restoring it, use one of these methods to create a new Firefox profile:

Your new profile will not contain settings or user data from your deleted or lost profile.
  • Method 1: Use the Profile Manager wizard

Follow the steps in the Use the Profile Manager to create and remove Firefox profiles article to create a new profile.

  • Method 2: Manually delete the profiles.ini file

If you have problems accessing the Profile Manager, you can create a new default Firefox profile by deleting the profiles.ini file, using these steps:

  1. Click on the Windows Start button or press the Windows key Windows Key to open the Start Menu.
  2. Type %appdata% (as you type, a Windows search will start) and press the Enter key. The hidden AppData\Roaming folder will open.
  3. Double-click the Mozilla folder.
  4. Double-click the Firefox folder.
  5. Delete (or rename, for example, to profiles.iniOLD) the profiles.ini file.
Note: Instead of deleting the profiles.ini file, you can delete (or rename) the folder that contains it. For example, right-click the Firefox folder and rename it FirefoxOLD.
When you start Firefox, a new profile will be created.