Lazycoder

3Mar/080

Modern JavaScript Development: null and undefined

In my last post on constructors and objects in JavaScript, I mentioned that the logical OR operator || was short-circuited and allowed us to set default values for arguments passed into the constructor. So we know that the argument evaluates to false if we don't pass it in to the constructor, but what value does the argument have that makes it evaluate to false?

There are three different values, or types, that a variable can have in JavaScript, null, undefined, and the value you set.

CODE:
  1. var isNull = null; //null type
  2. var isUndefined; //undefined
  3. var isNumber = 1; //neither null nor undefined, contains a value

A variable is null if you explicitly set it to the null value or if it receives a value from an expression that results in null; A variable is undefined if you declare it and haven't assigned a value to it yet. The tricky part about null and undefined is that they are equal, but are two separate types. Consider the following code.

CODE:
  1. var isNull = null;
  2. var isUndefined;
  3. alert(isNull == isUndefined);

So how do we differentiate between null and undefined variables? By using either the typeof function or the identity(===) operator. The identity operator has an evil twin (!==) that returns true if the object is not of the type you passed. The typeof function is defined in the JavaScript global object and returns a string containing the name of the type of object passed to it. The identity operator is a binary operator that compares the types of the two objects being compared and returns a boolean.

CODE:
  1. var isNull = null;
  2. var isUndefined;
  3. alert(isNull == isUndefined);
  4. alert(isNull === isUndefined);

n.b. If you pass "null" as an argument to a function, typeof will return "Object", but the object will === null.

CODE:
  1. function defaultArgs(name, options) {
  2.         alert(typeof(name));
  3.                 alert(name === null);
  4.                 alert(name === undefined);
  5.         this.name = name || "unknown";
  6.         this.options = options || { size: 42 };
  7.         };
  8.         var instanceOne = new defaultArgs("Scott");
  9.         var instanceTwo = new defaultArgs();
  10.             var instanceThree = new defaultArgs(null, {size : 43 });

So, how does this affect the logical OR operator? Well, both null and undefined are evaluated to "false" by the || operator, but the argument is still declared in the scope of the function and you can assign a default value to it. It's important to know the distinction between null and undefined. A function call may result in a null return value, a failed function call may result in an undefined value.

26Feb/081

Modern Javascript Development: constructors and objects

JavaScript doesn't have a "class" keyword or any formal class construct. Instead, functions are 1st class objects. When you write a function, you are essentially writing a constructor for a new object.
Here we are defining a object constructor called "newClass" and assigning some member values.

CODE:
  1. function newClass() {
  2.     this.name = "newClass";
  3.     this.options = {size:42};
  4. };
  5.  
  6. var myInstance = new newClass();
  7. alert(myInstance.name);
  8. alert(myInstance.options.size);

You can also specify arguments for the constructor just like any other function and assign the argument values to the objects members.

CODE:
  1. function newClassInitialzed(name, options) {
  2.     this.name = name;
  3.     this.options = options;
  4. };
  5. var anotherInstance = new newClassInitialzed("John", {size:42})
  6. alert(anotherInstance.name);
  7. alert(anotherInstance.options.size);

So what happens if you don't want to pass the name and options to the constructor every time? You can specify defaults for the member variables values using the logical OR ( || ) operator in JavaScript. The logical OR operator has a short-circuit which always returns "true" if the first argument is true.

CODE:
  1. function defaultArgValues(name, options){
  2.     this.name = name || "unknown";
  3.     this.options = options || {size:42};
  4. };
  5. var defaultArgsInstance = new defaultArgValues();
  6. alert(defaultArgsInstance.name);
  7. alert(defaultArgsInstance.options.size);

Since functions are first class objects, we can pass them as arguments in our constructors as well.

10Dec/079

Using the ASP.NET MVC framework with Visual Web Developer Express

If you try to use the new ASP.NET MVC framework with Visual Web Developer Express, there are some manual steps you have to take in order to get up and running.

Select "New Web Site" and pick "ASP.NET 3.5 Extensions Web Site".

The example web.config I saw added the following lines in the "system.web"/"pages" section. But I'm not sure if they are necessary. I just added them as a cargo cult programming convention at this point.

CODE:
  1. <namespaces>
  2.                 <add namespace="System.Web.Mvc"/>
  3.                 <add namespace="System.Linq"/>
  4.             </namespaces>

edit to add: The namespaces element defines a set of namespaces to be imported in every page and serves the same function as the @Import attribute on an aspx page.

You have to create your "Models" and "Controllers" folder in the "App_Code" folder.

You have to manually add global.asax to the site and manually add the default routes. Add this to the "Application_Start" method.

CODE:
  1. // Note: Change Url= to Url="[controller].mvc/[action]/[id]" to enable
  2.             //       automatic support on IIS6
  3.  
  4.             RouteTable.Routes.Add(new Route {
  5.                 Url = "[controller]/[action]/[id]",
  6.                 Defaults = new { action = "Index", id = (string)null },
  7.                 RouteHandler = typeof(MvcRouteHandler)
  8.             });

When adding a new view, make sure it inherits from "ViewPage" not "System.Web.UI.Page"

Remove any content from Default.aspx in the root of the site. It's just a placeholder to route IIS to the MVC framework.

Add the "using System.Web.Mvc;" line to any MVC page (e.g. Controllers, Views, Model, etc...)

Otherwise the standard MVC framework rules apply.

Phil Haacked will correct me if I missed anything, but following those directions I was able to bring up my default "Index" view and display some text.

Tagged as: 9 Comments
10Oct/070

More on querystring security

Ok, so the last post had some good responses. In that post I mainly looked at it the risk in putting params in the querystring from an application architecture point of view. But I threw in one sentence that a lot of people overlooked, including me because I thought it was obvious.

The W3C mentions not including sensitive data in the querystring or URL.

(emphasis added)

So lets look at another example.

http://ssl.gov/view/224444333

Look really closely at the URL. What do you see? A social security number. Now, look at the protocol. It's not using SSL. So what happens to that URL when it gets passed around through routers and proxies between you and the server? It gets cached and stored and logged. So now, that SSN is available to anyone who has access to those routers and proxies. Either black hat or white hat.

"Yeah, so you make sure you use SSL when you are dealing with sensitive data anyway so it's not that big of a deal."

Ok, so what happens to EVERY request made to a web server by default? They get logged. The URL gets logged, but not necessarily the headers. So, how secure are your web sites logs? How secure is your web server?

The reason you don't put sensitive data in the URL is the same reason you don't store unencrypted passwords/credit card numbers/SSNs in your database.

8Oct/075

member variable values in the querystring == security risk?

There is a lot of emphasis in the web development world on making urls "pretty" and, more importantly, discoverable. While there isn't anything wrong with wanting urls that human beings can read and understand, web developers need to understand that the querystring is an entry point into your application if you are passing values in it and therefore is an attack vector.

So, say you have a querystring that looks something like this.

http://lazycoder.com/people/delete/1242

What does 1242 stand for? Why are you passing it in the query string? What happens to the value when it gets assigned to a variable inside your code? Are you sure you have all of your authorization checks in place to make sure that the currently logged in user has permission to edit whatever 1242 represents? The W3C mentions not including sensitive data in the querystring.

Authors of services which use the HTTP protocol SHOULD NOT use GET based forms for the submission of sensitive data, because this will cause this data to be encoded in the Request-URI. Many existing servers, proxies, and user agents will log the request URI in some place where it might be visible to third parties. Servers can use POST-based form submission instead.

I personally get itchy anytime I see PK values in a web interface. It means if an attacker does somehow gain access to my database, they already know a PK value and could possibly pass it in through a security hole.

Encoding or encrypting the values before putting them into the querystring doesn't completely solve the problem. In fact, it makes the URL ugly again.

What I would suggest is this:

  1. Encrypt sensitive values (userID, values used in edit/delete actions)
  2. Place those values in hidden form fields. These can be created on the fly if needed
  3. Only pass sensitive values using a POST verb.
  4. Include a secure site/session token in a hidden form to help foil cross-site attacks.

Ideally, I'd like some way in the framework to mark variables as "secure" to prevent any part of the framework from putting them in the querystring. Perhaps raise some kind of warning.

My point isn't to indict pretty URLs, it's just to raise awareness of the querystring and it's potential security risks.

There are also other possible problems with passing params in the querystring. They mainly involve changing data on the server. The W3C explicitly states that HTTP GET is only to be used when no data will be changed on the server.

GET considered harmful.
Get Considered Harmful; Sometimes.
Securing forms with POST isn't enough

Filed under: .NET, Rails, Tutorials 5 Comments
4Oct/070

The Big Rewrite – Other articles

Adam Turoff wrote a couple of great blog posts examining the big rewrite.
Rewriting Software
Rewriting Software Part 2

Adam Wiggins:

Go Ahead, do the big Rewrite

Great comments in the post Informal Survey: Do Rewrites Really Fail?