I have generally avoided Node.js as I am almost exclusively embedded in ASP.NET web server technology. That said Node.js is also being used for developing desktop applications and for integrating tools that allow you to make constructing web sites simpler and more automated.
Ironically my initial exposure with Node.js and NPM came after installing the Windows Subsystem (WSL) for Linux which allowed me to do a command line install via Bash. But I am starting to see real benefits from having Node.js and NPM as part of my Windows development environment as an integral part of Visual Studio (and VS Code) development.
I will start looking documenting some of my favorite tools over the next few weeks, but for now let's do the install.
Installing Node.js and NPM
- Download the latest stable Windows installer (msi) from the Node web site.
- Follow the prompts in the installer (accept the agreement, click NEXT button with the default settings).
- Perform a Windows restart to complete the installation process.
The problem that immediately comes to mind with this type of distribution is trusting that the source your assets use remains uncompromised, because in all likelihood you do not own the CDNs upon which you rely. This is even more critical for financial institutions where security (over speed) is the premium concern. A much more complicated attack could, via DNS poisoning, trick a user into downloading content from a compromised server. Content owners would remain completely oblivious to an attack that injects content indirectly. And no, this type of attack would not be helped by hiding behind TLS.
What can we do?
In order to account for the scenarios I describe here the W3C have defined a validation scheme referred to as Subresource Integrity (SRI), this adds the integrity attribute to both the script and link HTML tags. Here is an example:
The integrity attribute is portmanteau of two values, “sha384”, which describes the hashing algorithm applied to the file (src), followed by the actual calculated hash “Li9vy3DqF…”. You would probably calculate and integrate these values during your build process. It is then up to each browser/user agent to verify those values during the asset retrieval process, and by matching the hashing algorithm applied each browser should be able to produce an identical hash. This provides statistically reliable way of guaranteeing that no changes have occurred in even the smallest way (remember a small change in the hash input radically changed the hash output).
So if the browser does not trust the source (hash does not match) it is not obligated to execute the response and an error is raised, during this error the developer can elect to do nothing or point to a trusted source (one they directly control). I think this is a powerful addition in our ever expanding security tool box.
Over the course of the last year I have been tasked with analyzing our production environments, specifically looking at performances issues, hangs and crash analysis using the Debug Diagnostic Tool, Performance Monitor and Debugging Tools for Windows (WinDbg).
WinDbg is an ancient and primordial tool of the Windows ecosystem, it is one of the oldest native debuggers I am aware of. Its age means that it really does not know, in a direct way, what the more modern .NET is or even does. In order for WinDbg to be able to give meaningful information about the .NET framework and how objects are collected and released we need to load a couple of extensions.
- Open WinDbg as an Administrator.
- Hit CTRL-D and navigate to your hang dump to load it into WinDbg.
- Load the .NET 4 managed (as appropriate) code extension and SOS extension with the following commands:
- .load psscor4
- .loadby sos clr
After loading these extension you now have access to commands that will allow you to analyze the hang dump. Here are the basic commands I tend to use for high memory, high CPU/hangs, and app crashes.
WinDbg - High memory scenarios
eeheap will shows information on the memory heaps used by GC. It will display a heap info for each logical processor, so if you have hyper threading on a dual core machine you would see four heaps.
What objects are consuming the memory, that have not been collected, first column output is the method table which is an index to the type of object.
!dumpheap –mt methodtable
Dumps out a list of all objects of that type (based on method table, first column output is the address.
A short cut for !dumpobj and shows properties of the specific objects including the objects value.
Converts the value into a readable output.
This command detects which objects reference this address. Useful for tracking down what might have a reference to stubborn objects.
WinDbg - Hangs and Performance Issues
This command shows CPU Usage percentages, be careful using this on multi use boxes, CPU is a function of the is CPU if this is not a dedicated box.
This extension display information about the time consumed by each thread. Very useful if you want to know if a specific thread is consuming way more time than other threads.
~* e !ClrStack
This command sequence is designed to show the .NET call stack for all threads
Tells us how many threads are waiting for a lock MonitorHeld. This can be important for threads that are blocked, it is important to remember that it only covers .NET locks.
Shows all the locks that have no conflicts.
WinDbg – Crash scenarios
Display exception information with the verbose switch gives as much information as possible.
Dumps all the available exceptions.
A few other useful WinDbg commands
~ 13 s
Set the current context to the thread id of 13.
Show the .NET stack for current thread context
Dumps the HttpContexts found on thread and lists the URI in various states of request and response.
Gives a list of objects stored in your web cache
Having the tools and commands is one thing, understanding context is a whole other question, if you need help with that I would strongly recommend visiting the blog of Tess Fernandez. A few years back she produced a legendary series of detailed hang analysis articles that remain wholly relevant today.
Every few years a developer, usually a really talented one, will makes a reductive and exclusionary statement that amounts to "You are not a real developer if you do not know (or do) this…". This statement is usually followed by declarations that the layer of abstraction a set of productive developers have invested in is simply not appropriate for a professional programmer. Here are some of the more notable examples I have encountered:
C# has always honored querying an object where you simply ask if it matches a particular class or interface, as in the following:
if (obj is SomeObject)
Unfortunately this was just about the limitation of the is statement, however, C# 7 has introduced the idea of pattern matching and is using the is construct, especially with case statements, as the cornerstone for a new type of development.
In the following example it will take the object parameter and check if it is an integer and will convert yourobj into the integer variable val. In this situation there is mercifully no need to use the awkward TryParse() method:
static void Convert(object yourobject)
if (yourobject is int val)
val = val + 20;
Pattern matching in switch statements
How long have switch statements been passé? Or is just really big switch statements that developers really frown at? Let's use this update as reset on our collective relationship with the switch.
So the first thing to state emphatically is that you can now switch on any object! You are no longer limited to primitive types, in fact each case statement can be filtered based on the pattern method, here are few examples we can look at:
static void Convert(object yourobj)
case Captcha c when c.Success == false && c.Count > 0:
c.Success = true;
case Captcha c:
c.Success = false;
throw new ArgumentException();
throw new ArgumentException(nameof(yourobj));
Things to note in above example:-
- We are using pattern matching to convert the object to variable c, the variable c only exists in the scope of the case statement (which is why I can define c twice).
- The first case clause has a when condition to directly access and evaluate the properties of the object. In this case I created a Boolean expression to look at Success and Count properties and determine if I want to subsequently update other properties.
- If the expression on the first case fails I go on to a later more permissive case that sets all other Captcha objects Success property to a value of false.
- I still get to use default catch all case as you would with a switch on a primitive type.
I find these ideas really promising, and I imagine this is just the beginning of pattern matching.
It took me a while to find a pristine copy of the the Surface Studio desktop owl image, and I must say I think it is gorgeous! Anyway I thought I would make it available for easy download here.
If C# is versatile it is partly because it housed in an integrated development environment (IDE) that supports it, and if maintaining both the beauty, consistency and accessibility of a language like C# requires expert stewardship, then designing and maintaining a productive UX to support that may actually be an order of magnitude harder.
Visual Studio has long been the IDE of the enterprise, but in recent years it is abundantly clear that Microsoft is actively going after solo developers, students, startups and the open source community. At first the strategy just seemed to resolve to make as many low hanging services free or as close to free as possible. Immediately following that approach we saw the introduction of Visual Studio Code as light weight IDE free of historical UX constraints, a light weight app for both Windows and Mac audiences.