How to pass mongodb ObjectId() in HTTP request JSON body? - json

I need to send a mongo query in JSON typed request body, something like:
{ _id : { $gt : ObjectId("575d0c22964ddb3b6ba41bed") } }
(to get records inserted later than the id'ed record)
On the node server side I have express with body-parser middleware. It won't parse the request body JSON unless everything is quoted. E.g. the above has to be like:
{ "_id" : { "$gt" : "ObjectId(\"575d0c22964ddb3b6ba41bed\")" } }
The db runs the query with all the quotation marks and returns nothing.
How do I pass ObjectId() to mongodb as a function without re-parsing the whole request body and stripping off the quotation marks?
I'm testing with postman extension in Chrome, and sends the request to a REST url: /api/:obj_type/list.
The entire request body is used as a query.

you would be only passing around the string value in the client and server until a request is made the the database at which point you would make it a new ObjectID with the same value to be passed into the db. Passing around a string is a bit easier as all the clients/server know how to deal with a string vs ObjectID - also passing the ObjectID in a URL would be an issue. - To answer your question on how to pass the ObjectID() to Monogdb without re-parsing. You really wouldn't unless I'm misunderstanding the context
but pass around the ID as a string so it would be something like var stringId = "507f1f77bcf86cd799439011" and when you are about do a query you would do something along the lines of col.find({_id: new ObjectId(stringId)}).toArray(function(err,results){});

Related

Rest API -> passing json string as parameter value

Is it the recommended way to pass a JSON string as a parameter value in a REST API?
This is the data which I am trying to send :
http://127.0.0.1:8000/v1/product/?productName=&metrics={"memory":2,"disk_space":10}
Here, is it ok to pass the value of metrics as JSON value?
Initially, I tried passing the metrics JSON value in the body. As it is not supported/recommended standard I have removed it.
Is it the recommended way to pass a JSON string as a parameter value in a REST API?
REST is an architectural style and it doesn't enforce (or even define) any standards for passing JSON string as a parameter value.
If you want to send JSON in the query string, you must URL encode it first:
/v1/products?productName=&metrics=%7B%22memory%22%3A2%2C%22disk_space%22%3A10%7D
Alternativelly, you could redesign the parameters to be like:
/v1/products?productName=&metrics.memory=2&metrics.diskSpace=10
If the URL gets too long (or the query gets too complex to be expressed in the query string), you may want to consider POST instead of GET, and then send the JSON in the request payload:
POST /v1/products/search HTTP/1.1
Host: example.com
Content-Type: application/json
{
"productName": "foo",
"metrics": {
"memory": 2,
"diskSpace": 10
}
}
Sending JSON values in GET request is not recommended. You can do it but metrics json can be long and anybody can read the content.
You should use POST request to send parameters such as productName and metrics in the body.
You should refer to this answer for detailed explanation.
For use Content-Type Application Json Please use below line
request.AddParameter("application/json", "{\n\t\"lastName\":\"gaurav.sablok#agarwalpackers.com\"\n}", ParameterType.RequestBody);
This is used with "RestSharp" name spaces

Make a JSON object Without Quotes on the beginning and end of the string

I'm using React and fetch, and I'm trying to send a JSON string to a client's web service, they are expecting an object like this:
{
"id":"1",
"plan_id":"6",
"plan_start_date":"2017-08-02",
"months":"1",
"extra_hours":"4",
"attendees":"1",
"mails":"",
"shopping_cart_id":"0"
}
However, whenever I use JSON.stringify() to generate the JSON string, the result is something like this:
"{
"id":"1",
"plan_id":"6",
"plan_start_date":"2017-08-02",
"months":"1",
"extra_hours":"4",
"attendees":"1",
"mails":"",
"shopping_cart_id":"0"
}"
So when the request is sent, I get back an error stating that the object is not valid.
Is there a way to send the object like on the first example? I've tried manually building the object, but I can't get the key's names to stay in quotes.
EDIT: The code for the call is here:
addToCart(plan) { //Plan is the object with the previous example's structure
fetch("http:ClientWS", {
method: "POST",
body: JSON.stringify(plan) //Produces the "{}" issue
})
.then(response => response.json())
.then(json => {
//Read the response info, here it tells me that the value for 'id' is invalid
console.log(json.datos);
}).catch(function(ex) {
console.log(ex);
});
}
JSON.stringify() does not add extra quotes around the output. If you are seeing those extra quotes, I would say that it implies that the error is somewhere else.
That's because JSON.stringify takes your object and outputs a string variable by concatenating all the properties and values together and inserting some separators. And a string is displayed in quotes, again because it's a string. It's not an object any more. When you send it to the server, the server will see it as a single string value. The fact that the content of the string happens to look like JSON is not taken into consideration.
You do know that JSON and JavaScript objects are essentially the same thing? The stringified JSON that you can see is just a human-readable version of the object structure. It also turns out to be a convenient format in which to serialise objects (from all languages not just JS) for transmission in a HTTP request (or storage in a file or database, among other uses).
So actually when you send your object to the server, do just that - send the object. If you're doing it via ajax, the JS code you're using will generally serialise it for transmission on your behalf. You may have to set the correct content type header. That serialised object inside the HTTP request's body will end up looking a lot like the output of JSON.stringify (if you viewed it in your browser's network tab, for instance), except it won't actually be a string, and the server will interpret it correclty as an object containing multiple properties.

Accessing data from API json response. Arrays? Laravel

I am trying to access the steamid data in a json response returned by an API, specifically the Steam API.
The responses look like this:
I've made it return json but why do I see array all over the place?
How would I access the steamid data? I'm getting a bit confused as I thought this would be json.
I'm using guzzle to get the data and converting it to json using the guzzle json() method:
Any help would be appreciated.
Thanks!
The API is indeed using JSON to send/receive , however JSON is just a string, so in order to use that data PHP must parse it, which is automatically handled by guzzle, so as soon as you get the data back it has automatically decoded the data into a usable format for yourself.
It does this using the json_encode() and json_decode() functions.
You'd be able to access the steamid with the following.
// Assuming $data is your response from the API.
$players = array_get($data, 'response.players', []);
foreach($players as $player)
{
$steamId = array_get($player, 'steamid', null);
}
Using the laravel helper array_get() function is a great way of ensuring you return a sane default if the data doesn't exist as well as eliminating the need to keep doing things like isset() to avoid errors about undefined indexes, etc. http://laravel.com/docs/5.1/helpers
Alternativly not using the laravel helpers you could use something similar to below, although I'd advise you add checks to avoid the aforementioned problems.
foreach($data['response']['players'] as $player)
{
$steamId = $player['steamid'];
}
If you didn't want guzzle to automatically decode the API's JSON I believe you should just be able to call the getBody() method to return the JSON string.
$json = $response->getBody();

How to use JSON Sanitizer at Server Side?

I want to implement the 'JSON Sanitizer' validation as mentioned by OWASP.
My understanding is that this needs to be done in two places:
JSON data (in Request) received from Client or Other Systems - This needs to be sanitized at Server side before being processed
JSON data (in Response) to be sent to Client - This needs to be sanitized at Server side before being sent to client
Is it sufficient that I just call a sanitizing method in JSON
Sanitizing library on that JSON Data ?
Will that perform all sanitization or are there any other validations to be done in this regard ?
The OWASP JSON Sanitizer converts JSON-like input to syntactically valid & embeddable JSON.
It is typically used to take “JSON” produced by ad-hoc methods on the server like
"{ \"output\": " + stringOfJson + " }"
and make sure it's syntactically valid so that it can be passed to JSON.parse on the client, and embeddable so that it can be embedded in a larger HTML or XML response like
<script>var jsonUsedByScriptsOnPage = {$myJson};</script>
You can definitely use it on your server if your clients are likely to send dodgy JSON.
Note that your server still needs to treat the JSON as untrusted just as it would any other string it receives in a response that does not arrive with valid credentials.
https://github.com/OWASP/json-sanitizer#security explains
sanitizing JSON cannot protect an application from Confused Deputy attacks
var myValue = JSON.parse(sanitizedJsonString);
addToAdminstratorsGroup(myValue.propertyFromUntrustedSource);
The OWASP JSON Sanitizer doesn't cope with quotes screening - it splits string into several fields instead. So I've written own sanitize method, quite primitive though - if you see any security caveats, I'm open to suggestions, please share.
/**
* Helper methods to validate data.
*/
#UtilityClass
public class ValidationUtils {
/**
* Removes disallowed symbols from string to prevent input injection.
* #param input User input with possible injection.
* #return Value without injection-sensible symbols.
*/
public String sanateInjection(String input){
return input.replaceAll("[^A-Za-z0-9 ]", "");
}
}
I want to know whether some json string contains <script> tags which can later be used to execute dynamic content. But since the return value of the sanitize()method would escape it there is no way to detect whether something like that is in there. So the following works for me:
public static String checkJsonForScripts(String input) {
if (!JsonSanitizer.sanitize(input).equals(input)) {
log.error("Problematic string found" + input);
throw new YourException(...);
}
return input;
}

Wrapping JSON payload with key in EmberJS

Ok basically I am sending a POST request with some JSON payload in it to Codeigniter. I use RESTAdapater. JSON get sent there with no key, so I have no access to it.
Here is model:
App.Bookmark = DS.Model.extend({
title: DS.attr("string"),
url : DS.attr("string")
});
Here is controller:
App.BookmarksNewController = Ember.ObjectController.extend({
save: function(){
this.get("model.transaction").commit();
this.get("target").transitionTo("bookmarks");
}
});
In REST implementation in CI that I use standard way to access the post request is $this->input("key"). But when the above request is generated, only raw JSON data is sent. Therefore I don't seem to have a way to reference it in any way.
Take this example:
function post(){
$this->response(var_dump(file_get_contents("php://input")),200);
}
Gives me this output:
string(48) "{"bookmark":{"title":"sdffdfsd","url":"sdfsdf"}}"
what I would like to see is:
string(48) payload="{"bookmark":{"title":"sdffdfsd","url":"sdfsdf"}}"
Then is server I would be able to access this JSON with something like $this->post("payload").
So 1 of 2. Anyway to wrap the JSON payload with key? Or anyway to access raw JSON data in CI with no key available??
Ok figured it out myself (or rather read properly the examples).
When using Adam Whitney's fork of Phil Sturgeons REST controller for CodeIgniter the JSON payload will be available in $this->_post_args. And in the underlying implementation he uses my already mentioned file_get_contents("php://input").
EDIT: Same convention applies for other type of requests as well, for example DELETE request data will be available in $this->_delete_args. Or $this->_args is the "magic" place where all types of args can be found.