How to use JSON Sanitizer at Server Side? - json

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;
}

Related

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.

How to validate user input contains server code at server side using c#

I have a search box which allows some of special characters (+,=,#.',") to type and search, here i need to validate user input contains any server codes like
''+System.Diagnostics.Process.Start("cmd.exe","whoami")+'';)..
Use case details:
A wcf service get input as json data which need to validate before deserialize to avoid creating object when deserialize.I have added custom validation attribue with service contract using IParameterInspector. here when validate the each input fields in beforecall event i would check one field asany of server code or not.
XXS attack-Causes:
Un-sanitized Serialized JSON Data leads to Application Denial of Service (DoS)
solution:
The server must validate and filter the data in the JSON request before it de-serializes it.
Can anyone tell me how to disallow server code by adding validation for input fields?
If checking the user input right after the user hits enter is not possible you could add a Message Inspector on the client and/or service side which checks the Message before the request is processed on the server.
More details on the official site: https://learn.microsoft.com/en-us/dotnet/framework/wcf/extending/how-to-inspect-and-modify-messages-on-the-service
EDIT
You could specify an array with symbols that are not allowed and only process the rquest if the index is , e.g.
if(input.IndexOfAny(new char[] { '+', '!', '\\', '&' })==-1)
{
...
}
You can also specify a List of strings with words or just symbols that are not allowed
i.e.
List<string> words = new List<string>();
words.Add("WhoAmI");
words.Add("&");
bool badWordDetected = words.Any(w => input.Contains(w));
I would also recommend to convert the input to upper or lower case so that the check can be case invariant.

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

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){});

Accept only number formats for a property from JSON

I am developing ASP.Net Web API application and we are exposing a REST API for different clients. I have a problem when taking users' JSON files and converting them to Data Model classes. My JSON looks like below.
{"engagementid":1,"clientname":"fsdfs","myno":"23,45","address1":"fsd","address2":"fsdfs","city":"fsdfs","zip":"fsdf","info":"fsdfs","country":"fsdfs","currency":"NOK"}
You can see that my "myno" is sent as a string. But in my Server Data Model "myno" is a double value. So what happen here is when I send the value for "myno" as "23,45", it gets assigned to MyNo property of my Model as 2345. This is wrong, because you can see that the number has been changed because of this wrong conversion. What I simply need is to restrict this conversion. I mean, I want to send an error to Client if he sends a string for "myno" property. Since it is a double value in my Server Data Model, I want to accept only numbers from the client for this property. Which means, I want it like this.
{"myno":2345} //correct
{"myno":"2345"} //wrong. I want to send a error to user by saying, "We only accept Numbers for this value"
How do I do this?
Update:
This problem gets solved if I am using int in my server-model. I mean, if a client send a string to a property which is represented as int in my model, then it gives an error to user by saying string to int conversion can not be done.
I don't whether it is correct or not. I am just telling my suggestion according to my experience. Why can't you create a custom validation attribute and check the datatype of data.
public class IsNumberAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext context)
{
if(value.GetType() != Int)
return new ValidationResult("Only Numbers Allowed");
return null;
}
}

Is it valid to define functions in JSON results?

Part of a website's JSON response had this (... added for context):
{..., now:function(){return(new Date).getTime()}, ...}
Is adding anonymous functions to JSON valid? I would expect each time you access 'time' to return a different value.
No.
JSON is purely meant to be a data description language. As noted on http://www.json.org, it is a "lightweight data-interchange format." - not a programming language.
Per http://en.wikipedia.org/wiki/JSON, the "basic types" supported are:
Number (integer, real, or floating
point)
String (double-quoted Unicode
with backslash escaping)
Boolean
(true and false)
Array (an ordered
sequence of values, comma-separated
and enclosed in square brackets)
Object (collection of key:value
pairs, comma-separated and enclosed
in curly braces)
null
The problem is that JSON as a data definition language evolved out of JSON as a JavaScript Object Notation. Since Javascript supports eval on JSON, it is legitimate to put JSON code inside JSON (in that use-case). If you're using JSON to pass data remotely, then I would say it is bad practice to put methods in the JSON because you may not have modeled your client-server interaction well. And, further, when wishing to use JSON as a data description language I would say you could get yourself into trouble by embedding methods because some JSON parsers were written with only data description in mind and may not support method definitions in the structure.
Wikipedia JSON entry makes a good case for not including methods in JSON, citing security concerns:
Unless you absolutely trust the source of the text, and you have a need to parse and accept text that is not strictly JSON compliant, you should avoid eval() and use JSON.parse() or another JSON specific parser instead. A JSON parser will recognize only JSON text and will reject other text, which could contain malevolent JavaScript. In browsers that provide native JSON support, JSON parsers are also much faster than eval. It is expected that native JSON support will be included in the next ECMAScript standard.
Let's quote one of the spec's - https://www.rfc-editor.org/rfc/rfc7159#section-12
The The JavaScript Object Notation (JSON) Data Interchange Format Specification states:
JSON is a subset of JavaScript but excludes assignment and invocation.
Since JSON's syntax is borrowed from JavaScript, it is possible to
use that language's "eval()" function to parse JSON texts. This
generally constitutes an unacceptable security risk, since the text
could contain executable code along with data declarations. The same
consideration applies to the use of eval()-like functions in any
other programming language in which JSON texts conform to that
language's syntax.
So all answers which state, that functions are not part of the JSON standard are correct.
The official answer is: No, it is not valid to define functions in JSON results!
The answer could be yes, because "code is data" and "data is code".
Even if JSON is used as a language independent data serialization format, a tunneling of "code" through other types will work.
A JSON string might be used to pass a JS function to the client-side browser for execution.
[{"data":[["1","2"],["3","4"]],"aFunction":"function(){return \"foo bar\";}"}]
This leads to question's like: How to "https://stackoverflow.com/questions/939326/execute-javascript-code-stored-as-a-string".
Be prepared, to raise your "eval() is evil" flag and stick your "do not tunnel functions through JSON" flag next to it.
It is not standard as far as I know. A quick look at http://json.org/ confirms this.
Nope, definitely not.
If you use a decent JSON serializer, it won't let you serialize a function like that. It's a valid OBJECT, but not valid JSON. Whatever that website's intent, it's not sending valid JSON.
JSON explicitly excludes functions because it isn't meant to be a JavaScript-only data
structure (despite the JS in the name).
A short answer is NO...
JSON is a text format that is completely language independent but uses
conventions that are familiar to programmers of the C-family of
languages, including C, C++, C#, Java, JavaScript, Perl, Python, and
many others. These properties make JSON an ideal data-interchange
language.
Look at the reason why:
When exchanging data between a browser and a server, the data can only
be text.
JSON is text, and we can convert any JavaScript object into JSON, and
send JSON to the server.
We can also convert any JSON received from the server into JavaScript
objects.
This way we can work with the data as JavaScript objects, with no
complicated parsing and translations.
But wait...
There is still ways to store your function, it's widely not recommended to that, but still possible:
We said, you can save a string... how about converting your function to a string then?
const data = {func: '()=>"a FUNC"'};
Then you can stringify data using JSON.stringify(data) and then using JSON.parse to parse it (if this step needed)...
And eval to execute a string function (before doing that, just let you know using eval widely not recommended):
eval(data.func)(); //return "a FUNC"
Via using NodeJS (commonJS syntax) I was able to get this type of functionality working, I originally had just a JSON structure inside some external JS file, but I wanted that structure to be more of a Class, with methods that could be decided at run time.
The declaration of 'Executor' in myJSON is not required.
var myJSON = {
"Hello": "World",
"Executor": ""
}
module.exports = {
init: () => { return { ...myJSON, "Executor": (first, last) => { return first + last } } }
}
Function expressions in the JSON are completely possible, just do not forget to wrap it in double quotes. Here is an example taken from noSQL database design:
{
"_id": "_design/testdb",
"views": {
"byName": {
"map": "function(doc){if(doc.name){emit(doc.name,doc.code)}}"
}
}
}
although eval is not recommended, this works:
<!DOCTYPE html>
<html>
<body>
<h2>Convert a string written in JSON format, into a JavaScript function.</h2>
<p id="demo"></p>
<script>
function test(val){return val + " it's OK;}
var someVar = "yup";
var myObj = { "func": "test(someVar);" };
document.getElementById("demo").innerHTML = eval(myObj.func);
</script>
</body>
</html>
Leave the quotes off...
var a = {"b":function(){alert('hello world');} };
a.b();