Skip to navigation Skip to main content Skip to footer

Does TypeScript Offer Security Improvements Over JavaScript?

06 October 2015

By Richard Appleby

TypeScript is a programming language, developed by Microsoft, which is a strict superset of JavaScript. It is intended to be used to aid in the development of large applications by adding static typing, class-based object-oriented programming, and modularity to JavaScript.

TypeScript uses a transpiler, a source-to-source compiler which takes TypeScript source and converts it into JavaScript. Any valid JavaScript is valid TypeScript, so you can take a JavaScript file, change its extension from .js to .ts, and you will have a valid TypeScript file. More importantly, the TypeScript you write ends up running as JavaScript.

So what is the point if you are just running JavaScript? The goal here is to make developing large applications in JavaScript more manageable, particularly in teams. TypeScript allows you to create well defined APIs which other developers can use.

Let’s take a look at the difference between Java, TypeScript, and JavaScript to see what we can discover about TypeScript’s type checking.

Here’s an example of a pure Java class which creates birthday greetings. It provides one function which takes a number as an argument, and returns a birthday message with the number in it.

class BirthdayMessage {

    public static void main(String[] args) {
        BirthdayMessage message = new BirthdayMessage();
        System.out.println(message.wish(args[0]));
    }

    public static String wish(int age) {
        return "Happy birthday! " + age + " today!";
    }
}

Now, if we try and use this class by passing the age straight from the command line, we get the following compiler error.

error: method wish in class BirthdayMessage cannot be applied to given types;
        System.out.println(message.wish(args[0]));
                                  ^
  required: int
  found: String
  reason: argument mismatch; String cannot be converted to int

We can be confident that someone cannot call our ‘wish’ function with a non-integer argument. This provides us with at least some level of security.

Now, let’s look at the same function in TypeScript, implemented here in a Node.js server.

import http = require('http');
var port = process.env.port || 1337
var url = require('url');

http.createServer(function (req, res) {
    var query = url.parse(req.url, true).query;
    res.writeHead(200, { 'Content-Type': 'text/html' });
    res.end(wish(query.age));
}).listen(port);

function wish(age: number): string {
    return 'Happy birthday! ' + age + ' today!';
}

When we compile this using the TypeScript transpiler, we get no errors, so what does the corresponding JavaScript look like?

var http = require('http');
var port = process.env.port || 1337;
var url = require('url');

http.createServer(function (req, res) {
    var query = url.parse(req.url, true).query;
    res.writeHead(200, { 'Content-Type': 'text/html' });
    res.end(wish(query.age));
}).listen(port);

function wish(age) {
    return 'Happy birthday! ' + age + ' today!';
}

Here we can see that the transpiler has stripped the type information from the ‘wish’ function. Any protections offered by explicitly defining a number when writing the function have been lost. In fact, this application is vulnerable to cross-site scripting by passing script tags (a string) in the age parameter (which should be a number).

So what has using TypeScript given us in terms of improved security? The answer is nothing. If anything, it has decreased the security of the application because it gives a false sense of type checking which doesn’t actually exist at run time. As useful as it may be while building the application, there is no benefit to using TypeScript at run time.

This is particularly important as JavaScript, and with it TypeScript, move from client side to server side with in-database servers (such as CouchDB), file servers (Opera Unite), and web servers (Node.js). These server-side deployments offer a much richer picking ground for attackers, with the potential for database access through SQL injection, system access through command injection, and many other forms of attack.

Published date:  06 October 2015

Written by:  Richard Appleby