Anyone who writes software should be concerned about its security. The term “security”, in the context of software, can mean a lot of different things to different people. Software can be secure, in the sense that it exudes confidence because its knows that its developers deeply care about it and love to improve it (which is very important, in order for software to be functional). However, right now, I am going to discuss secure software in the sense that (1) it cannot be made to act in ways we did not intended and (2) it does not allow its proprietary and private information to be intercepted by people or software that are not authorized to access that information.
In LabVIEW, when we build an executable application, there are a lot of security issues. For example, while working on VI Package Manager, we (JKI) employed several mechanisms to address LabVIEW security issues. One significant security limitation of LabVIEW, is that the subVI call boundary is inherently not secure. At run-time, LabVIEW dynamically links parent VIs (callers) to subVIs (callees). It is therefore possible (and, yes it’s been done) to fool a VI in a built application into calling a different subVI than was specified at build time. VIs can be inserted into the hierarchy of a LabVIEW application in order to intercept and modify data — we call these intruders “mole VIs”. I’m not going to explain the process of creating and inserting mole VIs, but I will tell you (only) a couple of the things that we’ve done to thwart the problem.
One technique that we used, is in-lining of subVIs. This is basically the inverse operation of Create SubVI from Selection, except that you merge a subVI into its caller’s block diagram (often recursively). We were working on a way to do this, using scripting (and had it nearly working), when we discovered a native scripting function that does it for us. Ironically, we noticed that someone on LAVA discovered this, too, just about a week after we did — small world! Of course, we were trying to solve two different problems (our issue was security and their issue was execution optimization) but is was interesting, nonetheless.
Another technique that we used is obfuscation (garbling) of VI names inside the executable, so that VIs’ real/descriptive names cannot be seen — for example a VI named “Is Password Valid.vi” might be renamed to something like “0BFE026AEEB3CF0FDDA37505B49D846C”. In VIPM, we achieve this by doing a programmatic renaming of all the VIs, during the build process. Now, this doesn’t really prevent someone from inserting a mole into your application hierarchy, but it makes it a lot harder to figure out what’s going on in your application.
Finally, I should note that both of the aforementioned techniques are executed programmatically during the build process. We use OpenG Builder to build VIPM and we have over a dozen separate build steps and also execute several call-backs that operate on VIs as they are copied from the source location to the build output location. Honestly, I couldn’t imagine creating a commercial software product, written in LabVIEW, that was not built using OpenG Builder. In future articles, I’ll describe more of the cool ways that we use OpenG Builder to overcome software engineering challenges.
In closing, I should also mention that insecure software is also a very serious problem — please, show your software some love and make sure that it is secure
Want to discuss this article? Please post to the LAVA discussion forum thread, here.