Are you concerned about having your Firefox Extension JavaScript code compromised? XPI files can be extracted and code can be easily viewed. One solution that works very well for many organizations that wish to keep their JavaScript code secret is to use a JavaScript obfuscator.
Also known as a script compiler or script compressor, an obfuscator takes human-readable JavaScript code and converts it into text that is virtually impossible for humans to process. When you're ready to deploy your product live, your developers can "obfuscate" a version of the code for distribution and maintain the original human-readable version for continued maintenance and development.
In addition to making it difficult to reverse-engineer, compressed JavaScript files are generally 40% to 60% smaller than their aesthetically pleasing human-readable counterparts, as a result of comment, whitespace, and line break removal.
http://www.javascript-source.com/
Please see the above link for a quick example of the difference between a human-readable JavaScript function and an obfucscated function. I wouldn't recommend purchasing this version though as there are open source versions out there that will accomplish the same goal.
http://javascriptcompressor.com/
This version is Dean Edward's Packer. The problem with this is that the website has a decoder. This kind of defeats the purpose of obfuscation, and I would recommend it only for compression and not obfuscation.
These tools appear to be a great way to keep proprietary JavaScript code from falling into the wrong hands. Obfuscation is not prefect or foolproof, but consider this question: Is a thief more likely to snoop around in a car with unlocked doors or one that is securely locked?
Here are some links to free or open source obfuscators. All three work from the command line:
- YUI Compressor
- ObfuscateJS JavaScript Obfuscator
- JSO (JavaScript Obfuscator)
Saturday, May 10, 2008
Open Source JavaScript Compressor
Saturday, April 5, 2008
Model View Squared Controller
At my place of work, Model View Controller is a common architectural pattern used as the foundation for the applications that we develop and maintain. MVC is a common pattern that can be seen in just about any software industry, from Agile development shops to those that follow the more traditional models of development.
As Computer Scientists, we often look for ways to solve a problem not once, but for N cases. Some really smart people at the Apache Foundation and SpringSource have designed and implemented solutions for Java that lay the foundation or "framework" for quickly and efficiently starting the development of an MVC application.
MVC Framework Flow
With both Struts and Spring, a request is sent from a browser to a servlet container, such as Tomcat or Jetty. The container hands off the request to a servlet declared in an XML configuration file. The servlet processes the request and hands it off to a controller. The controller, typically an Action subclass in Struts or a Controller subclass in Spring, makes calls to the model to retrieve data from the data source, manipulate that data, and pass it back to the controller. Afterwards, the result is forwarded to the view. In Struts, an ActionForward is returned by calling the mapping.findForward method and passing in a String that maps to a JSP page declared in the configuration file. In Spring, a ModelAndView object is instantiated with the JSP filename as an argument.
Advantages and Disadvantages
This particular pattern is well-known for decoupling the business logic from the user interface, the user interface from the controller, and the controller from the business logic. The advantage is that the view can be modified, maintained, or completely replaced, independent of the rest of the system.
Well, almost....
If you want to change the view, it's still a development issue. You still have to deploy a new Web Application Archive, or WAR file for short. You still have to test the application, as other developmental changes could affect the behavior of the system.
Unless you break the application up into completely separate modules that all exist outside the application....
Velocity, a templating language developed by the Apache Foundation, is very similar to Java Server Pages (JSP), except the Velocity files can be hosted outside the WAR file, on a completely different server, completely independent of the application.
The Velocity Advantage
Picture an enterprise-level reporting tool designed to be hosted by an application service provider. Imagine that there are thousands of clients who use this system and who regularly depend on the functionality. If you're a project manager for this reporting tool and you want to allow all of your clients to customize and skin the user interface without needing to involve your developers, then you need the Velocity Advantage!
The JSP Disadvantages
Even with MVC, you may have a few JSP pages that create a tightly coupled system where a change to the HTML structure for one client will affect thousands, perhaps with disastrous results. While the number of pages is small, it may take a lot of work to make them all work together for each logical case.
On the other hand, you could have N JSP pages for N clients. This means that deploying a new feature means that you will need to modify N JSP pages.
No matter what solution you use, the fact remains that updating the user interface becomes a development issue that involves a complete development, testing, and deployment cycle, as well as the possibility of either introducing new bugs into the system or creating a situation where you require intense, time-consuming CVS management. Being organized takes time.
But using Velocity, these JSP page equivalents could be stored on the client's servers, or an external server that you maintain that is specifically dedicated to hosting these view components. Suppose you then have a configuration file where you can store the location of the view for each client, kind of like struts-config but better; it exists outside the WAR file! And suppose the client has control over which view they use!
Sure, with Struts and Spring, the configuration exists in an XML file outside of the codebase, but you still have to pack a new WAR file and possibly restart your servlet container when making changes to these files. This, of course, equates to downtime!
Here is where those smart people at the Apache Foundation failed to completely solve this problem. (For the record, the developers of Struts are extremely bright problem solvers who have made significant contributions to the development community. These contributions have reduced the cost of development significantly in many J2EE environments, and without them, I would probably still be sorting through a mess of code trying to figure out how to write a controller! Additionally, I've not seen a container/framework yet that solves this problem in the manner that I propose.) What's the point of externalizing all of my configuration if changing it still requires me to disrupt my production systems? Any changes made to web.xml, server.xml, struts-config.xml, tiles-defs.xml, or any other configuration file requires a servlet container restart, in most cases.
And this is exactly the type of problem that would make the above scenario fail with a framework such as Struts, or Spring, or WebWork, or Struts 2.
Model View Squared Controller
The framework can of course still be used, just not with the struts-config.XML file. To allow clients to modify their HTML or CSS or change the view that they see, they have to be able to access your own customized, instantly reloadable configuration schema, not the framework schema. You can use an XML file on your server or even a database, as long as changes to the data are instantly recognizable.
This is the type of framework that I want to develop. I'll call it Model View Squared Controller. It's too long though. I need a better name. The concept is that your view would consist of a single JSP page, but all it would do is output data from a bean or even the HttpServletRequest object. The bean would be populated in the controller with the view template retrieved from outside the application. The view would be created as a Velocity object, processed in the controller, and then forwarded to the JSP page.
Essentially, there are two "views"; one is part of the application and the other plugs into this view. The JSP page within the WAR file does nothing except render the data, while the other view -- the plugged-in view -- is actually retrieved from a remote data source and assembled in the controller. It's almost as if your view becomes a piece of data. It actually is data!
It's a tough concept to ponder. "My view is data, you say? I thought the model was the data?". Well, it is. But the view just happens to be something that we retrieve from an external data source, whether it be a remote server as a file, or as a template stored in a database.
Forms can be data. I don't mean the data that is entered in the forms, I mean the forms themselves! In your reporting tool, clients want to be able to use different forms with different field names and values. If your developers are smart, they can design a database schema that is abstract and extensible, one where field names aren't column names, but pieces of data themselves.
Fitness Tracker
This is also the answer to my Senior Design project! I designed a system for allowing health club owners to add exercises to the system so that their members could record data for each exercise.
Since each exercise is different, there are different data fields for each type of exercise. These things can't be hard-coded because they are data. Not data that the member would see, but data that the client, the club owner or manager would see! Once again, the form fields are data!
Same with the reporting tool! Each client will have their own idea of what data they want their employees or customers to be able to enter. Therefore, you absolutely must solve the problem once and only once! Otherwise, you'll be scrambling to reinvent the wheel for each new customer that knocks on the door.
I'm going to continue to write more on this subject, as I feel that the concept of a model generated view, view view, or whatever I decide to call it, is oftentimes overlooked.
Wednesday, March 19, 2008
Technical Customer Service
Quoted from Joel On Software - Some interesting jobs:
"My pet theory is that if the person who takes the call when a customer is missing, say, the Pear Mail module, if this person is the same person who maintains the setup code, then they will eventually get sick of sshing into customers' servers and typing "pear install Mail" for them and they'll just fix it in the setup code once and for all. And I think a lot of people would find a job that combines problem solving with new software development is going to be pretty interesting,..." - Joel Spolsky
I agree 100% with Joel's theory on having the software developers also be the customer service department. I don't deal directly with external clients, but I do have to fix problems when things break. As a result, I like to fix them the first time so that I don't have to deal with it again.
It's a beautiful feeling when you can solve a problem the first time for N cases where N -> INFINITY!
As long as the business model empowers software developers to actually implement these solutions, this organizational style will be successful. I feel that I have this level of freedom at my company, and I'm fairly certain that this level of freedom exists at Fog Creek.
Thursday, March 13, 2008
Multiple HTML Reply Signatures for Google Apps
Gmail HTML Reply Signatures Greasemonkey Script
The company I work for uses Gmail for email communications. Specifically, the service the company uses is part of the Google Apps bundle of services, and it's the same service that I use for my blog email.
As many of you may know, custom signatures through Gmail can't contain HTML by default. However, HTML Multiple Reply Signatures for Gmail solves this by using the Greasemonkey engine to inject HTML into the page. The HTML Multiple Reply Signatures Script (and Firefox Extension) injects a drop down list to the left of the Gmail editor where a user can select from up to four customized HTML signatures, which will be injected into the Gmail editor.
History of Gmail HTML Multiple Reply Signatures
About a year ago, I integrated the HTML Reply Signatures script into our company's global Windows profile. Since the global profile was shared across most of the company workstations, I created a DOS batch script that took the user's Windows login details from a workstation PC and generated the Greasemonkey script using this information. The generated script on each workstation is exactly the same, except for the filename of the signature image to use. The constraint is that all of the images must use a standard naming convention and all be located on the same public server.
Reliable Gmail HTML Signatures Solution
This solution has worked out quite well. It has been very stable and reliable in the last year and has required absolutely zero maintenance. Now that we have a need for certain people to have more than one signature card, I suggested that one of our managers install the HTML Multiple Reply Signatures Greasemonkey script. So far, he's pretty satisfied with it.
Not being on the global profile made this much easier; otherwise, I would need to write a new batch script that generates the HTML Multiple Reply signatures script instead of the HTML Reply Signatures script, which can only handle injecting one signature. In addition, not being on the global profile means that he could essentially name the image files whatever he wants, as long as he modifies the signature HTML in the script to point to the correct filenames.
I recommended the script instead of the Firefox Extension for three reasons:
- The script is actually more reliable and bug-free than the Firefox Extension.
- This particular manager is technically adept and fully capable of modifying the script himself to configure new signatures.
- Google Apps Gmail is not using Gmail's New Interface, so it has not been susceptible to the same bugs that standard Gmail users have faced.
New version of Gmail
Once Gmail moves these customers to the new version, we're likely to see problems. I wonder why they haven't done this yet. The bigger question is, with my organization's growing use of this particular tool, should we prepare for the change by using a plug-in that supports the new interface?
At any rate, it was cool to see the script being used in my own organization! It may be a good idea to seriously consider moving the script to Gmail's Greasemonkey API to support the new interface.
Wednesday, March 5, 2008
500 Gigabytes of Relief
Backup Humor
I just bought a Seagate OneTouch 4 Maxtor 500GB external hard drive. The hard drive is marketed for backup purposes and comes with the backup software installed on the hard drive. Below is a note included in the instructions for step 2:
Note: It is highly recommended that you copy the current contents of the OneTouch 4 to your computer before proceeding. Reference Seagate Knowledge Base article 4169 for more information.
It doesn't inspire confidence to know that I have to backup the software on the backup drive in case something goes horribly wrong. If the unthinkable does happen, the backup software is the least of my worries. I'm not too concerned. The really important things will be backed up on a CD or a DVD.
Solution to my Problems
Having this hard drive will solve a big problem that I have. Lack of space. With two Linux installations, Windows XP, and several Virtual PC images, my 160GB internal hard drive has reached capacity.
This has led to many other problems that all stem from lack of space. I want to try more distributions of Linux, but I have so much data spread out on different partitions that I was afraid I might lose something important if I tried to install the latest version of Ubuntu or SUSE. Now I am free to proceed with an upgrade.
I also wanted to be able to convert my Virtual PC images to VMWare as part of the Microsoft Quit Date. This has not been going as well as I've planned, but it hasn't been going bad.
I am using the Mozilla Thunderbird Extension Lightning for my Calendar application; however, I'm still using MS Outlook for email. If I can get a solid Linux distribution running then this will help reduce my dependence. At the moment, Pandora is the only music that I have in Linux. I had MP3 support briefly, but for some reason G-Streamer is complaining about missing something.
Don't get me wrong, I like troubleshooting broken software, but not my music player. I just want that to work. I don't care why it broke, or why Novell didn't include it by default, after fixing it once and having it break, I am at a point where I just want to hear music without having to read a bunch of knowledge base articles.
However, overlooking media player issues, there are a ton of advantages to using Linux. As a programmer, it is 10 times easier to get things done. Web programming isn't the same when loading a local file in the browser. You're not using http when you do this, you're using the file protocol. AJAX, as well as other techniques, behave completely different under this scheme. To get an accurate idea of what a JavaScript library or technique will do when served on a web server, you need a development platform that mirrors this environment. In Linux, I can configure Apache, PHP, even Java's Tomcat servlet container, in under 30 minutes. In Windows, I'm not as confident.
I can also use tools like grep, vi, and locate in Linux. In Windows, I am lost without these. The cute puppy that appears in Windows Search is cool and all, but I don't have all day to search for a string in a file in the file system, I just want results. Grep gives almost instant results. Sure, there's no puppy, as my 7 year old nephew would say, but it's fast.
Little by little, I have been moving data to the hard drive. In the next couple weeks, I hope to have SUSE 10.3 installed on a partition. I might also install Ubuntu. We'll see what happens.
Oh, and in case something happens to the hard drive, don't worry! I've backed up the backup software on my computer. Now you can sleep at night.
Saturday, January 12, 2008
Data Loss Prevention Tips
Oops!
That's the sound of the second most common type of data loss! We've all done it at one point or another. No matter what industry you are in, whether it be software development, information technology, automotive repair, or homemaking, you've most likely experienced some form of data loss caused by some form of human error.
According to several resources, this type of data loss accounts for 32% of all data losses and trails behind hardware failures, which account for 44% of all instances of data loss. (I'm not going to bother to cite my sources; just simply search for data loss statistics and you'll see numbers very close to these.)
The sad thing is, data loss can be prevented. In fact, many people have made a lot of money developing backup solutions to help protect consumers and industries in the event that a data loss does occur.
But I'm not promoting backup software. Yes, backup software is important, but I think that there are other factors that are important to consider. I've come up with a list of suggestions which can be utilized to help protect you from data loss. I work in software development, so many of these suggestions will apply to my field. However, the concept is the same. Set yourself up for success, and protect you from yourself!
Data Loss Prevention Tips
SQL Statements
SQL is not designed for human consumption. In fact, the Linux command line is more user friendly than SQL. Most of the tools that we use on computers are designed with functionality to help protect us from ourselves, but not SQL.
SQL, or Structured Query Language, is a syntax used by developers and database administrators to modify the structure and data contained within a database. While SELECT statements are relatively harmless, most other types of statements can be extremely hazardous to the health of your data.
Consider this statement that may be used to update a balance in a bank account table:
update accounts.checking set balance='100.00' where accountnumber='12345678';The above statement will change the balance in account 123456789 to $100.00. Let's assume that there are 1,000,000 accounts in this table. With this statement, we updated a single customer's account.
Next, consider the following statement:
update accounts.checking set balance='100.00';The above statement is missing a very important piece. Without a where clause, the entire list of account balances is changed to $100.00! This is a major, catastrophic error!
No single customer has the same banking habits or account balances as another customer. Some people are constantly overdrawn while others have savings in excess of thousands of dollars. Some have balances that remain fairly constant while those with debit cards tend to have more dynamic account balances. Not only is a restore going to be necessary, but it must be coordinated with the fact that banks are a 24 hour a day 7 day per week business, and the restore will need to account for these changes as well.
In my experience, the single most common cause of these types of SQL errors is that the query is executed before its author finished writing it. A colleague of mine offers a very brilliant suggestion: Purposely embed a syntax error into your query until you are sure that all of the components are in place:
pdate accounts.checking set balance='100.00';The above statement -- when executed -- will throw a syntax error. Syntax errors are good. They let the user know that some required component is missing in order to complete an operation. When a syntax error occurs, nothing happens! This occurs with a majority of tools and software that's currently in use, but not with SQL. With SQL, a developer or DBA has an executable statement at a very critical point in the process of writing the statement. I've never written an update SQL statement that didn't involve a where clause. They just aren't very common, but for a brief second when writing an update statement we have a fully executable statement capable of wreaking havoc.
If I were to redesign the SQL language, I would put the where clause first. It's perhaps the single most important piece of the statement, and if it's written first, accidents should happen much less. Here is my version of SQL:
update where accountnumber='12345678' set balance='100.00';In my example above, if I execute before finishing the query, nothing happens! But the bottom line is that SQL isn't going to change anytime soon. There are people out there right now that are probably laughing at the fact that I've even considered rewriting SQL. "Just be careful", they'll say! "Just don't screw it up". Well, yeah! But sometimes things aren't that simple. Some people are built differently, and for some of us who are accident prone, we have learned techniques to adapt.
This is why I followed my colleagues advice and purposely write syntax errors into the beginning of my SQL statements. That SQL statement can't be executed until I'm ready to execute it and have thoroughly examined it. I keep all of my SQL update and insert statements saved in this format. Only SQL statements that I want to run will be executed. Yes, I am still very careful, but I also rely on this safety mechanism, just in case.
Software Development and IT
We run a three-tier development system at work. Each application has its own development, staging, and live server. The development and staging servers are connected to a staging database that mirrors the live environment, and the live server is of course connected to the live database.
In any IT-related industry, the live server is the bread and butter. If something happens to it, expect to see a negative sign followed be several zeros on the balance sheet. The staging database isn't important. Sure, it can be corrupted. If something bad does happen to it, your friendly IT department probably won't be inviting you out to lunch for a few days because they'll have to add "restore Staging database" to their to-do list, but to external customers and the bottom line, it just doesn't matter.
The staging environment is a developer's sandbox to do whatever he or she pleases. When I'm working in a development environment, that part of my brain that gets real paranoid and makes me do crazy things (like write syntax errors into my SQL statements) shuts down. There's really nothing to break. Play, have fun, and if something breaks, find out why and move on.
However, this is an area where human error can occur. In small companies, developers sometimes configure their own development environments. In my case, I configured my environment to use the staging database. I set all of my environment variables to reflect development mode.
Analogy
Have you ever walked out of a store into a packed parking lot, approached what you thought was your car with the key and tried to unlock the door? Dodge Caravans are good examples. They're everywhere, and they all look exactly the same. Here are some factors that differentiate them: Color, tires, hub caps, interior, window tinting, and many more.Now, if you made the mistake of approaching the wrong minivan, you wouldn't walk up to a blue minivan if you owned a red one. That's easy to identify the difference. But another red minivan, with the same hub caps, the same window tinting... well, maybe this is enough to fool you.
However, no matter how close the other minivan is in comparison to yours, the bottom line is it's NOT yours, and the key just won't fit.
This analogy can be applied to configurations as well. IP addresses all look alike. They're numbers. They're red minivans with window tinting. Hostnames are different. Now you have a blue minivan and a red one.
Other criteria that can be used to help an individual quickly spot a configuration problem are passwords. Don't use the same passwords for your staging and live environments. You shouldn't anyway for security, but someone who tries password A on server B when they meant to login to server A is going to realize their mistake before any damage can be done. The IT specialist who looks at the development server configuration for the new developer and sees an obfuscated password instead of the hello world password that is used on the other development servers is going to realize something is amiss and correct the problem before the new mad scientist developer conducts science experiments on the live server.
It's like documenting code. The easiest way to document source code is to use variable names that convey information to other humans about what the code does. This way, you kill two birds with one stone by telling not only the compiler, but also people.
Example 1:
//Send the account balance to the user via email
s.s(a,u);
Example 2:
CustomerEmailManager.sendAccountBalanceToUserViaEmail(accountNumber,userId);
Documenting code in this manner works extremely well, and if it works here, it should work in other areas as well.
Read-only
A read only file can still be deleted, but if you mark it as "read only", perhaps it will make you think before going through with actually deleting the file!
These suggestions are no different than things like setting that bill that has to be paid next to your car keys so that you won't leave the house without it. The only difference is that these suggestions are for situations that are way more technical.
Saturday, December 8, 2007
Corporate Intranet Blogging
One of my coworkers recently came up with what I thought was a really good idea. He suggested that the company allocate time for us to blog. From a marketing standpoint, this could be good public relations in terms of finding both customers and employees, but from a business standpoint, there is a danger of compromising corporate intellectual property.
A lot of other companies have been successful with this idea, but our management is against the idea because of the fact that company secrets could inadvertently find their way into the hands of a competitor.
Therefore, my solution is corporate intranet blogging. We take the idea and we push forward with it, but only internally. This won't buy us any PR points, but it will provide everyone in the company with a platform where they can keep everyone up to date on any cool technologies, advice, bugs, or projects that they've worked on.
This would be a great extension of documentation. If I spend a few days fixing a nasty bug that I think someone else in the company may encounter, the fix will be documented in my intranet blog. If I know that coworker A has really good suggestions for user interface design, I can periodically review the blog for new advice. Sure, this may not be necessary when everyone works in the same office during the same hours, but suppose most employees work in another office? This is a great way to find out what everyone is working on without having to necessarily ask.
