Encrypting the client side local storage data using Angularjs - angularjs

I have a client side data storing in the localStorage. For security reasons i want to encrypt the data. Is there any way to encrypt/decrypt the client data(not server data) using Angularjs?
$scope.accountObj = {
isErrorMsg:false,
isReadonly:false,
createAccountErr:false
};

You could use cryptojs library for encrypting/decrypting your data. First you should generate some key to use in encryption process:
var secretKey = 'your-secret-key';
Then you need method to store and claim data:
store : function (key, value) {
var encryptedData = CryptoJS.AES.encrypt(angular.toJson(value), secretKey).toString();
window.localStorage.setItem(key, encryptedData);
},
get : function (key) {
var encryptedData = window.localStorage.getItem(key);
if (!_.isNull(encryptedData))
return angular.fromJson(CryptoJS.AES.decrypt(encryptedValue, secretKey).toString(CryptoJS.enc.Utf8));
return null;
}
The only problem here is that secret key is stored on the client side and it's kind of breaking logics of such encryptions.

These are probably the best out of the box solutions available for cryptography in Javascript until now.
https://www.w3.org/TR/WebCryptoAPI/
https://crypto.stanford.edu/sjcl/
However, you will probably wanna avoid cryptography on the browser if "security" is a concern and seeing as you don't trust the client machine with your localStorage.

Related

How to generate SAS token for Azure blob container in Angular?

I am generating SAS (shared access signature) token for my Azure blob containers with private access level using .net core application and it is working fine.
Code:
private static string GetContainerSasUri(CloudBlobContainer container, string storedPolicyName = null)
{
string sasContainerToken;
if (storedPolicyName == null)
{
SharedAccessBlobPolicy adHocPolicy = new SharedAccessBlobPolicy()
{
SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-1),
SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(2),
Permissions = SharedAccessBlobPermissions.Read
};
sasContainerToken = container.GetSharedAccessSignature(adHocPolicy, null);
}
else
sasContainerToken = container.GetSharedAccessSignature(null, storedPolicyName);
return container.Uri + sasContainerToken;
}
Now I want to do the same using Angular (generating SAS tokens). I've googled it and found some links but none of them explain this in detail. Is there anyway to do this?
Now I want to do the same using Angular (generating SAS tokens). I've
googled it and found some links but none of them explain this in
detail. Is there anyway to do this?
Simple answer is no, you can't create SAS tokens from a client-side library like Angular. Well, technically you can but creation of SAS tokens require storage account key and creating it from the client side would mean that you would be exposing your storage account key to everyone who's using your application.
Better option would be to make an API call to your back-end service and have that service create a SAS token for you. That way you can keep your account key safe.

Is it safe to access Elasticseach from a client without going through an API server?

For example, suppose you embed the following Javascript code in Vue.js or React.js.
var elasticsearch = require ('elasticsearch');
var esclient = new elasticsearch.Client ({
host: 'Elasticsearch host name of Elascticsearch Cloud's(URL?')
});
esclient.search ({
index: 'your index',
body: {
query: {
match: {message: 'search keyword'}
},
aggs: {
your_states: {
terms: {
field: 'your field',
size: 10
}
}
}
}
}
).then (function (response) {
var hits = response.hits.hits;
}
);
When aiming at a search engine of an application like stackoverflow,
if only GET from the public is OK by using the ROLE setting of the cloud of Elasticseach,
Even though I did not prepare an API server, I thought that the same thing could be realized with the above client side code,
Is it a security problem? (Such as whether it is dangerous for the host name to fall on the client side)
If there is no problem, the search engine response will be faster and the cost of implementation will be reduced,
I wondered why many people would not do it. (Because sample code like this can not be seen on the net much)
Thank you.
It is NOT a good idea.
If any client with a bit of programming knowledge finds our your ElasticSearch IP address, you are screwed, he could basically delete all the data without you even noticing.
I have no understanding about XPack Security, but if you are not using that you are absolutely forced to hide ES behind an API.
Then you also have to secure you ES domain to allow access only from the API server and block the rest of the world.

Having trouble converting a complex javascript object to a query string

Here is the javascript object I'm trying to convert to a query string
{$and: [{topic: categoryIds} , {$or :[ {'groups 1': {$ne: ''}}, {groups: $scope.myGroups}]}]};
Basically I'm looking to match a topic that equals a categoryIds and grab documents that have an empty groups array or that the groups array has values and matches one in the array $scope.mygroups
My question is what would be best practice to convert this in an easily parseable format so I can append it to a GET request, and how would you go about parsing it on the express server.
I am using this code in production for querying against a server with a MongoDB backend (using angular and lodash):
.factory('mongoQuery', function() {
return {
fromJson: function(json) {
return JSON.parse(json, fromJsonReviver);
},
toJson: function(object) {
return JSON.stringify(object, toJsonReplacer);
}
};
function fromJsonReviver(key, value) {
var val = value;
if (_.isPlainObject(value)) {
if (_.isNumber(value.$date)) {
val = new Date(0);
val.setUTCMilliseconds(value.$date * 1000);
} else if (_.isString(value.$regexp)) {
var match = /^\/(.*)\/([gimy]*)$/.exec(value.$regexp);
val = new RegExp(match[1], match[2]);
}
}
return val;
}
function toJsonReplacer(key, value) {
var val = value;
if (_.isPlainObject(value)) {
val = _.extend({}, value);
for (var k in value) {
val[k] = toJsonReplacer(k, val[k]);
}
} else if (_.isDate(value)) {
val = {$date: (new Date(value)).valueOf() / 1000};
} else if (_.isRegExp(value)) {
val = {$regexp: value.toString()};
}
return val;
}
})
It includes many of the suggestions mentioned by others in the comments and supports dates and regular expressions.
Other than that, if you need to send the query with a GET request, just use encodeURIComponent like others have mentioned.
Here is a working example: http://plnkr.co/edit/b9wJiUkrHMrDKWFC1Sdd?p=preview
What you're thinking here is basically to redevelop an API server, coupled with some mongodb database, and querying it with some format.
REST is the "best practise" you're looking for. It's a standard that encapsulates some common actions to http ressources.
You should know that you don't need to redevelop an ecosystem based on such a standard. Full-featured REST API servers exist, some are even based on express.js. Loopback and sails.js. These one provide some extra features like
Model abstraction through ORM's, and database-engine agnostism
Automatic REST actions, from database schema or model finition
Advanced querying through "extended REST" ("where", "limit", "order", ...)
Realtime with REST-like websockets
Client side libraries that help you query the server
Some standalone exernal libraries, such as js-data or Restangular can deal with REST server pretty well, and act as a frontend connector to backend
Now, if I had to purely answer your question, and if you realy wanted to go with your solution, I'd just add the mongo query to a where query param on the http call with encodeURIComponent as stated before.

Modify request object in Slim framework

I am developing a small REST app in slim framework. In that, users password is send as encrypted in the request body as xml or json. I want to de-crypt that password in a callable function and update the request body so that in the actual call back function we can validate the password without de-cryptng. I want to do those steps as follows:
$decrypt = function (\Slim\Route $route) use ($app) {
// Decrypt password and update the request body
};
$update = function() use ($app) {
$body = $app->request()->getBody();
$arr = convert($body);
$consumer = new Consumer($arr);
if ($consumer->validate()) {
$consumer->save();
$app->response()->status(201);
} else {
.....
}
}
$app->put('/:consumer_id', $decrypt, $update);
We can modify the body like following way:
$env = $app->environment;
$env['slim.input_original'] = $env['slim.input'];
$env['slim.input'] = 'your modified content here';
Courtsey: ContentTypes middleware
You say you want decrypt the password and update the request body. If you're encrypt the password at client side, i would rather decrypt the password in a server side layer like API service (or something that consume the business layers like a controller in mvc).
I do believe that this decryption process should belong to your application instead of doing it outside before consuming your code. I don't know how you encrypt but if you use server side programming to generate a new hash in those requests, for me that's even a better reason to do it inside the library.
That's how i handle this type of tasks, i try to use only the frameworks for consuming libraries and not handling any logic.
However if you want to do this, you could transform the request body and save it in a new location for services that need to decrypt the password.
I use Middleware for almost every code i need to write specifically to Slim layers. I only passe functions consuming classes that act as API layers and are abstracted from Slim. For your case, use a Middleware to keep this logic in his own place.
class DecriptPasswordRequest extends \Slim\Middleware
{
public function call()
{
$decriptedRoutes = array('login', 'credentials');
$app=$this->app;
$container = $app->container;
$currentRoute = $app->router()->getCurrentRoute();
if ($app->request->getmethod() == 'POST' && in_array($currentRoute, $decriptedRoutes){
$body = $app->request->post();
if (!isset($body['password'])){
throw new Exception('Password missing');
}
$provider = new ClassThatDecryptPassword();
$body['password'] = $provider->decrypt($body['password']);
}
$container['bodydecripted'] = $body;
$this->next->call();
}
}

ExtJs Model Proxy vs. Store Proxy

OK, I'm stuck on what should be a basic task in ExtJs. I'm writing a simple login script that sends a user name and password combination to a RESTful web service and receives a GUID if the credentials are correct.
My question is, do I use a Model Proxy or a Store Proxy?
To my understanding, Models represent a single record, whereas Stores are for handling sets of data containing more than one record. If this is correct then it would seem that a Model proxy is the way to go.
Following Sencha's documentation at http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.data.Model the code would look something like this:
Ext.define('AuthenticationModel', {
extend: 'Ext.data.Model',
fields: ['username', 'password'],
proxy: {
type: 'rest',
url : '/authentication'
}
});
//get a reference to the authentication model class
var AuthenticationModel = Ext.ModelManager.getModel('AuthenticationModel');
So far everything is OK, until the next step:
//Use the configured RestProxy to make a GET request
AuthenticationModel.load('???', {
success: function(session) {
console.log('Login successful');
}
});
The load() method for the Model class is a static call expecting a single unique identifier. Logins typically depend upon two factors, username and password.
So it appears Store proxies are the only way to validate someone's username and password credential combination in ExtJS. Can someone verify and explain? Any help to understand this would be greatly appreciated.
You just need to know the following:
The store will use it's own proxy if you configured one for this
instance and if not he takes the proxy from the model.
So you can easily go with two proxy configurations to enable the multi-CRUD operations on the store and the single-CRUD operations on the Models. Note the the static load method of the Model expects the model id because it is supposed to load a model by just one Id (yes, composite keys are not supported). You will also have to fetch the model instance in the callback (As you did).
Back to your Username/password problem
You may apply your session Model with a custom 'loadSession' method
loadSession: function(username,password, config) {
config = Ext.apply({}, config);
config = Ext.applyIf(config, {
action: 'read',
username: username,
password: password
});
var operation = new Ext.data.Operation(config),
scope = config.scope || this,
callback;
callback = function(operation) {
var record = null,
success = operation.wasSuccessful();
if (success) {
record = operation.getRecords()[0];
// If the server didn't set the id, do it here
if (!record.hasId()) {
record.setId(username); // take care to apply the write ID here!!!
}
Ext.callback(config.success, scope, [record, operation]);
} else {
Ext.callback(config.failure, scope, [record, operation]);
}
Ext.callback(config.callback, scope, [record, operation, success]);
};
this.getProxy().read(operation, callback, this);
}
Now call this instead of load.
I found it in the documentation of sencha App Architecture Part 2
Use proxies for models:
It is generally good practice to do this as it allows you to load and
save instances of this model without needing a store. Also, when
multiple stores use this same model, you don’t have to redefine your
proxy on each one of them.
Use proxies for stores:
In Ext JS 4, multiple stores can use the same data model, even if the
stores will load their data from different sources. In our example,
the Station model will be used by the SearchResults and the Stations
store, both loading the data from a different location. One returns
search results, the other returns the user’s favorite stations. To
achieve this, one of our stores will need to override the proxy
defined on the model.

Resources