Friday, August 5, 2016

How to Use Jscrambler 4 to Protect Your Application's Integrity_part1

In recent years, as a platform-independent language, JavaScript has found its way to a wide array of uses, ranging from mobile applications to HTML5-based games and Node.js servers. Long gone are the days when you only used JavaScript for special effects and form validation.

This development is good both for developers and for consumers, who get faster updates to their applications regardless of the platform they are on.

But it also raises questions about security.

How can we make sure our applications run as intended? How do we enforce our licenses? And what about piracy?

In this tutorial, we will look at the most common threats to your JavaScript applications and how you can protect against them. We will also look at the steps in making Jscrambler 4.0 a part of your development workflow to easily keep your JavaScript applications secure.

Secure the Communication Between Your Client and Server

As JavaScript is mostly used online, the natural place to start is the connectivity between the application running on your users' devices and your server.

First, let me get this out of the way: no matter how good protection you add on the client side, you always need to start with the assumption that the client can be compromised. Some go as far as to say that you have to treat the client as malicious.

Fundamentally, the reason for this is that no matter how well you secure your client, the HTTP communication between the JavaScript client and your server can always be tampered with, with the help of request-sniffing tools or even custom-made clients that use your server's protocols.

So, if your application talks to a server, before adding any other form of client-side security, start by securing your server as much as possible—just as you would when using a regular HTML interface.

1. Validate Your Data

You can think of securing your server through two concepts: data integrity and data confidentiality.

Data integrity means that the data in your application should remain accurate and consistent during its lifecycle. Data confidentiality means that your users' data should stay secure, and third parties should never get access to it.

While you should do parameter validation already in the JavaScript client, that won't prevent hackers from sending malformed or even malicious data to your server. After all, someone looking to break your server probably won't even use your UI!

So, when working with a JavaScript application, all the regular server-side validations, from escaping HTML characters to checking that attributes are of the correct type, still apply.

Sometimes, the data sent in is correctly formatted but doesn't make sense in the application's state—for example, when a player submits an impossibly high score. You can protect your server against situations like these by using sanity checks and placing as much of the application's logic on the server as possible.

2. Keep Your Data Secure

Another part of securing the client-server communication is making sure that all user-specific data stays confidential and accessible by only the authorized user.

The first step is to use SSL in all communication between your JavaScript client and your server to prevent others on the internet from spying on the data passed between the two.

Next, you'll need to validate that the requests are indeed coming from the correct user. The details for how to best do this depend on your application. In web-based applications, nonces are a useful technique, whereas in a game's context, OAuth authentication might be a more natural approach.

Just keep in mind that you should never store sensitive information such as passwords or API keys in your client. It's a good idea to think of your server as an API that can be used by the JavaScript client but also other clients on the internet.

You Can't Check Everything on the Server

While the checks mentioned above apply to every type of application, when more complexity is added to the client, some verifications become hard to do.

In multiplayer games, for example, running all the logic through your server will work well as long as the game is simple and you only have a limited number of players. But as the active user base grows, the load on the server will make you consider the possibility of moving some of the processing to the client. The same happens if your game logic is so complex that simulating it on the server would take up a lot of resources.

That's where the boundaries get blurred. 

While the idea of never trusting the client sounds good, in practice you'll have to set a threshold, saying "this is how much I trust my client" and only do sanity checks on the server. If some of the player's actions also affect other players, that's where you need to involve the server more, leaving the spots where the user can harm only his or her own experience to the client to handle.

And what about the many JavaScript use cases where you don't have a server, or where placing the application logic on the server doesn't make sense, such as mobile apps, HTML5 streaming players, and map applications?

Finally, it's good to keep in mind that no matter how well you secure your server, your JavaScript client is always exposed. So, unless you add some kind of protection to it, it's very easy for an attacker (Man-in-the-Browser or data exfiltration attacks, for example) to gain access to sensitive data, or to modify the user experience.

Protect Your JavaScript

As a dynamic language, JavaScript can be modified in the browser using basic tools such as the browser's built-in debugger. If you know what you are doing, you can replace parts of the code and change the application's behavior on the fly.

As we saw above, you should make sure invalid data never makes it to the database on your server. But some changes are more restricted than this. A malware plugin might add new buttons to your application to lure the user to an external site. Or the user might hack the client to see more of the game without playing it.

Changes like this will not break your entire application, but they will change the way the user experiences it. In the case of malware, this can also pose a serious threat to the user's privacy.

Because JavaScript is an interpreted language, this is impossible to prevent entirely. A dedicated hacker will always find a way to get past the obstacles, just as a burglar can break any lock. But we can make breaking in so hard that most users will use proper methods (such as getting good at your game) rather than hack the application.

This is where Jscrambler can help you.

1. Make Your JavaScript Hard to Hack

Jscrambler is a JavaScript security platform that aims to make sure JavaScript applications are executed the way they were developed to be.


To give Jscrambler a try, visit its homepage and sign up for a free trial. If you find it lives up to your expectations, you can later pick one of its paid plans.

When signed in, if there is some text saying "A new version of Jscrambler is now available" at the top of the page, it means you're still seeing the old version. Click on Try it now.


Jscrambler 4 organizes your work in applications, each of which can consist of one or more JavaScript files. So next, you'll see the screen for selecting the application to work on.


If you want to test the functionality using a JavaScript application of your own, click on Create App.

For now, however, let's choose Playground. In this mode, you'll get to try all transformations on an example script, while the transformations you can apply to your actual application are limited by your subscription level.

On the left, you'll see the File Tree, a list of files in your application, and an Add button for importing or creating new files. In the playground, the Add button is disabled.

On the right, there is a menu for picking the Language Specifications and Application Mode for your app. Jscrambler uses them to ensure the transformed code will work in your selected environment, taking its limitations and possibilities into account.

We'll now go with ES5 and a basic Web Browser App.


Click on the filename (clock.js) to start working on it.

The file's contents will be shown in the middle of the screen: the source code on the left and the version transformed by Jscrambler on the right.


Next, select the Code Transformations tab on the right to reveal a list of available transformations. Jscrambler allows you to choose the transformations you find relevant to your code. You can even use annotations in your code to change the way some of the code gets transformed. That can be handy in performance-critical code blocks, for example rendering functions in games.

To test the transformations, select them one at a time. Then click on Protect App at the bottom of the window to create a new version of your transformed code.

Next to the button, you'll see a meter presenting the effects of these changes on your JavaScript code.


In the meter, you'll see three icons, representing the cost, resilience, and potency (going from left to right in the screen shot above) of the transformations you have selected for your application.

To get started, check the checkbox in front of Control Flow, and then click on Protect App.


The Control Flow Flattening is one of the powerful new transformations added in Jscrambler 4. It flattens the script's control flow so that it becomes hard for a person reading the code to follow the logic of your application.

Next, continue by selecting some more obfuscation options. As you add more, you'll notice how your code gets more and more difficult to read—and thus edit without breaking its functionality.

Also, when you click on Protect App again, even without changing the settings, you'll notice that the contents of the protected script change every time.

Jscrambler's transformations are polymorphic, making sure the transformations produce a different output every time. This way, even if someone were able to hack the current version, next time you run your code through Jscrambler, those changes would no longer work.
Written by  Jarkko Laine

If you found this post interesting, follow and support us.
Suggest for you:

JavaScript for Absolute Beginners

JavaScript For Beginners - Learn JavaScript From Scratch

JavaScript for Beginners

JavaScript Bootcamp - 2016

ES6 Javascript: The Complete Developer's Guide


Building a REST API With AWS SimpleDB and Node.js_part2 (end)

Building the Server

To get started, let's install Express, a Node.js HTTP server framework:
  1. npm install express —-save
Express manages most of the minutiae in setting up a server, but it doesn't include any facility for handling the HTTP request body, so we'll need to install another module, body-parser, to enable us to read the request body.
  1. npm install body-parser --save
Body-parser has a few different options for parsing the body of the HTTP request. We’ll use the json() method for readability, but switching to another method is just swapping out the method on the bodyParser object. We only need the bodyParser method on the create and update methods, so we can just include it in those particular routes.

Create
Since each SimpleDB itemName needs to be unique, we can auto-generate a new itemName for each newly created item. We’re going to use the cuid module, which is a lightweight way to generate unique identifiers.
  1. npm install cuid --save
SimpleDB expects attributes to be in the attribute name/value pair format:
  1. [
  2.     { "Name" : "attribute1", "Value" : "value1" },
  3.     { "Name" : "attribute1", "Value" : "value2" },
  4.     { "Name" : "attribute2", "Value" : "value3" },
  5.     { "Name" : "attribute3", "Value" : "value4" }
  6. ]
Your server could certainly just accept and pass the values in this format directly to SimpleDB, but it is counter-intuitive to how data is often structured, and it's a difficult concept with which to work. We'll use a more intuitive data structure, an object/value array:
  1. {
  2.     "attribute1"    : ["value1","value2"],
  3.     "attribute2"    : ["value3","value4"]
  4. }
Here is a basic Express-based server with the create operation:
  1. var
  2.   aws         = require('aws-sdk'),
  3.   bodyParser  = require('body-parser'),
  4.   cuid        = require('cuid'),
  5.   express     = require('express'),
  6.    
  7.   sdbDomain   = 'sdb-rest-tut',
  8.    
  9.   app         = express(),
  10.   simpledb;
  11.  
  12. aws.config.loadFromPath(process.env['HOME'] + '/aws.credentials.json');
  13. simpledb = new aws.SimpleDB({
  14.   region        : 'US-East',
  15.   endpoint  : 'https://sdb.amazonaws.com'
  16. });
  17.  
  18. //create
  19. app.post(
  20.   '/inventory', 
  21.   bodyParser.json(),
  22.   function(req,res,next) {
  23.     var
  24.       sdbAttributes   = [],
  25.       newItemName     = cuid();
  26.      
  27.     //start with: 
  28.     /*
  29.       { attributeN     : ['value1','value2',..'valueN'] }
  30.     */
  31.     Object.keys(req.body).forEach(function(anAttributeName) {
  32.       req.body[anAttributeName].forEach(function(aValue) {
  33.         sdbAttributes.push({
  34.           Name  : anAttributeName,
  35.           Value : aValue
  36.         });
  37.       });
  38.     });
  39.     //end up with:
  40.     /*
  41.       [ 
  42.         { Name : 'attributeN', Value : 'value1' },
  43.         { Name : 'attributeN', Value : 'value2' },
  44.         ...
  45.         { Name : 'attributeN', Value : 'valueN' },
  46.       ]
  47.     */
  48.  
  49.     simpledb.putAttributes({
  50.       DomainName    : sdbDomain,
  51.       ItemName      : newItemName,
  52.       Attributes    : sdbAttributes
  53.     }, function(err,awsResp) {
  54.       if (err) { 
  55.         next(err);  //server error to user
  56.       } else {
  57.         res.send({
  58.           itemName  : newItemName 
  59.         });
  60.       }
  61.     });
  62.   }
  63. );
  64.  
  65.  
  66. app.listen(3000, function () {
  67.   console.log('SimpleDB-powered REST server started.');
  68. });
Let's start up your server and try it out. A great way to interact with a REST server is to use the cURL tool. This tool allows you to make an HTTP request with any verb right from the command line. To try out creating an item with our REST server, we'll need to activate a few extra options:
  1. curl -H "Content-Type: application/json" -X POST -d '{"pets" : ["dog","cat"], "cars" : ["saab"]}' http://localhost:3000/inventory
Option Purpose
 -H        Add a line to the HTTP heading
 -X        Define which verb will be used
 -d        Data to be sent in the HTTP request body

After running the command, you'll see a JSON response with your newly created itemName or ID. If you switch over to SdbNavigator, you should see the new data when you query all the items.

Read
Now let’s build a basic function to read an item from SimpleDB. For this, we don’t need to perform a query since we’ll be getting the itemName or ID from the path of the request. We can perform a getAttributes request with that itemName or ID.

If we stopped here, we would have a functional but not very friendly form of our data. Let’s transform the Name/Value array into the same form we’re using to accept data (attribute : array of values). To accomplish this, we will need to go through each name/value pair and add it to a new array for each unique name.

Finally, let’s add the itemName and return the results.
  1. //Read
  2. app.get('/inventory/:itemID', function(req,res,next) {
  3.   simpledb.getAttributes({
  4.     DomainName    : sdbDomain,
  5.     ItemName      : req.params.itemID   //this gets the value from :itemID in the path
  6.   }, function(err,awsResp) {
  7.     var
  8.       attributes = {};
  9.        
  10.     if (err) { 
  11.       next(err);  //server error to users
  12.     } else {
  13.       awsResp.Attributes.forEach(function(aPair) {
  14.         // if this is the first time we are seeing the aPair.Name, let's add it to the response object, attributes as an array
  15.         if (!attributes[aPair.Name]) { 
  16.           attributes[aPair.Name] = [];
  17.         }
  18.         //push the value into the correct array
  19.         attributes[aPair.Name].push(aPair.Value);
  20.       });
  21.       res.send({
  22.         itemName    : req.params.itemID,
  23.         inventory   : attributes
  24.       });
  25.     }
  26.   });
  27. });
To test this, we need to use curl again. Try replacing [cuid] with the itemName or ID returned from our example of creating an item earlier in this tutorial.
  1. curl -D- http://localhost:3000/inventory/[cuid]
Notice that we're using the -D- option. This will dump the HTTP head so we can see the response code.

Another aspect of REST is to use your response codes meaningfully. In the current example, if you supply a non-existent ID to curl, the above server will crash because you’re trying to forEach a non-existent array. We need to account for this and return a meaningful HTTP response code indicating that the item was not found.

To prevent the error, we should test for the existence of the variable awsResp.Attributes. If it doesn’t exist, let’s set the status code to 404 and end the http request. If it exists, then we can serve the response with attributes.
  1. app.get('/inventory/:itemID', function(req,res,next) {
  2.   simpledb.getAttributes({
  3.     DomainName    : sdbDomain,
  4.     ItemName      : req.params.itemID
  5.   }, function(err,awsResp) {
  6.     var
  7.       attributes = {};
  8.        
  9.     if (err) { 
  10.       next(err);
  11.     } else {
  12.       if (!awsResp.Attributes) {
  13.         //set the status response to 404 because we didn't find any attributes then end it
  14.         res.status(404).end(); 
  15.       } else {
  16.         awsResp.Attributes.forEach(function(aPair) {
  17.           if (!attributes[aPair.Name]) { 
  18.             attributes[aPair.Name] = [];
  19.           }
  20.            
  21.           attributes[aPair.Name].push(aPair.Value);
  22.         });
  23.         res.send({
  24.           itemName    : req.params.itemID,
  25.           inventory   : attributes
  26.         });
  27.       }
  28.     }
  29.   });
  30. });
Try it out with the new code and a non-existent ID and you'll see that the server returns a 404.

Now that we know how to use status to change the value, we should also update how we are responding to a POST/create. While the 200 response is technically correct as it means ‘OK’, a more insightful response code would be 201, which indicates ‘created’. To make this change, we’ll add it in the status method before sending.
  1. res
  2.  .status(201)
  3.  .send({
  4.    itemName  : newItemName
  5.  });
Update
Update is usually the most difficult operation for any system, and this REST server is no exception.

The nature of SimpleDB makes this operation a little more challenging as well. In the case of a REST server, an update is where you are replacing the entire piece of stored data; SimpleDB on the other hand, represents individual attribute/value pairs under an itemName.

To allow for an update to represent a single piece of data rather than a collection of name/value pairs, we need to define a schema for the purposes of our code (even though SimpleDB doesn’t need one). Don’t worry if this is unclear right now—keep reading and I’ll illustrate the requirement.

Compared to many other database systems, our schema will be very simple: just a defined array of attributes. For our example, we have four fields we are concerned with: pets, cars, furniture, and phones:
  1. schema      = ['pets','cars','furniture','phones'],
With SimpleDB you can’t store an empty attribute/value pair, nor does SimpleDB have any concept of individual items, so we’ll assume that if SimpleDB doesn’t return a value, it doesn’t exist. Similarly, if we try to update a SimpleDB item with an empty attribute/value pair, it will ignore that data. Take, for example, this data:
  1. {
  2.   "itemName": "cil89uvnm00011ma2fykmy79c",
  3.   "inventory": {
  4.     "cars": [],
  5.     "pets": [
  6.       "cat",
  7.       "dog"
  8.     ]
  9.   }
  10. }
Logically, we know that cars, being an empty array, should have no values, and pets should have two values, but what about phones and furniture? What do you do to those? Here is how we translate this update request to work with SimpleDB:
  • Put an attribute pet with a value to cat.
  • Put an attribute pet with a value to dog.
  • Delete attributes for cars.
  • Delete attributes for phones.
  • Delete attributes for furniture.
Without some form of schema that at least defines the attributes, we wouldn’t know that phones and furniture needed to be deleted. Luckily, we can consolidate this update operation into two SimpleDB requests instead of five: one to put the attributes, and one to delete the attributes. This is a good time to pull out the code from the post/create function that transforms the attribute/array of values object into the attribute/value pair array.
  1. function attributeObjectToAttributeValuePairs(attrObj, replace) {
  2.    var
  3.      sdbAttributes   = [];
  4.  
  5.     Object.keys(attrObj).forEach(function(anAttributeName) {
  6.       attrObj[anAttributeName].forEach(function(aValue) {
  7.         sdbAttributes.push({
  8.           Name    : anAttributeName,
  9.           Value   : aValue,
  10.           Replace : replace           //if true, then SimpleDB will overwrite rather than append more values to an attribute
  11.         });
  12.       });
  13.     });
  14.  
  15.    return sdbAttributes; 
  16. }
We’re going to make an important alteration to the create function as well. We’ll be adding a new attribute/value to all items. This attribute will not be added to the schema and is effectively read-only.

We will add an attribute called created and set the value to 1. With SimpleDB, there is limited ability to check if an item exists prior to adding attributes and values. On every putAttributes request you can check for the value and existence of a single attribute—in our case, we’ll use created and check for a value of 1. While this may seem like a strange workaround, it provides a very important safety to prevent the update operation from being able to create new items with an arbitrary ID.
  1. newAttributes.push({
  2.   Name    : 'created',
  3.   Value   : '1'
  4. });
Since we’ll be doing a couple of asynchronous HTTP requests, let’s install the async module to ease the handling of those callbacks.
  1. npm install async —-save
Remember, since SimpleDB is distributed, there is no reason to sequentially put our attributes and then delete. We’ll use the function async.parallel to run these two operations and get a callback when both have completed. The responses from AWS form putAttributess and deleteAttributes do not provide important information, so we will just send an empty response with a status code 200 if there are no errors.
  1. app.put(
  2.   '/inventory/:itemID', 
  3.   bodyParser.json(),
  4.   function(req,res,next) {
  5.     var
  6.       updateValues  = {},
  7.       deleteValues  = [];
  8.      
  9.     schema.forEach(function(anAttribute) {
  10.       if ((!req.body[anAttribute]) || (req.body[anAttribute].length === 0)) {
  11.         deleteValues.push({ Name : anAttribute});
  12.       } else {
  13.         updateValues[anAttribute] = req.body[anAttribute];
  14.       }
  15.     });
  16.      
  17.     async.parallel([
  18.         function(cb) {
  19.           //update anything that is present
  20.           simpledb.putAttributes({
  21.               DomainName    : sdbDomain,
  22.               ItemName      : req.params.itemID,
  23.               Attributes    : attributeObjectToAttributeValuePairs(updateValues,true),
  24.               Expected      : {
  25.                 Name          : 'created',
  26.                 Value         : '1',
  27.                 Exists        : true
  28.               }
  29.             },
  30.             cb
  31.           );
  32.         },
  33.         function(cb) {
  34.           //delete any attributes that not present
  35.           simpledb.deleteAttributes({
  36.               DomainName    : sdbDomain,
  37.               ItemName      : req.params.itemID,
  38.               Attributes    : deleteValues
  39.             },
  40.             cb
  41.           );
  42.         }
  43.       ],
  44.       function(err) {
  45.         if (err) {
  46.           next(err);
  47.         } else {
  48.           res.status(200).end();
  49.         }
  50.       }
  51.     );
  52.   }
  53. );
To take this for a spin, let's update a previously created entry. This time, we will make the inventory only include a "dog", removing all other items. Again, with cURL, run the command, substituting [cuid] with one of your item IDs.
  1. curl -H "Content-Type: application/json" -X PUT -d '{"pets" : ["dog"] }' http://localhost:3000/inventory/[cuid]
Delete
SimpleDB has no concept of an item deletion, but it can deleteAttributes, as mentioned above. To delete an item, we’ll need to delete all the attributes and the ‘item' will cease to be.

Since we’ve defined a list of attributes in our schema, we’ll use the deleteAttributes call to remove all of those attributes as well as the created attribute. As per our plan, this operation will be at the same path as Update, but using the verb delete.
  1. app.delete(
  2.   '/inventory/:itemID', 
  3.   function(req,res,next) {
  4.     var
  5.       attributesToDelete;
  6.      
  7.     attributesToDelete = schema.map(function(anAttribute){
  8.       return { Name : anAttribute };
  9.     });
  10.      
  11.     attributesToDelete.push({ Name : 'created' });
  12.      
  13.     simpledb.deleteAttributes({
  14.         DomainName    : sdbDomain,
  15.         ItemName      : req.params.itemID,
  16.         Attributes    : attributesToDelete
  17.       },
  18.       function(err) {
  19.         if (err) {
  20.           next(err);
  21.         } else {
  22.           res.status(200).end();
  23.         }
  24.       }
  25.     );
  26.   }
  27. );
List
Rounding out our REST verbs is list. To achieve the list operation, we’re going to use the select command and the SQL-like query language. Our list function will be barebones, but will serve as a good basis for more complex retrieval later on. We’re going to make a very simple query:
  1. select * from `sdb-rest-tut` limit 100
As we ran into with the get/read operation, the response from SimpleDB isn’t very useful as it is focused on the attribute/value pairs. To avoid repeating ourselves, we’ll refactor the part of the get/read operation into a separate function and use it here. While we are at it, we’ll also filter out the created attribute (as it will show up in the get operation).
function attributeValuePairsToAttributeObject(pairs) {
  1.   var
  2.     attributes = {};  
  3.   pairs
  4.     .filter(function(aPair) {
  5.       return aPair.Name !== 'created';
  6.     })
  7.     .forEach(function(aPair) {
  8.     if (!attributes[aPair.Name]) { 
  9.       attributes[aPair.Name] = [];
  10.     }    
  11.     attributes[aPair.Name].push(aPair.Value);
  12.   });  
  13.   return attributes;
  14. }
With a select operation, SimpleDB returns the values in the Items array. Each item is represented by an object that contains the itemName (as simply Name) and the attribute/value pairs.

To simplify this response, let’s return everything in a single object. First, we’ll convert the attribute/value pairs into an attribute/value array as we did in the read/get operation, and then we can add the itemName as the property ID.
  1. app.get(
  2.   '/inventory',
  3.   function(req,res,next) {
  4.     simpledb.select({
  5.       SelectExpression  : 'select * from `sdb-rest-tut` limit 100'
  6.     },
  7.     function(err,awsResp) {
  8.       var
  9.         items = [];
  10.       if (err) {
  11.         next(err);
  12.       } else {
  13.         items = awsResp.Items.map(function(anAwsItem) {
  14.           var
  15.             anItem;
  16.            
  17.           anItem = attributeValuePairsToAttributeObject(anAwsItem.Attributes);
  18.            
  19.           anItem.id = anAwsItem.Name;
  20.            
  21.           return anItem;
  22.         });
  23.         res.send(items);
  24.       }
  25.     });
  26.   }
  27. );
To see our results, we can use curl:
  1. curl -D- -X GET  http://localhost:3000/inventory
Validation
Validation is whole a subject of its own, but with the code we’ve already written, we have a start for a simple validation system.

For now, all we want to make sure is that a user can’t submit anything but what is in the schema. Looking back at the code that was written for update/put, forEach over the schema will prevent any unauthorized attributes from being added, so we really just need to apply something similar to our create/post operation. In this case, we will filter the attribute/value pairs, eliminating any non-schema attributes.
  1. newAttributes = newAttributes.filter(function(anAttribute) {
  2.   return schema.indexOf(anAttribute.Name) !== -1;
  3. });
In your production code, you will likely want a more robust validation system. I would suggest integrating a JSON schema validator like ajv and building a middleware that sits between bodyParser and your route function on create and update operations.

Next Steps

With the code outlined in this article, you have all the operations needed to store, read and modify data, but this is only the start of your journey. In most cases, you’ll need to start thinking about the following topics:
  • Authentication
  • Pagination
  • Complex list/query operations
  • Additional output formats (xml, csv, etc.)
This basis for a REST server powered by SimpleDB allows you to add middleware and additional logic to build a backbone for your application.
Written by Kyle Davis

If you found this post interesting, follow and support us.
Suggest for you:

JavaScript For Beginners - Learn JavaScript From Scratch

JavaScript for Beginners

JavaScript Bootcamp - 2016

JavaScript Tutorials: Understanding the Weird Parts

ES6 Javascript: The Complete Developer's Guide

Wednesday, August 3, 2016

Building a REST API With AWS SimpleDB and Node.js_part1

SimpleDB is a remote database offered by Amazon Web Services (AWS). The world of data stores is usually divided into SQL and NoSQL, based on the use (or non-use) of the SQL language. NoSQL data stores are usually based on a simpler key/value setup. SimpleDB straddles this line—it is a key/value store and it can also use a variant of SQL for retrieval. Most SQL languages are based on a schema that lays out the rows and columns of the data, but SimpleDB is a schema-less database, making for a very flexible data store.

In the SimpleDB database model, you have items, attributes and values.  Each row in the database is an item and can be identified by a unique and assignable item name. Each item can have up to 256 pairs of attributes and values. An unexpected aspect of SimpleDB is that an attribute can have more than one pair per item. I think the best way to think about SimpleDB is to think of a spreadsheet, but instead of each column/row intersection representing a single value, it represents an array of values.

This chart represents two items stored in a SimpleDB domain. The term domain is analogous to a “table” in other databases.

The first column is the item name—this is the only column where you can have only a single value, and you can think of it as a unique index column.

The other four columns (pets, cars, furniture, and phones) represent attributes that are currently in this domain—you aren’t limited to this, so every item can have an entirely unique set of attributes. In this data, the attribute pets on the item personInventory1 has three pairs; expressed in JSON, it’ll look something like this:
  1. { "Name" : "pets", "Value" : "dog" }, 
  2. { "Name" : "pets", "Value" : "cat" }, 
  3. { "Name" : "pets", "Value" : "fish" }
On the other hand, the item personInventory2 has only one pair:
  1. { "Name" : "pets", "Value" : "cat" }
While you don’t have to supply the same attributes for each item, you do need to supply at least one pair. This means that you cannot have an ‘empty’ item. Each attribute can have a value up to 1kb in size, so this means that each item is functionally limited to 256kb, due to the 1kb value limit and the 256 pair limit.

SimpleDB is distributed, which has some distinct traits that you need to understand and keep in mind as you design your app. Being a distributed database means a whole group of machines will respond to your requests and your data will be replicated throughout these servers. This distribution will be completely transparent to your program, but it does introduce the possibility of consistency issues—your data cannot be guaranteed to be present on all servers initially.

Don’t panic: it’s not as bad as it sounds for a few reasons. With SimpleDB, the consistency isn’t promised, but it is usually pretty good and quickly reaches all nodes from my experience. Designing around this also isn’t so hard—normally you try to avoid immediately reading a record you just wrote. Finally, SimpleDB has the option to perform consistent reads, but they are slower and may consume more resources. If your app requires consistent reading every time, you might want to reconsider using SimpleDB as your data store, but for many applications, this can be designed around or not even worried about.

On the upside, the distributed nature also affords SimpleDB a few advantages that mesh nicely with the Node.js environment. Since you don’t have a single server responding to your requests, you don’t need to worry about saturating the service, and you can achieve good performance by making many parallel requests to SimpleDB. Parallel and asynchronous requests are something that Node.js can handle easily.

Unlike many AWS services, there isn’t an Amazon-delivered console for management of SimpleDB. Luckily, there is a nice in-browser management console in the form of a Google Chrome plugin, SdbNavigator. In the SdbNavigator you can add or delete domains, insert, update and delete items, modify attributes, and perform queries.

AWS SDK

Now that we’ve gotten to know the SimpleDB service, let’s start writing our REST server. First, we’ll need to install the AWS SDK. This SDK handles not just SimpleDB but all the AWS services, so you may already be including it in your package.json file. To install the SDK, run the following from the command line:
  1. npm install aws-sdk —-save
To use SimpleDB, you’ll also need to get your AWS credentials, which include an Access Key and a Secret Key. SimpleDB is a pay-as-you-go service, but AWS currently includes a generous free allowance for SimpleDB.

Word of warning: As with any pay-as-you-go service, be aware that it’s possible to write code that can rack up big bills, so you’re going to want to keep an eye on your usage and keep your credentials private and safe.

Once you get the AWS SDK installed and have acquired your credentials, you’ll need to set up SimpleDB in your code. In this example, we'll use AWS credentials stored in a JSON file in your home directory. First, you’ll need to include the SDK module, create an AWS object, and finally set up your SimpleDB interface.
  1. var
  2.   aws         = require('aws-sdk'),
  3.   simpledb;
  4.  
  5. aws.config.loadFromPath(process.env['HOME'] + '/aws.credentials.json');
  6.  
  7. //We'll use the Northern Virginia datacenter, change the region / endpoint for other datacenters http://docs.aws.amazon.com/general/latest/gr/rande.html#sdb_region
  8. simpledb = new aws.SimpleDB({
  9.   region    : 'US-East',
  10.   endpoint  : 'https://sdb.amazonaws.com'
  11. });
Notice that we are using a specific endpoint and region. Each datacenter is entirely independent, so if you create a Domain named “mysuperawesomedata” in Northern Virginia, it will not be replicated to nor present in the Sao Paulo datacenter, for example.

The SimpleDB object that you’ve created with new aws.SimpleDB is where all your methods for interacting with SimpleDB will be based. The AWS SDK for SimpleDB has only a few methods:

Batch Operations
  • batchDeleteAttributes
  • batchPutAttributes
Domain Management & Information
  • createDomain
  • deleteDomain
  • domainMetadata
  • listDomains
Item/Attribute Manipulation
  • deleteAttributes
  • getAttributes
  • putAttributes
Querying

select
In this tutorial, we will only be dealing with Item/Attribute Manipulation and Querying; while the other categories are useful, many applications will not have any use for them.

Test Data

Using SdbNavigator, enter your access and security keys into the tool, select ‘US-East’, and click
connect.

Once you’ve successfully connected, let’s create a domain for testing. Click Add domain.


Then enter the domain name ‘sdb-rest-tut’ and click OK.


Now that you’ve created a domain, let’s enter some test data. Click Add property and add a property named “colors”. As a convention, I usually name properties in plural form to reflect the multi-value nature of SimpleDB.


Finally, we’ll click Add record to create our first SimpleDB item. In the ItemName() column, enter your unique item name. A quirk of SdbNavigator is that, by default, it will only accept a single value to each item, but this obscures the fact that a property can contain multiple values. To enter multiple values, click the S along the right edge of the property column.



In the new box, select Array to enter multiple values. In the Value column, enter “red”, and then click Add value and enter “blue”.


Finally, click Update to save the changes to this row.


Now that we’ve entered some test data, let’s make our first SimpleDB request from Node. We’ll just get everything in the Domain, which, at this point, will be just a single row.
  1. var
  2.   aws         = require('aws-sdk'),
  3.   simpledb;
  4.  
  5. aws.config.loadFromPath(process.env['HOME'] + '/aws.credentials.json');
  6.  
  7. simpledb = new aws.SimpleDB({
  8.   region        : 'US-East',
  9.   endpoint  : 'https://sdb.amazonaws.com'
  10. });
  11.  
  12. simpledb.select({
  13.   SelectExpression  : 'select * from `sdb-rest-tut` limit 100'
  14. }, function(err,resp) {
  15.   if (err) {
  16.     console.error(err);
  17.   } else {
  18.     console.log(JSON.stringify(resp,null,' '));
  19.   }
  20. });
The response will be logged to the console. Here is the response, annotated for explanation:
  1. {
  2.  "ResponseMetadata": {
  3.   "RequestId": "...",             //Every request made to SimpleDB has a request ID
  4.   "BoxUsage": "0.0000228616"      //This is how your account is charged, as of time of writing US-East region is 14 US cents per hour, so this request costs 0.00032 cents + the transfer cost (if you are currently outside of your free tier)
  5.  },
  6.  "Items": [                       //For a Select, your response will be in the "Items" object property
  7.   {
  8.    "Name": "myfirstitem",         //this is the itemName()
  9.    "Attributes": [                //these are the attribute pairs
  10.     {
  11.      "Name": "colors",            //attribute name
  12.      "Value": "red"               //value - note that every Value is a string, regardless of the contents
  13.     },
  14.     {
  15.      "Name": "colors",            //Since the attribute name is repeated, we can see that `colors` has more than one value
  16.      "Value": "blue"
  17.     }
  18.    ]
  19.   }
  20.  ]
  21. }
A REST Server

Since we’ll be building a REST Server that stores data in SimpleDB, it’s important to understand what a REST server does. REST stands for REpresentational State Transfer. A REST server is really just a server that uses HTTP standard mechanisms as an interface for your data. Often, REST is used for server-to-server communications, but you can use REST servers with the client through JavaScript libraries such as jQuery or Angular. Generally, however, an end-user won’t interact directly with a REST server.

Interestingly, the AWS SDK actually uses the REST protocol to interact with SimpleDB, so it may seem odd to create a REST server to another REST server. You wouldn’t want to use the SimpleDB REST API directly because you need to authenticate your requests, which would risk the security of your AWS account. Also, by writing a server, you’ll be able to add a layer of both abstraction and validation to your data storage that will make the rest of your whole application much easier to deal with.

In this tutorial we will be building the basic CRUD+L functions, that is Create, Read, Update, Delete and List. If you think about it, you can break down most applications into CRUD+L. With REST, you will use a limited number of paths and several HTTP methods or verbs to create an intuitive API. Most developers are familiar with a few of the HTTP verbs, namely GET and POST, as they are used most often in web applications, but there are several others.

                    Operation                                                  HTTP Verb
                    Create                                                            POST
                    Read                                                             GET
                    Update                                                             PUT
                    Delete                                                           DELETE
                    List                                                               GET

Notice that Read and List both use the same verb; we will be using slightly different paths to differentiate between the two. We’re using POST to represent Create as creating is not considered idempotent. Idempotent means that multiple identical calls will have the same result to the user and in your data, so an update (aka PUT) would be considered idempotent.

As our example, we’ll build a personal inventory server—a database to save whatever you own. Here is how the paths will look:

                            Operation HTTP Verb Path
                            Create         POST      /inventory
                            Read         GET              /inventory/1234
                            Update         PUT              /inventory/1234
                            Delete         DELETE       /inventory/1234
                            List          GET              /inventory

1234 is a placeholder for the person identifier (ID)—note that ‘create' and ‘list' do not have an ID. In the case of create, the ID will be generated, and with list, we’ll be getting all the names, so we don’t need a specific ID.
Written by Kyle Davis

If you found this post interesting, follow and support us.
Suggest for you:

Angular 2 and NodeJS - The Practical Guide to MEAN Stack 2.0

Complete Node JS Developer Course Building 5 Real World Apps

Learn and Understand NodeJS

Learn Nodejs by Building 12 Projects

Node.js Tutorials: The Web Developer Bootcamp


How to Use Jscrambler 4 to Protect Your Application's Integrity

In recent years, as a platform-independent language, JavaScript has found its way to a wide array of uses, ranging from mobile applications to HTML5-based games and Node.js servers. Long gone are the days when you only used JavaScript for special effects and form validation.

This development is good both for developers and for consumers, who get faster updates to their applications regardless of the platform they are on.

But it also raises questions about security.

How can we make sure our applications run as intended? How do we enforce our licenses? And what about piracy?

In this tutorial, we will look at the most common threats to your JavaScript applications and how you can protect against them. We will also look at the steps in making Jscrambler 4.0 a part of your development workflow to easily keep your JavaScript applications secure.

Secure the Communication Between Your Client and Server

As JavaScript is mostly used online, the natural place to start is the connectivity between the application running on your users' devices and your server.

First, let me get this out of the way: no matter how good protection you add on the client side, you always need to start with the assumption that the client can be compromised. Some go as far as to say that you have to treat the client as malicious.

Fundamentally, the reason for this is that no matter how well you secure your client, the HTTP communication between the JavaScript client and your server can always be tampered with, with the help of request-sniffing tools or even custom-made clients that use your server's protocols.

So, if your application talks to a server, before adding any other form of client-side security, start by securing your server as much as possible—just as you would when using a regular HTML interface.

1. Validate Your Data
You can think of securing your server through two concepts: data integrity and data confidentiality.

Data integrity means that the data in your application should remain accurate and consistent during its lifecycle. Data confidentiality means that your users' data should stay secure, and third parties should never get access to it.

While you should do parameter validation already in the JavaScript client, that won't prevent hackers from sending malformed or even malicious data to your server. After all, someone looking to break your server probably won't even use your UI!

So, when working with a JavaScript application, all the regular server-side validations, from escaping HTML characters to checking that attributes are of the correct type, still apply.

Sometimes, the data sent in is correctly formatted but doesn't make sense in the application's state—for example, when a player submits an impossibly high score. You can protect your server against situations like these by using sanity checks and placing as much of the application's logic on the server as possible.

2. Keep Your Data Secure
Another part of securing the client-server communication is making sure that all user-specific data stays confidential and accessible by only the authorized user.

The first step is to use SSL in all communication between your JavaScript client and your server to prevent others on the internet from spying on the data passed between the two.

Next, you'll need to validate that the requests are indeed coming from the correct user. The details for how to best do this depend on your application. In web-based applications, nonces are a useful technique, whereas in a game's context, OAuth authentication might be a more natural approach.

Just keep in mind that you should never store sensitive information such as passwords or API keys in your client. It's a good idea to think of your server as an API that can be used by the JavaScript client but also other clients on the internet.

You Can't Check Everything on the Server
While the checks mentioned above apply to every type of application, when more complexity is added to the client, some verifications become hard to do.

In multiplayer games, for example, running all the logic through your server will work well as long as the game is simple and you only have a limited number of players. But as the active user base grows, the load on the server will make you consider the possibility of moving some of the processing to the client. The same happens if your game logic is so complex that simulating it on the server would take up a lot of resources.

That's where the boundaries get blurred.

While the idea of never trusting the client sounds good, in practice you'll have to set a threshold, saying "this is how much I trust my client" and only do sanity checks on the server. If some of the player's actions also affect other players, that's where you need to involve the server more, leaving the spots where the user can harm only his or her own experience to the client to handle.

And what about the many JavaScript use cases where you don't have a server, or where placing the application logic on the server doesn't make sense, such as mobile apps, HTML5 streaming players, and map applications?

Finally, it's good to keep in mind that no matter how well you secure your server, your JavaScript client is always exposed. So, unless you add some kind of protection to it, it's very easy for an attacker (Man-in-the-Browser or data exfiltration attacks, for example) to gain access to sensitive data, or to modify the user experience.

Protect Your JavaScript

As a dynamic language, JavaScript can be modified in the browser using basic tools such as the browser's built-in debugger. If you know what you are doing, you can replace parts of the code and change the application's behavior on the fly.

As we saw above, you should make sure invalid data never makes it to the database on your server. But some changes are more restricted than this. A malware plugin might add new buttons to your application to lure the user to an external site. Or the user might hack the client to see more of the game without playing it.

Changes like this will not break your entire application, but they will change the way the user experiences it. In the case of malware, this can also pose a serious threat to the user's privacy.

Because JavaScript is an interpreted language, this is impossible to prevent entirely. A dedicated hacker will always find a way to get past the obstacles, just as a burglar can break any lock. But we can make breaking in so hard that most users will use proper methods (such as getting good at your game) rather than hack the application.

This is where Jscrambler can help you.

1. Make Your JavaScript Hard to Hack

Jscrambler is a JavaScript security platform that aims to make sure JavaScript applications are executed the way they were developed to be.


To give Jscrambler a try, visit its homepage and sign up for a free trial. If you find it lives up to your expectations, you can later pick one of its paid plans.

When signed in, if there is some text saying "A new version of Jscrambler is now available" at the top of the page, it means you're still seeing the old version. Click on Try it now.


Jscrambler 4 organizes your work in applications, each of which can consist of one or more JavaScript files. So next, you'll see the screen for selecting the application to work on.


If you want to test the functionality using a JavaScript application of your own, click on Create App.

For now, however, let's choose Playground. In this mode, you'll get to try all transformations on an example script, while the transformations you can apply to your actual application are limited by your subscription level.

On the left, you'll see the File Tree, a list of files in your application, and an Add button for importing or creating new files. In the playground, the Add button is disabled.

On the right, there is a menu for picking the Language Specifications and Application Mode for your app. Jscrambler uses them to ensure the transformed code will work in your selected environment, taking its limitations and possibilities into account.

We'll now go with ES5 and a basic Web Browser App.


Click on the filename (clock.js) to start working on it.

The file's contents will be shown in the middle of the screen: the source code on the left and the version transformed by Jscrambler on the right.


Next, select the Code Transformations tab on the right to reveal a list of available transformations. Jscrambler allows you to choose the transformations you find relevant to your code. You can even use annotations in your code to change the way some of the code gets transformed. That can be handy in performance-critical code blocks, for example rendering functions in games.

To test the transformations, select them one at a time. Then click on Protect App at the bottom of the window to create a new version of your transformed code.

Next to the button, you'll see a meter presenting the effects of these changes on your JavaScript code.


In the meter, you'll see three icons, representing the cost, resilience, and potency (going from left to right in the screen shot above) of the transformations you have selected for your application.

To get started, check the checkbox in front of Control Flow, and then click on Protect App.


The Control Flow Flattening is one of the powerful new transformations added in Jscrambler 4. It flattens the script's control flow so that it becomes hard for a person reading the code to follow the logic of your application.

Next, continue by selecting some more obfuscation options. As you add more, you'll notice how your code gets more and more difficult to read—and thus edit without breaking its functionality.

Also, when you click on Protect App again, even without changing the settings, you'll notice that the contents of the protected script change every time.

Jscrambler's transformations are polymorphic, making sure the transformations produce a different output every time. This way, even if someone were able to hack the current version, next time you run your code through Jscrambler, those changes would no longer work.
Written by: Jarkko Laine

If you found this post interesting, please follow and support us.
Suggest for you:

JavaScript For Beginners - Learn JavaScript From Scratch

JavaScript for Beginners

JavaScript Bootcamp - 2016

JavaScript Tutorials: Understanding the Weird Parts

ES6 Javascript: The Complete Developer's Guide