Try. Learn. Repeat.

Welcome to

I’m a JavaScripter writing about web software development. I write about other interests too.

Tennis, cars, videography, music, composition of the universe, the aesthetics of everything, and Batman tend to be on my mind as well.


Find me on

How to Talk While Coding and Whiteboarding in 7 Steps

- - posted in Communication for Engineers, JavaScript, career development, communication skills, dev job search | Comments

Photo of whiteboarding

In my first article on Communication For Engineers, I ranted about my disappointment surrounding engineering and communication skills. I ended that blog post with a list of communication-related topics that I promised to write about. Instead of addressing any of those topics (sorry!), this post will talk about how software engineers can improve their communication while coding collaboratively or while solving coding challenges for a job interview.

Warning: JavaScript is my specialty, so some of the advice below is JS-centric, and all code examples are written in JS.

I cooked up 7 steps for how to discuss code smoothly:

  1. Draw the situation
  2. Ask clarifying questions
  3. Explain approach
  4. Breadth-first coding
  5. Refactor
  6. Walkthrough
  7. Testing

Notice that these steps don’t magically provide a complete guide to actually solving problems. For example, they don’t tell you which data structures to use. Instead, these steps show you how to communicate better as you solve a challenge. They help you talk with your interviewer or colleague about the problem space, your initial impressions, your ability to break down the problem into sub-problems, and your quality assurance process.

The 7 Steps Explained

1. Drawing the Problem

Admittedly, this step could be optional. Drawing is best for folks who work well with visuals. But even if you’re not an artist, you should still consider drawing a diagram or picture of the problem because visuals tend to be effective tools for communicating complex subjects and situations. For example, data structures are usually easier to talk about after you draw them out.

Furthermore, you might reveal certain questions through the act of drawing. At the very least, drawing stuff out can help an interviewer follow you. Going back to the data structures example: imagine you’re supposed to work with a binary tree. It’s easier to talk about it if you draw a tree and point to nodes rather than just saying, “First we will process the root node, then we will go to the left child and do blah blah blah. At that point, depending on the value, we might go down to the child’s child or we might…”

By the way, you don’t have to stick to drawing pictures. This step could be about writing down example data, example inputs, example outputs, example use cases; and then mapping them together by drawing arrows, circles, etc. Examples are great for communication, and they are also good for problem-solving in general. Try to think of examples that are really simple (to get a basic grasp of the problem), examples that are more realistic, and examples that are crazy (to reveal edge cases and potential validation concerns).

2. Asking Clarifying Questions

Do not follow any of your assumptions without asking a question first. It’s tempting to hear a challenge or puzzle and immediately get into solving it. But there are real-world concerns for real-world problems, and you should demonstrate your familiarity with such issues.

Also, you can save time by asking clarifying questions during an interview because interview challenges tend to be contrived. Do you have to account for crazy input values? Does the output need to be formatted in a certain way? If the puzzle involves numbers, do you have to account for negative values, decimals, etc? Are you expected to do input validation, error handling, or memory optimization?

3. Explaining Your Approach

At this point, you might have a solution in mind and you’re eager to get coding. Or you might just have a partial solution. Either way, take a moment to give a quick overview of the purpose of the code you’re about to write. Also, give a sense of what algorithms or concepts will be implemented as part of your approach to the problem at hand.

For example, “This looks like a problem we can solve with a recursive solution that traverses all nodes of the dataset.” In this example, “recursion” is the concept and traversal is the purpose.

4. Breadth-First Coding

When it comes time to actually write out some code (or pseudocode), write out as much as possible at a high-level before going into the low-level details. For example, if your solution requires looping over objects received from an AJAX request in order to parse some data, don’t dive into that AJAX request. That’s a low-level detail. Start from the high-level approach of “fetching data” and then immediately move to the next high-level step of “parsing data”. With this strategy, you cover the whole breadth of the solution before diving into any detail of the solution.

In other words, write modular code by using a breadth-first mindset. Everyone knows it’s a good idea to write several small functions rather than one giant function, so apply that approach to your communication too. When you explain how a computer works, you start the explanation at a high level (e.g., “hard drives store data, CPUs crunch data, …”) rather than starting at a low level (e.g., “the flow of electrons is controlled by gates known as transistors”).

Example - Breadth-First Coding
// Challenge (aka Prompt) - Write a function that determines the average number of
// retweets for a given user after a given cut off date.

// Phase 0 - Psuedocode (optional)
function getRetweetAverage(username, cutOffDate) {
   * 1. Fetch tweets via Twiter API
   * 2. Filter tweets based on date
   * 3. Calculate avg count of retweets from filtered data
   * 4. Return a promise that resolves to the answer

// Phase 1 - Coding with declarative helper functions
function getRetweetAverage(username, cutOffDate) {
  return fetchTweets(username).then(function(tweets) {
    var recentTweets = filterTweetsByDate(tweets, cutOffDate);
    return calculateAverageRetweets(recentTweets);

// Phase 2 - Implement low-level helper functions
function fetchTweets(username) {
  // Let's pretend we're using AngularJS's HTTP request service, which uses promises.
  var params = {
    screen_name: username,
    count: 200 // FYI this is the max allowed by Twitter's API
  return $http.get('', params);

function filterTweetsByDate(tweets, cutOffDate) {
  return tweets.filter(function(tweet) {
    // Convert tweet's String date into a JS Date object before comparing.
    var createdAt = new Date(tweet.created_at);
    return createdAt > cutOffDate;

function calculateAverageRetweets(tweets) {
  var totalRetweets = tweets.reduce(function(sum, tweet) {
    return sum + tweet.retweet_count;
  }, 0);
  return totalRetweets / tweets.length;

In the example above, you should write code one “phase” at a time. Starting with psuedocode is optional, but it might be a good idea to at least verbalize it if you don’t plan on writing it. Then write the code in a declarative style as seen in “Phase 1”. Lastly, flesh out the functionality of your solution by writing the code that actually makes things work.

By the way, I’ve never actually used the Twitter API, so the example code might not follow best practices or might not take into account how it actually behaves. For instance, maybe the API accepts a parameter to do the date filtering for you.

5. Refactoring Your First Draft

Once you’ve reached the point where the code seems to solve the challenge at hand, it’s time to refactor. If you’re writing under pressure in an interview situation, it’s likely that you haven’t written the cleanest code. If you’re writing without any pressure, it’s still good to refactor your first draft into a more readable/maintainable variant. Here’s a list of tips for deciding what to refactor:

  • Improve readability by fixing indentation, whitespace, names, etc.
    • Rename variables into semantic names. It’s tempting to use very short variable names during interviews because you feel pressure to finish quickly. Consider renaming them into more recognizable names to show your audience that you know how to write maintainable code that potential co-workers could easily read.
    • Replace loops with a map, filter, reduce, etc where possible.
    • Consider naming anonymous functions if they have potential to be re-used as a helper.
  • Extract code into helper functions. It’s very common for interview candidates to inadvertently write long functions. Even if you tried to follow Breadth-First Coding in Step 4, you may have slipped.
  • Double-check promises and look for opportunities to reduce boilerplate and anonymous functions.
    • Check return statements to ensure that your promises will resolve to the correct values (and that the segments of your promise chain will pass correct values).
    • Use promise library helpers such as all, spread, etc where possible.
  • Add error-handling/logging for professional bonus points.
  • Rewrite in another style (e.g., Functional Programming vs Object-Oriented Programming) for massive bonus points.

Admittedly, this Step 5 isn’t as directly related to communication as other steps. It’s mostly focused on improving your code. However, there is still a communiation-related opportunity here. As you are refactoring, verbalize your intentions. Discuss what you want to improve before you improve it. Explain the rationale behind the improvements. Mentions the pros and cons of your code without the improvements and with the improvements (i.e., before vs after).

6. Walking Through Your Answer

At this point, your code should be presentable. By following the previous steps, your audience should already have a solid, high-level understanding of your code. So now it’s time to give a detailed walkthrough.

Explain any nuances, use precise terminology, and expound on any interesting control flow or references (e.g., closures in JavaScript). You can also mention any implications regarding speed, memory, I/O, security, etc. But overall, your goal is to describe your code in detail.

7. Testing Your Answer

You might actually want to perform this step before step 6, but it depends on how you roll. After you’ve gotten to the point where you have a solution that seems to be good, take a minute to describe how you’d make sure it’s robust. When you normally write code on your own, you of course test it out by running it with various inputs or circumstances. Describe them; verbalize them.

For example, if you’re writing a function with some parameters, you’ll probably run the function with a bunch of different arguments with different values and maybe different datatypes.

  • Numbers: negative values, 0, 1, odd vs even, really big numbers, decimals
  • Strings: upper vs lower case, single character, numeric characters, punctuation and non-alphanumeric characters.
  • Object Literals: check for weird keys (much like Strings)
  • Collections & Data Structures: empty collections, only 1 item, several items, check for mutation side-effects, ascending order, descending order, random order, nested objects/arrays/other data structures.

Where Did These Steps Come From?

I came up with these 7 steps based on…

How to Help a Beginner Debug Code

- - posted in programming, teaching | Comments


When I teach JavaScript workshops, I usually have teaching assistants who can help students complete classwork exercises. The TAs mostly focus on helping beginners debug their code rather than just giving solutions and walking through them.

Here’s the advice that I give TAs:

Dear Teaching Assistant

Remember that you should avoid giving away direct solutions. When students ask for your help, they will often not know exactly what puzzles them. They will often just ask, “Can you help me?” rather than asking something more precise such as, “Why doesn’t this function return the value I expect?”

Your role is to understand the particular problem that the student is facing. Try to find out what precise questions should be asked and relay them to the student. This might require vocalizing your step-by-step thought process for solving the problem, and finding the first step that confuses the student.

When debugging, try to debug the student’s code one step at a time. Explain those steps so the student can learn how to debug (e.g., where to put console.logs, which variables need to be checked, etc).

Never give the hungry student a cooked fish. Teach the student how to use a fishing pole, a gutting knife, a cooking fire, and Chrome DevTools.

Do everything you can to show a student how to get the solution. Showing a student the actual solution is the last resort. At that point, you should not only show the student the solution, but walk through it and ask the student questions to test their understanding. Oftentimes, asking a student “do you understand?” is not effective. You will get nods thanks to a superficial level of a understanding. That understanding must be tested by asking the student to walk through the code verbally, asking the student values of specific variables, and so on.

The Myth of the AngularJS Armageddon

- - posted in AngularJS, JavaScript, technical posts | Comments

RIP? AngularJS

A few months ago, the JavaScript community had a rather negative reaction to an announcement about Angular v2.0. Quick aside: my boss lost faith in Google and jumped on the ReactJS bandwagon. On a recent episode of the Adventures in Angular podcast, the Angular core dev team tried to clear the air regarding the general approach for Angular 2.0 and the differences between Angular 1.3 and 2.0. The podcast is surprisingly well-done. There are 9 people included (1 of them is THE John Papa; 4 of them are Angular team members) and yet they never accidentally interrupt one another or talk over one another.

I’ve listed some interesting bits I gleaned:

Some Misunderstandings

  • It sounds like there might actually be a migration path for 1.3 to 2.0. There is no path yet because 2.0 isn’t close enough to completion to judge. The idea of “no migration path” was a misunderstanding.
  • It is not necessary to use AtScript for Angular 2.0 (and it is not necessary to use Angular 2.0 for AtScript).

Some Rationale

  • They’re trying to re-make their routing module in a way that will be easier to use.
  • Some things are disappearing for logical reasons:
    • $scope is disappearing because they realized “controller as” syntax is best, so they want to revamp that system completely to avoid common $scope confusion.
    • Code for directives will be totally different because Directive Definition Objects as they currently stand are ugly and kind of convoluted (e.g., most directives don’t need a linking function, they just need a controller function –kind of like how most views/templates should use controllerAs instead of $scope).
    • Angular’s module system will disappear because ECMAScript6 will have a native module system. By embracing the new ES6 system, it will make Angular 2.0 more compatible with future non-Angular modules (much like how all back-end JS embraces Node’s system).
  • There are a few key motivations behind Angular 2.0’s design:
    • Mobile friendliness.
    • Fixing mistakes they’ve made when creating Angular 1.x (e.g., getting rid of $scope).
    • Simplicity and performance.
    • Embracing future tech like ES6 and web components.

Some Points of Emphasis

  • The new syntax looks crazy, but the Angular team claims that it will be much harder to convert a non-Angular 1.3 app to 2.0 than to convert Angular 1.3 to 2.0 –which sounds like a no-brainer, but as you can imagine, they’re really trying to emphasize that you should not abandon 1.3 just because 2.0 looks so different now.
  • They emphasized how Angular 2.0 is still in a state of flux, so it’s too early to make business decisions based on it.
  • The Angular team claims they are making changes for practical reasons, not purely academic reasons. In other words, they have examined how current Angular apps are made, deployed, etc. They don’t just think about what would be cool, they do think about what would be truly helpful/useful.

My Takeaways

I know I sound like I’m defending the Angular team. To a certain extent, that’s true (I need to try some React.js one day to hopefully reduce my bias for Angular), but it really comes down to:

  • They’re converting to ES6, which means it will probably be necessary to use a transpiler to convert core Angular 2.0 code to ES5 for older browsers.
    • Ideally, this won’t be a huge problem for evergreen (self-updating) browsers. Maybe they will support key ES6 features by the time Angular 2.0 becomes “mainstream” (in the same sense that Angular 1.3 is currently “mainstream”). Or maybe I’m dreaming :p.
  • There were some huge misunderstandings when Angular 2.0 was announced (re: lack of migration path, role of AtScript, etc).
  • It’s too early to really tell what Angular 2.0 will look like when it’s released.
  • When Angular 2.0 does arrive, it may look syntactically different, but it will do many of the same, Angulary things (i.e., the Angular “flavor” of MVC, augmenting HTML markup, enabling powerful custom components, etc).

Newsflash! Angular 1.x is NOT Dead!

Angular 1.4 is coming in Spring 2015.

News of 1.4 landed after the podcast aired. It will bring the new router I mentioned earlier, a “first class” I18N system, slick-looking documentation (using Angular-Material), and other goodies –including some breaking changes. :D

How to Start and Continue Learning JavaScript and Web Development

- - posted in JavaScript, learn to code, links, web development | Comments

Teaching my JS Fundamentals workshop

Me teaching a JavaScript workshop for beginners

Last update on Nov 30, 2014 to add a great link to the “Compilations” section.

  1. A couple of weeks ago, a friend asked me for advice on giving advice to beginners.
  2. One week ago, I taught a class on JavaScript for beginners (or advanced beginners –as I like to say).
  3. A few days ago, I recently found a Quora question about getting better at JS.

These three moments have had my brain wondering about how to point coding newbies in the right direction. After some Googling and recalling my own past, I’ve gathered some links that will hopefully help beginners and maybe even intermediate folks. However, I should warn you that I haven’t tried out all the various services for myself.

The Basics

This Imgur post lists 6 sites that provide tutorials for getting started in coding. I’ve personally used Code School and Codecademy. They’re great, but after awhile, you’ll want to explore other options. They are not sufficient by themselves.


These sites gather tutorials and various resources into one place. Most of these also give some guidance or roadmap to help beginners prioritize what to learn:

The Fundamentals of JS

If you’re specifically trying to learn the quirks of JavaScript, then classes like the one I teach are perfect for you. If you’re not near San Francisco, you can try online classes taught by the one who helped me become a teacher (@BiancaGando).

But these aren’t free. Ya know what is free? This great gathering of words describing vital JS concepts: 16 JavaScript Concepts JavaScript Professionals Must Know Well

The Community

San Francisco is my neck of the woods. If you’re lucky enough to be around here, then you should take advantage of the stellar community. There are lots of free meetups/events that can help you learn. If you’re not in the area, check for groups that provide similar events.

  • Tinderbox: They often host “hack nights”, which might sound intimidating, but they’re very open-ended so you could show up and just ask for help learning a particular subject.
  • SF Rails: Much like Tinderbox, the SF Rails group hosts open-ended “protonight” events. The group might focus on Ruby on Rails, but you’re likely to find people who can help with any beginner or intermediate level coding topic.

If you’re female, you might want to search for organizations that provide free support for women. Some examples:

Back in the day, I used a free, online curriculum created by Railsbridge to learn some web dev skills.

A Hack Reactor alum recently launched a free service called Hackvard. It helps people quickly find nearby programmers who want to meet up. After a few weeks (or days?), it was renamed to Codaround. One of the co-founders contacted me and mentioned that Codaround might be changed to focus on helping match mentors/teachers with students/beginners. I don’t know any details, but it’s worth keeping an eye on this.


Want to play while you program? Here are some sites that turn learning to code into a game:

  • CheckIO: When I tried them out, I wasn’t impressed by their attempt to cover coding challenges in a layer of gamification. A CheckIO employee reached out to me and told me things have changed a lot. I haven’t verified his claims, but their user base was pretty large last time I checked, and their blog is very active, so they’re alive and kicking.
  • Code Combat: I played with this a couple months ago. It was fun, but a tad buggy. I like the idea of writing code to control your character.
  • Screeps: This looks quite promising. You write code to control small armies.

What else?

Let me know in the comments (or via Twitter) if you know of any other solid resources that help people learn JavaScript and other programming skills.

Web Security Fundamentals - Part 2: More Info on Modern Defense

- - posted in Express, JavaScript, Node.js, security, technical posts, web tech | Comments

Last updated: Sep 22nd, 2014 at 12:21PM PDT. I added some info about using CSP with AngularJS.

Last Thursday, I published a blog post in which I summarized the main attack techniques (XSS, CSRF, and MITM) used by baddies to screw with the web. That post also covered two header-based solutions available to help you defend your site: CSP and HSTS. To supplement all that info, I am providing a bunch of articles, references, videos, and tools to help you learn more and take advantage of CSP and HSTS.

Content Security Policy (CSP)

Browser Support

Cross-browser support for CSP is pretty good. The latest versions of IE require the CSP header to use a special prefix (much like vendor prefixes for certain CSS features). Older crap like IE9 and below have no CSP support.

AngularJS + CSP

Sadly, CSP reduces Angular’s performance because the framework does some optimizations that run afowl of CSP. I imagine that the performance loss shouldn’t be a problem unless you have a ton of Angular expressions on the page at once (e.g., you use ng-repeat to generate hundreds of expressions).

Despite these concerns, CSP is highly recommended by the AngularJS FAQ page. For more info on how to use CSP with AngularJS, check out the docs for the ngCSP directive.

Further Reading/References

Awesome Presentation on CSP

HTTP Strict Transport Security (HSTS)

Browser Support

Most browsers get a passing grade when it comes to HSTS support –except for…

Internet Explorer doesn’t support HSTS—which means that there’s basically no such thing as a secure website in IE

Further Reading/References

Quick Video Summary of MITM and HSTS

Note: The video above provides outdated browser support info. Updated info can be found here:

Bonus: Security Toolkit for Express Apps


Do you use Node.js? Does your Node.js app use Express? Want some middleware to help secure that app? Perhaps you should consider using Lusca, a free module created by Paypal to quickly add and configure various security features such as CSP and HSTS. I haven’t personally tried it yet, but I plan to do so soon. Their README file makes Lusca look very easy for devs to use.

You can pick and choose which security features you want to enable. For example, if you’re already using JSON Web Tokens, then you may not want to use Lusca’s CSRF method while you take advantage of Lusca’s legacy browser XSS protection.

By the way, don’t get confused: Paypal uses their own open-source, Express-based framework called KrakenJS, but Lusca works with Kraken apps and Express apps.

Presentation on Securing SPAs and Node.js Apps (by PayPal Engineer)

Web Security Fundamentals - Part 1: What Google Peeps Say

- - posted in JavaScript, security, technical posts, web tech | Comments

Back in late May, I went to one of the most informative tech meetups ever. The SFHTML5 meetup group organized an event at the Google SF office to cover web security. Google security researchers presented about 2.5 hours of lectures talking about common hacks/attacks, good defense, and the general state of web security.

You can check out the slides here: click here if you dare. You can watch the lectures here:

But if you don’t feel like sitting through 2.5 hours of lecture, allow me to summarize the best parts:

  1. Common hacks/exploits
    • XSS
    • CSRF
    • MITM
  2. Simple security best practices
    • Use frameworks/libraries to fight XSS for you
    • Implement CSP to protect your front end
    • Reinforce HTTPS with HSTS

I won’t go into detail about any particular topic. This blog post will simply get you started in understanding fundamental web security. I suggest you use Google to research more about hacks/attacks or wait for me to post another blog post that provides a collection of links to sweet videos, references, and articles that I found particularly helpful for learning more about all these topics.

Be Afraid

How are websites and web apps compromised? Why are sites often “hacked”? There are three main types of attacks that you should worry about: XSS, CSRF, and MITM.

Cross-Site Scripting (XSS)

When a punk manages to get your code to run their JavaScript, that’s XSS. A simple example is when an unprotected website just accepts text from the user and adds it to the site’s HTML code. If that text is actually JS, then the site ends up sending the browser user-generated code. Damn.

XSS is one of the most common problems plaguing web security today. This is pretty depressing because there are plenty of frameworks and libraries that help fight XSS, but so many site operators just don’t use them and some fools even try to write their own anti-XSS code.

Cross-Site Request Forgery (XSRF/CSRF)

Let’s say a user logs into your website or web app. They are now authenticated, right? Well it depends. It could be that the user’s browser is authenticated. An attacker could take advantage of this authentication and get the user’s browser to submit an HTTP request crafted with nefarious intentions. The request will be accepted because the browser has the right authentication cookie data, for example.

How is the evil HTTP request initiated? It could be through XSS, it could be through convincing a victim to visit a malicious site that sends HTTP requests, etc. Most examples mention authenticated cookies being used by attackers.

Man-in-the-Middle (MITM)

There’s a reason why public internet is unsafe. When you’re on a shared network, other users on the same network can try to intercept your data. Not only can man-in-the-middle attacks read your data, they can also send you bad data/code. Some attackers merely intercept web pages you’re accessing, add more advertisements, and feed you the web page with extra ads. Other attackers might intercept your attempt to visit, give you a fake Facebook login page, and convince you to submit your login info to them.

Obviously, protecting a network by requiring a password to connect can help. However, if you’re using public WiFi in a coffee shop where the password is given to anybody who asks for it, then you’re in trouble again. As I shall mention, HTTPS is crucial for fighting MITM pain.

Be Somewhat Less Afraid

It’s great if you’re aware of threats. Now it’s time to learn the basics on how to combat the threats. At the meetup, the Google peeps focused on three types of solutions: frameworks/libraries, CSP, and HTTPS with HSTS. I will also mention a couple other technologies (BONUS) for your consideration.

Frameworks/Libraries Features

One of the Google experts emphasized that XSS is a much bigger problem than it should be because there are so many frameworks and libraries that help fight XSS. He said that no one should be writing their own anti-XSS libraries. Instead, use one of the many open-source solutions. Also, it’s quite possible that you’re already using a framework that has anti-XSS features that just need to be activated or configured.

For example, in some templating libraries, a simple syntax change will enable anti-XSS escaping features. Other templating libraries automatically escape contents by default. Some frameworks like AngularJS do “round-trip escaping on all strings for you” to protect your app from XSS and other injection attacks.

Content Security Policy (CSP)

A server can instruct a browser to use a whitelist to decide which resources should be loaded and which should be blocked. This is done when a server adds a CSP to a response header.

For example, a CSP whitelist can tell a browser to trust script files from the server and Google CDNs, images from the server and Amazon CDNs, CSS files from the server, and web fonts from Google. Everything else will be blocked. In-line JavaScript will be blocked, in-line styles will be blocked, images hosted by 3rd parties will be blocked, Flash will be blocked, iframes will be blocked, etc.

Your CSP can be configured based on various types of resources. Check this CSP Cheatsheet for the list of options. I recommend that you investigate server-side libraries, frameworks, or middleware that can help you implement CSP. When writing your CSP, you can try starting with the most restrictive whitelist and then see what needs to be unblocked.

Reporting Feature

You can also set up a reporting system to find out what your CSP has managed to block (thereby identifying failed attacks).

A Googler suggested using the CSP reporting feature without an enforced whitelist to help you examine what browsers are actually digesting when they visit your site or app. For example, you could set up a CSP that has a whitelist and just asks browsers to report non-whitelisted sources without actually blocking them. This gives you the ability to tweak your whitelist based on production usage without changing production usage. After you’re done tweaking, change the CSP to force browsers to report and block uninvited resources and content.

Ultra-Strict Example CSP for Express server using Lusca middleware
  policy: {
    'default-src': 'none', // Block EVERYTHING
  reportOnly: true, // Record what's being blocked
  reportUri: '/report-violation-endpoint'

HTTPS and HTTP Strict Transport Security (HSTS)


To protect data transfers from MITM attacks, many sites connect to visitors via HTTPS. HTTPS connections not only protect typical payloads like JSON, but also static files and cookies that would otherwise be vulnerable to CSRF attacks. The hard part about using HTTPS is making sure no part of the site ever falls back to unencrypted HTTP.

For example, let’s say you’re browsing a site that provides free icons and graphics. Are all files served over HTTPS? HTML, CSS, and JavaScript files are no-brainers. What about images? Yeah that’s pretty standard too. But what about when you get an icon pack? You click a download link, and the browser starts downloading a zip file. Is that using the HTTPS protocol? It’s easy to make mistakes.


Furthermore, what if a user visits the site using HTTP first? It’s pretty common for people to type “” in the URL bar and the browser will turn that into “”. After they visit that URL, the site can redirect the visitor to “”. But sadly, that initial connection via http wasn’t secure. It’s susceptible to a MITM attack.

With HTTP Strict Transport Security, the browser can automatically turn “” into “”. HSTS works by setting a header that tells the browser to enforce HTTPS for requests sent to the domain (“”) for the next X number of seconds. Yes, you can set X to be a very large number such that HSTS is enforcing HTTPS for the next year, if you want to be cool like that.

Stay Tuned

This blog post was getting pretty lengthy, so I decided to split it into two parts. In a follow-up blog post, I will provide a list of references, tutorials, and videos to help you research more about CSP, HSTS, and some complementary tools/libraries.