To test the JumboEats app we used two automated testing tools: Lint and Crashlytics. These tools allowed us to identify and correct issues, inconsistencies, and deprecated methods used in our front-end. We also conducted usability to gauge impressions of our app from a user’s perspective. To evaluate the security of our backend server and database we found a checklist on an engineering blog. This checklist laid out best practices and tools to promote security for users and our own systems.
We started out with a lot of errors and went through them one at a time. Most of them could be solved easily (ie: unused import statements), some of them required a little bit of code restructuring (ie: layout redundancies), and some of them had to be suppressed for our code to function the way we wanted. The linting tool for android has a little bit more involved than a linter for javascript, and less intuitive, but still helpful to make sure we are following good coding practices.
We installed Fabric in Android Studio and walked through their “crash button” tutorial where we forced our app to crash and then looked at the output on our Fabric Dashboard. We then added in Crashlytics log statements to all of our catch statements in our Get and Post requests. This testing software was helpful when we found a bug in our app right after installing Crashlytics. While trying to solve the bug, things we did to try to fix it kept crashing the app. Our Fabric Dashboard told us what line our app had crashed on and why it had crashed. Thanks Crashlytics!
We walked through the app with three testers (A, B and C):
1. First we asked a series of preliminary questions about their app usage and comfort level with the android OS:
A used 9 apps a day and did not have an android phone
B used 5 apps a day and did not have an android phone
C used 15 apps a day and did have an android phone
All three had push notifications enabled on their phones for certain apps
None of the three used food related apps
2. Then they opened the app on the emulator and we asked what their eye was drawn to first and second:
A saw a food item first, and the add button in the corner second
B saw a food item first, and then another food item below it
C saw a time, and then another time below it
3. We then asked them to find which field held the food type in each entry:
All three quickly identified the correct field.
4. We then pointed to the field that contained the group/organization sponsoring the event and asked them to identify the piece of information being conveyed:
They took a little time to scroll and look at different entries before each answering correctly.
5. We asked the same question about the location field:
All three answered correctly.
6. We then asked them to pretend they had a free food event they wanted others to know about, and post it:
All three correctly went to the add button in the corner.
A completed the task with no difficulty.
B did not know that the add form was scrollable, so couldn’t add more information or click the post button, until we told her.
C had the same problem as B, but figured it out within a reasonable amount of time.
7. The next step was to add a free food event happening at that moment. We wanted to make sure it was obvious that the date and time fields did not have to be edited if the event was current.
All three participants understood this when posting their event.
8. The last question asked if the users had any suggestions:
A said the font on the main screen was too small
B said there should be pictures of the food
C said the add button in the corner looked bad, and that the scrolling capabilities of the main screen aren’t obvious
Conclusion from usability testing:
Information location and how to post a free food event seems to be straightforward, however, the post screen needs definite work to be more user friendly (we especially need to work on making the scrolling capabilities of the post screen more obvious).
To review our Node.js server’s security we followed a series of guidelines laid out in the article Node.js Security Checklist written by Gergely Nemeth (https://blog.risingstack.com/node-js-security-checklist/). The guidelines are extensive and while not all of them are relevant to our server and application, they provide a solid framework for identifying potential vulnerabilities. We updated our server to include the most practical and effective security measures described in the RisingStack article.
Security HTTP Headers - To handle security HTTP headers I used the Helmet npm module. This automatically sets several HTTP headers to hide information from suspicious sources trying to access the server. Examples include automatically setting the user to HTTPS and concealing the server’s MIME type. Users can select various security options using Helmet, though I stuck with the default settings.
Sensitive Data on the Client Side - The best way to mitigate exposing sensitive client data is by regularly reviewing code to ensure this data is hidden or encrypted. We accomplish this by only using hard-coded API keys on the server and not in the application itself.
Authentication/Brute Force Protection - The author prescribes the use of rate limiting to protect against brute force attacks. I implemented rate limiting using the express-rate-limit npm module. This is a basic system that allows for limiting the rate uniformly on all server paths or with different rules for each path.
Data Validation - Our server uses a series of conditional statements ensuring the proper type and length of inputted data to defend against reflected cross site scripting and stored cross site scripting. We do not have to worry so much about users receiving executable JavaScript code since their application is running on Android and not a web browser; however, our server can still be taken advantage of by such attacks. Also, protecting users is arguably a developer’s greatest responsibility even if the risk of danger is low. Our server will also remove food events that are in the past so any item in the database for more than a few days will become suspect. A multipronged approach is most effective for ensuring data is valid. Data filtering also helps prevent database and command injections.
Node Security Project - The Node Security Project has a command-line tool that checks modules being used in a project for vulnerabilities. This tool (nsp) found no vulnerabilities with any of the modules being used by the JumboEats server.