Rest Web Services Security - best practices


I`m trying to explore as well the web version of XOJO, and recently i found that i need some kind of rest service to avoid using that 3306 remote connection which is a security issue, all good until now.

The issue is the data encrypting part and the way to handle it. I will implement a ssl only session but the problem is the data itself and the authentication method,

I have some php api that uses an email and password to authenticate, then once authenticated gets an unique token and the transactions are done with that , but still i was thinking to encrypt the json data with the framework crypto library , hopefully that works on web as well so either pbkdf2 or rsa but the issue comes with the length and the limitation of the string, is there a limit on the rest payload ? what i know is that on php you can set this payload.

If i would use a token based and let`s say transpose the current api into a xojo web app it will be enought ? and how i should proceed ?

As far as i know i have to use either /special or /api then i guess i`ll have to split the chunk of the url separated by “/” get the token and do all the logics, or it is a better way ?

I can use some kind of authentication from the framework side?

Any ideas or point to start are more than welcomed, i`m starting my quest based on this link

As well for the rest service you recommend sqlite database with wal and encryption or an mysql database ? i prefer the fist one but i`m not obliged to stick on it.

Thanks again .

Howdy there. I’m not an expert, but I’m working on a very similar project.

[quote=253583:@Aurelian Negrea]
As far as i know i have to use either /special or /api then i guess i`ll have to split the chunk of the url separated by “/” get the token and do all the logics, or it is a better way ?[/quote]

The HandleURL allows for any identifier after the first /. It could be called /magic.

I handle mine like:

Select Case Request.Path Case "search" // If Request.QueryString <> "" Then Do success blah (Send Request.QueryString to Method/Function) Else Do fail blah. End If Return True Case "other" // requires a POST Do success blah. End Select // Nothing else to do, just fail blindly. Return False

And yes, you’ll probably have to split the chunks up as you described. I do that similar to this way:

Search method(Query as String):

Dim queryarray() as String = Query.Split("&") For i as Integer = 0 to queryarray.Ubound blah() = queryarray(i).Split("=") If blah.Ubound = 1 Then d.value(blah(0)) =blah(1) Else WriteLog(randString, "Incorrect query strings: Missing stuff after = sign, " + queryarray(i)) Return ReturnJSONMsg("error", randString +" - Incorrect query strings: "+randString) End If Next i

Basically the query string is split by & instead of /, but obviously works either way. Then is further split by the =. This should be familiar since you’re from php. It works however you want it to, this is just the way I do it.

You might want to check out Luna, an open-source REST framework for Xojo.

I’ll be talking a bit about Luna and web services in the March 22 webinar.

Of course you can do whatever you feel that you need to do but if this is going to be an API for others to develop with then adding your own encryption on top of SSL will deny users the ability to use browsers and other tools to explore and work with your API. If it is a private API then do you really need to use a RESTful approach?

To ‘do’ REST properly is more than just receiving and sending across HTTP(S), the urls need to be designed so that they make sense for each verb and to the consumers as well as the application. Also the authentication mechanism should be separate from the API so the token/basic auth/etc would travel in the header rather than the url.

I will be interested to view Paul’s webinar and see how Luna deals with REST and maybe try Xojo for an API myself. Some languages/frameworks make it easy to structure your API (I use .NET/WebAPI and have used Ruby/Sinatra) but underneath the layers that they provide there is still something simple and somewhat raw like Xojo’s HandleURL and so a good framework could make this easy in Xojo.

Just FYI - That’s not entirely true. We do reserve a few of the top level urls for ourselves. Look here for more info.

Thanks guys, The Luna project sound promising, i`ll have to look into it .

Regarding the Crypto, i have few in mind, and actually, 4 api`s are used internally only or only between the apps so no need for publicity, one indeed will be used for public so indeed it will have to be properly made.

I wanted to try XOJO to see how it handles the requests and what is the limit on hardware/software part, if its to much im thinking php will handle it way better and maybe more efficient, the advantage on Xojo is closed code so you can, in a way protect your code little bit better then you doit on other frameworks, but we will see.

I`ll have a look on Luna to see how it goes, so far i see only the HandleURL and not the HandleSpecialURL is used so i guess in a way gives you more flexibility.

Regarding the versioning , why not use url versioning and it is used like that ? is there a special reason ? for example rest . I just saw the api now so i guess it is used this way.

And what you recommend in case of multiple APIs lets say, it is recommended to use only one build to handle all or to make a different app for each api ?

Thanks again.

It can be dangerous to generalise, especially without me knowing what you are trying to achieve, but to try and give you some thoughts and ideas.

Traditional library and framework APIs are often organised by functional areas and the functions names include verbs and nouns about what they do, so for example the Graphics library/namespace has a GetPixel() method. REST APIs should really take a different approach and be organised by resources for which the URIs are ‘representations’. The resources are your data whether that is coming from a database, a file store, a device, etc.

You will often see examples URIs along the lines of:

GET /product/5 --returns the details of a product id == 5
GET /photo/74 – returns the url for photo id == 74
GET /photos/tags/beach --returns a list of photos tagged with the word ‘beach’

Suppose we were providing a REST API for graphics (not a good practical example but it serves to contrast with a library API)

GET /screen/1/pixel/0/0 --returns the value of pixel x=0, y=0 for screen 1
GET /photo/74/pixel/0/0 --returns the value of pixel x=0, y=0 for photo id = 74

and to set a pixel we would use the same URIs with a HTTP PUT verb with the value in the body.

So back to your question, use one build or different? Well don’t think about functional areas, REST is different, think about your resources and how they are organised. Also do you have different domains and sub domains available to organise your resources by? If so then you can direct the different (sub) domains to different applications but if not then you are going to make things harder for your users and less flexible for the infrastructure people.

Another tip - when designing your URIs be careful so ensure that they are ‘clean’ and that there is no meaningless or unnecessary information in them. Versioning is often necessary and if you are operating with a domain that is used for a website then including something like /api is useful. Some examples:

/api/v1/product/5 --good
/api/v1/admin-users-only/product/5 --not good, restricting access should be done through authorisation
/api/v1/management/product/5 --probably not good if it returns the same as /api/v1/product/5 as it adds no value --we already know it is bing from the domain and the verb would specify ‘get’

Once you have figured out your resources (data) and their representations (URIs) you have done the most important part - the remainder is just how to code it.

Aurelian -

Let me know if you get a chance to check out Luna and have any comments or questions about it.

Also, in terms of “best practices,” I highly recommend Vinay Sahni’s “Best Practices for Designing a Pragmatic RESTful API.” You can find that here:

I’m not sure I understand why you need encryption on top of an SSL connection? The SSL connection is negotiated first, before any other data is sent back and forth. Once you have an SSL connection then any other tokens or user id/passwords that you send will already be encrypted so no further encryption should be necessary. It will just slow things down and add layers of complexity.

It’s also possible I totally misunderstood what you’re doing :wink:

One reason could be that SSL only provides encryption while the data is transported, the OP may need to protect the data once it has been received so that only specific application(s) can decrypt it.

double encryption is a valid way to increase the security of a piece of data, but make sure to read the wiki article on it so that you understand the pitfalls, don’t use the same encryption type for both or the same key for 2 different ones and such things as that can make it less secure and not more.

If you’re concerned about the unencrypted data showing up in a memory dump or something then keeping it encrypted in memory will make that more difficult, but you’ve still got to decrypt it to use it. If you’re just going to save it to a local file or data store of some kind then re-encryption could be done then with a locally stored key.

Thanks guys, that was a good info, i saw recently Paul`s webinar and i see what luna can do so my first option will be to have a look there.

As for the security part, some parts are normal data and i can deal with ssl and Auth and some datas are quite private and mostly medical data so i have to be careful how i handle those, that was the reason why i asked best practices on security .

One more question, how reliable is sqlite db on web services with multi users . i should or i should not use sqlite db as a backend ?
I saw Paul said something about timestamps as a reference control so i was thinking in using sqlite db with wal still have to see if it`s worth it or i still have to rely on mysql or postgres

[quote=253886:@Tim Dietrich]Aurelian -

Let me know if you get a chance to check out Luna and have any comments or questions about it.

Also, in terms of “best practices,” I highly recommend Vinay Sahni’s “Best Practices for Designing a Pragmatic RESTful API.” You can find that here:[/quote]

Well so far im loving it , good job there i hope it will get mode improved in terms of databases interchangeability and security, but so far its quite nice, i`ll try to use it in one of my test apps to see how it goes.

Thanks a lot .

Having just watched the Webinar on Making Database Web Services, my biggest question coming out of it is are you able to use this over a https connection as I did not see any of the apps created using an https connection?

You can absolutely use https. Just set up your web app to use https and then use https in the URL when connecting to it.

Thanks Paul. Guess I was thinking I had to use httpsecuresocket rather than httpsocket in my client app to do that.

Yes, you need to use HTTPSecureSocket in the client to connect securely to an https url. On the server, request an ssl certificate from your hosting provider or install the cert yourself and enable https. Your server-side CGI app doesn’t need to do anything special.

If you use Xojo.Net.HttpSocket, it handles both secure and insecure connections. In the classic framework you’d use HTTPSecureSocket for secure connections.

Thanks Paul and Tim. That clarifies things immensely.

The Webinar was very interesting, it seems like Luna has taken away much of the pain of working out which method gets called etc. and the Paw app looks really good, I would really like to have something that slick for Windows.

One question came into my mind - I can see that the methods allow for versioning but how is versioning of the data handled? For a simple example V1 of an API method may return a simple contact name but as the system develops and the contact name get split into Title/Firstname/Lastname in the database V2 now returns these as separate fields but V1 still needs to return the concatenation of them as ‘name’. When I do this in .NET land I have to create versioned data models and map from database to model to return the JSON of the model or map from model to database for a PUT/POST. Is there a neat way to do this in Luna or something that I will need to add.