Guidelines for Creating a Secure App API: Security Tips

Seeking Input on App Data Sync Process and API

  • I am seeking feedback on my approach to creating a data sync process and supporting API for an app I am developing. Here are the core principles guiding my app and API:
  • Free: The app/API will be available for use at no cost.
  • Open source: Both the app and API source code will be openly accessible for public use.
  • Decentralised: Users can run the API service on any server and share it with other users, promoting autonomy and flexibility.
  • Anonymous: User information will not be collected or stored alongside their data to prioritize privacy.
  • Secure: User data will be encrypted before transmission, ensuring data security and confidentiality.

The plan is to set up a default instance of the API on a public server for initial user syncing. However, if the app gains popularity, users can create their own instances for personal use or share with others to ensure uninterrupted service availability. This model encourages self-sufficiency and independence among users for privacy, reliability, and cost-saving purposes.

User Sync Journey Overview:

  1. User downloads the app and generates data during app usage.
  2. When ready to sync for the first time, user enters a "password" used to encrypt their data locally without sending the password to the server.
  3. User clicks "Sync," sending encrypted data along with a unique ID to the selected API instance for storage.
  4. Subsequent syncs involve locally encrypting data using the saved password before updating on the server with the unique ID.
  5. To retrieve synced data, the unique ID is sent to the API for encrypted data retrieval, decrypted locally using the user's password.

The app is built in javascript, while the API uses Node.js (restify) with MongoDB as the backend. A typical sync interaction with the server appears like this:

1. Initial Sync

POST /api/data

Post body:

{
    "data":"DWCx6wR9ggPqPRrhU4O4oLN5P09onApoAULX4Xt+ckxswtFNH/QQ+Y/RgxdU+8+8/muo4jo/jKnHssSezvjq6aPvYK+EAzAoRmXenAgUwHOjbiAXFqF8gScbbuLRlF0MsTKn/puIyFnvJd..."
}

Response:

{
    "id":"507f191e810c19729de860ea",
    "lastUpdated":"2016-07-06T12:43:16.866Z"
}

2. Get Sync Data

GET /api/data/507f191e810c19729de860ea

Response:

{
    "data":"DWCx6wR9ggPqPRrhU4O4oLN5P09onApoAULX4Xt+ckxswtFNH/QQ+Y/RgxdU+8+8/muo4jo/jKnHssSezvjq6aPvYK+EAzAoRmXenAgUwHOjbiAXFqF8gScbbuLRlF0MsTKn/puIyFnvJd...",
    "lastUpdated":"2016-07-06T12:43:16.866Z"
}

3. Update Synced Data

POST /api/data/507f191e810c19729de860ea

Post body:

{
    "data":"DWCx6wR9ggPqPRrhU4O4oLN5P09onApoAULX4Xt+ckxswtFNH/QQ+Y/RgxdU+8+8/muo4jo/jKnHssSezvjq6aPvYK+EAzAoRmXenAgUwHOjbiAXFqF8gScbbuLRlF0MsTKn/puIyFnvJd..."
}

Response:

{
    "lastUpdated":"2016-07-06T13:21:23.837Z"
}

Data storage in MongoDB format:

{
    "id":"507f191e810c19729de860ea",
    "data":"DWCx6wR9ggPqPRrhU4O4oLN5P09onApoAULX4Xt+ckxswtFNH/QQ+Y/RgxdU+8+8/muo4jo/jKnHssSezvjq6aPvYK+EAzAoRmXenAgUwHOjbiAXFqF8gScbbuLRlF0MsTKn/puIyFnvJd...",
    "lastUpdated":"2016-07-06T13:21:23.837Z"
}

Data encryption utilizes CryptoJS's AES implementation, generating a 256-bit key from the user's password for secure data transmission. Concerns to address include potential data breaches and safeguarding against abuse of the service.

  • CryptoJS AES Security: Is the level of encryption provided by CryptoJS AES strong enough to prevent unauthorized decryption of sensitive data?
  • Data Submission Control: How can data integrity be ensured when allowing open access submission within the API? Implement practical measures without compromising guiding principles.
  • Service Abuse Prevention: Sustain server space efficiency by monitoring and limiting user actions such as spamming sync requests and excessive data storage.

Your insights and suggestions on improving this approach while upholding core principles are appreciated, especially if you know of similar implementations worth referencing.

Answer №1

While I cannot provide a definitive answer on the security of specific AES algorithms/keys, if they are secure and properly generated, it shouldn't pose a problem if other users can access the encrypted data.

To prevent abuse without the need for additional accounts, implementing captchas or similar measures against automated usage can be effective. Requiring captchas for new accounts and setting limits on data volume and call frequency across all accounts can help maintain security.

For safeguarding against accidental exposure of clear-text data, creating secondary keys for each account and verifying messages using the server's public secondary key can enhance encryption. For example:

data = secondary_key(user_private_key(cleartext))

This approach ensures that the data remains encrypted, with the server being able to decrypt it if necessary while preventing unauthorized access.

In terms of your API, if you are already utilizing HTTP and POST methods, an id may not be essential. Typically, a POST request returns a URI linking to the created data. This URI can then be accessed via GET or modified through PUT:

POST /api/data
{"data": "..."}

Response:

Location: /api/data/12345
{"data": "...", "lastmodified": "..." }

To update the data:

PUT /api/data/12345
{"data": "..."}

While this method is optional, it could simplify client-side implementation and potentially improve caching and cache invalidation processes.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Prevent Jquery nth-child from impacting nested elements

Here is an issue I am currently dealing with in my code. I need to insert some text after the second paragraph, excluding the blockquote. Currently, when using jQuery, the new text appears after both the 2nd paragraph in content and the 2nd paragraph in th ...

Attempting to navigate through nested data within existing mapped data

The data set 1 consists of an array that contains another array called data set 2. Currently, data set 1 is being mapped to display a single-column table with data1.name inside it. The data1.name serves as a clickable button that reveals the related data i ...

How can we apply position: fixed in print media queries using CSS?

In order to display a footer on every printed page, we have implemented the use of position: fixed. However, one issue that has arisen is that content ends up flowing underneath the footer. Is there a solution to prevent this from happening while still k ...

Original: Custom/Modified 'Fibonacci' Number sequenceRevised: Personalized/Altered

I am looking to create a unique variation of the Fibonacci sequence. The implementation I have in mind is as follows: (FSM) - FSM(0) = 0, FSM(1) = 1, FSM(n) = FSM(n - 2) + FSM(n - 1) / n How can this be achieved using JavaScript? Specifically, I need to ...

Learn the process of utilizing confirm (and then submit) with Sweet Alert!

I have a table where each row has a delete button set up like this: <form id="tableDelete_1"> <input type="hidden" name="tipo" value="delete" /> <input type="submit" name="send" value="Delete" class="btn btn-danger btn-xs" onClick="retu ...

Searching for documents in MongoDB that meet specific criteria has become possible through the use

Criteria: COUNT the total number of documents in the collection WHERE objects.objectType is 'group' AND (objects.objectType is NOT 'person' AND relation is 'Exposed_to') Expectation: should return the count of all documents W ...

__dirname value not able to be retrieved

Currently, I'm utilizing __dirname to obtain the absolute path to the GraphQL schema: const schema = loadSchemaSync(path.join(__dirname, './graphql/schemas/schema.graphql'), { loaders: [new GraphQLFileLoader()] }); After transitioning the ...

Implementing AJAX to Access a PHP File Across Multiple Web Pages

I devised a personal framework for myself. I implemented an ajax script on each page of my website by including a single PHP file in every webpage. Here is the script I added to my add.php file: function demo(str) { if (str.length==0){ ...

What is the most efficient method for transferring Flask variables to Vue?

I am currently developing a visualization application using a flask server and vue.js for the front end. Other discussions on this topic explore how to avoid conflicts between vue.js and flask variable syntax, as shown here. In my scenario, I'm inte ...

InvalidTypeError: The function 'state.map' cannot be applied

import React from "react"; import { useContext, useEffect, useRef, useState } from "react"; import noteContext from "../Context/notes/NoteContext"; import Addnote from "./Addnote"; import Noteitems from "./Notei ...

Tips for executing a series of getJSON requests sequentially, depending on the outcome of the preceding request

Within my project, I am in the process of collecting data from two distinct sources. Initially, it must iterate through an internal JSON file using loop.each to check if the data is available. If not, it then needs to initiate a second request using $.getj ...

Receiving a getRange error when importing JSON into Google Sheets

Struggling with importing JSON data to Google Spreadsheets using Google Script? I don't have much Java knowledge, so forgive me if this question seems a bit silly! However, I do have experience coding in VBA. My current challenge involves pulling liv ...

Vue/Vuex - Module two relies on module one, which in turn fetches data from the server

Take a look at this: import accountModule from '@/store/modules/account/account'; import otherModule from '@/store/modules/other/other'; export default new Vuex.Store({ modules: { account: accountModule, other: otherModule, ...

React seems to be frequently throwing errors related to undefined variables

What I'm attempting to do is repeat a React element a certain number of times. I've used a for loop in the past with simple HTML elements and it worked fine. However, now I'm encountering an error stating that the 'fields' array is ...

What is the process for using the GitHub API to access a repository's README document?

For my project, I'm utilizing the GitHub API to access the raw README.md file using /repos/{owner}/{repo}/readme. I've successfully executed the call using Thunderclient in VSCode and retrieved the raw file. https://i.sstatic.net/FtkfW.png Howev ...

Creating an element in react-draggable with two sides bound and two sides open - here's how!

At the moment, I am facing an issue where the element is restricted from moving outside of the container with the class of card-width-height. My goal is to have the right and bottom sides bounded within the container while allowing the element to move beyo ...

An error was discovered: [$injector:unpr] The provider aProvider is not recognized <- a

While working on my development machine, I encountered no issues. However, upon loading the same form onto my production server, I encountered an error: Uncaught Error: [$injector:unpr] Unknown provider: aProvider <- a I found that removing the followi ...

How can labels be added when mapping over JSON data?

If I have JSON data structured like this: { "siteCode": "S01", "modelCode": "M001", "modelDesc": "Desc01", "price": 100 "status": "A", "startDate": "Ma ...

Struggling to access YouTube account via Google sign-in using Puppeteer framework

I am facing an issue with my puppeteer code where I am unable to proceed past the email page after clicking next due to some bot protection by Google advising me to "Try using a different browser...etc". Is there a way to bypass this using puppeteer? I h ...

Instructions on how to insert information into an array by clicking a button

As a newbie JavaScript programmer, I am struggling to figure out how to make my code work as a function. I want to update the ajax_data array every time I click the add row button. Fresh JS coder looking for some guidance. var ajax_data = [{ Type: "A ...