javascript - App API design advice specifically around security -


i'm building app , feedback on approach building data sync process , api supports it. context, these guiding principles app/api:

  • free: not want charge people @ use app/api.
  • open source: source code both app , api available public use wish.
  • decentralised: api service supports app can run on server, , made available use users of app.
  • anonymous: user should not have sign service, or submit personal identifying information stored alongside data.
  • secure: user's data should encrypted before being sent server, access server should have no ability read user's data.

i implement instance of api on public server selected in app default. way initial users of app can sync data straight away without needing find or set instance of api service. on time, if app popular users set other instances of api service either or make available other users of app should wish use different instance (or if primary instance runs out of space, goes down, etc). may access api in own apps. essentially, want them able have choice self sufficient , not have rely on other's providing instance on service them, reasons of privacy, resilience, cost-saving, etc. note: data in question not sensitive (i.e. financial, etc), personal.

the user's sync journey works this:

  1. user downloads app, , creates data in process of using app.
  2. when user ready sync, enter "password" in password field, used create complex key encrypt data. password stored locally in plain text never sent server.
  3. user clicks "sync" button, data encrypted (using password) , sent specified (or default) api instance , responds giving them unique id saved app.
  4. for future syncs, data encrypted locally using saved password before being sent api along unique id updates synced data on server.
  5. when retrieving synced data, unique id sent api responds encrypted data. locally stored password used decrypt data use app.

i've implemented app in javascript, , api in node.js (restify) mongodb backend, in practice sync requests server looks 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. 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" } 

their data in mongodb this:

{     "id":"507f191e810c19729de860ea",     "data":"dwcx6wr9ggpqprrhu4o4oln5p09onapoaulx4xt+ckxswtfnh/qq+y/rgxdu+8+8/muo4jo/jknhsssezvjq6apvyk+eazaormxenaguwhojbiaxfqf8gscbbulrlf0mstkn/puiyfnvjd...",     "lastupdated":"2016-07-06t13:21:23.837z" } 

encryption implemented using cryptojs's aes implementation. app provides user's password passphrase aes "encrypt" function, generates 256-bit key which encrypt user's data, before being sent api.

that sums sync process, it's simple needs secure , reliable. concerns are:

  • as mongodb objectid easy guess, possible malicious user request else's data (as per step 2. sync data) guessing id. however, if successful retrieve encrypted data , not have key decrypt it. same applies has access database on server.
  • given above, cryptojs aes implementation secure enough in real possibility user's encrypted data retrieved malicious user, not realistically able decrypt data?
  • since api open , doesn't audit or check submitted data, potentially submit data wish stored in service, example:

post body:

{     "data":"this anyold data..." } 

is there practical can guard against whilst adhering guiding principles above?

  • general abuse of service such users spamming initial syncs (step 1 above) on , on fill space on server; or user's using disproportionately large amounts of server space. i've implemented features guard against this, such logging ips initial syncs 1 day (not kept longer that) in order limit single ip set number of initial syncs per day. i'm limiting post body size syncs. these options configurable in api however, if user doesn't these limitations on public api instance, can host own instance , tweak settings liking.

so that's it, appreciate has thoughts or feedback regarding approach given guiding principles. couldn't find examples other apps have attempted similar approach, if knows of , can link them i'd grateful.

i can't comment on whether specific aes algorithms/keys secure or not, assuming (and keys generated properly), should not problem if other users can access encrypted data.

you can maybe protect against abuse, without requiring other accounts, using captchas or similar guards against automatic usage. if require catcha on new accounts, , set limits accounts on data volume , call frequency, should ok.

to guard against accidental clear-text data, might generate secondary key each account, , check on server public secondary key whether messages can decrypted. this:

data = secondary_key(user_private_key(cleartext)) 

this way data encrypted, , in worst case server able read it, others wouldn't.

a few comments api :) if you're using http , post, don't need id. post returns uri points created data. can get uri, or put change:

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

response:

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

to change it:

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

you don't have way, might easier implement on client side, , maybe caching , cache invalidation.


Comments

Popular posts from this blog

Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12:test (default-test) on project.Error occurred in starting fork -

windows - Debug iNetMgr.exe unhandle exception System.Management.Automation.CmdletInvocationException -

configurationsection - activeMq-5.13.3 setup configurations for wildfly 10.0.0 -