How do I do JSON schema validation using Apigee Edge policies? - javascript

Suppose you have the schema for valid payload defined in accordance to json-schema.org and you'd like to validate it in a proxy prior to handling the payload or passing it to backend, how can you properly validate the contents of the payload?

Apigee doesn't have a JSON schema validator built in, so your best bet is to create a Javascript something like tv4 or another javascript based validator. Then you need to create a Javascript callout which has your script to validate the Apigee flow variable and includes your library (for example, tv4.js)
<Javascript async="false" continueOnError="false" enabled="true" timeLimit="200" name="JSO- Validate-JSON">
<DisplayName>JS-Validate-JSON</DisplayName>
<FaultRules/>
<Properties/>
<ResourceURL>jsc://validatejson.js</ResourceURL>
<IncludeURL>jsc://tv4.js</IncludeURL>
</Javascript>
tv4 is available on github at https://github.com/geraintluff/tv4

To expand a bit on Michael B. response validatejson.js will be a JavaScript policy that will load the schema into schema variable, which will be validated against the response.content:
var valid = tv4.validate(response.content, schema);
if(valid){
log.info("Schema is valid!" + valid);
} else {
context.setVariable("raiseFaultRuleSchemaValidation", "true");
context.setVariable("raiseFaultRuleSchemaValidationMessage", tv4.error)
}
}

Related

How to sanitize PHP posted in comments by users

I am creating a commenting system where users can post comments that can also consist of basic HTML including code. Like this:
<pre><code class="language-php"><?php
echo 'Test';
?></code></pre>
The problem is that I can't sanitize this one server side because the PHP code in the comment will actually run on my server. I tried using JavaScript like this before submitting the form:
$("#comment").val() = $("#comment").val().replace("<?", "<?").replace("?>", "?>");
However, this results in Syntax error.
Is there any way for me to safely post user comments that consist of PHP?
to set a new value of input element using jquery, you need to use this syntax
$("#yourElement").val(newValue);
so change your javascript code to:
$("#comment").val($("#comment").val().replace("<?", "<?").replace("?>", "?>"));
read: http://api.jquery.com/val/

Link/HREF Validation using jQuery or Javascript and RegEx

I have an input form where users can fill out a profile for their internal tool that they are submitting. There is a link field that allows the user to enter a link to this tool.
The following formats are accepted:
http://
https://
file://
\\server\path\to\file.txt
W:\
I am trying create a javascript function to validate the input to make sure it is in one of the above mentioned formats.
I have found some generic URL validation regEx strings but none of them seem to include the local paths of files.
Here is a quick example of a function that works just fine for the top 2 needed formats but when it comes to network paths, I can't find anything that I can get integrated into one easy function.
var message;
var myRegExp =/^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?#)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/i;
var urlToValidate = "\\server.domain.com\path\file.txt";
if (!myRegExp.test(urlToValidate)){
message = "Not a valid URL.";
}else{
message = "Its a valid URL.";
}
alert(message);
JS Fiddle: https://jsfiddle.net/carlhussey/ebg4m278/
I am looking for a solution to validate the standard web protocols as well as network/file shares.

Django passing user profile data from client to server

I am using a custom User model with an user profile using a OneToOneField with this structure :
email
password
profile : {
username
avatar
}
It works pretty good for mobile because I just basically send json back and forth, but it's a problem whenever I am using my API with a website because there is no way in html to send json-like data, hence I can't fill the "profile" field without using ajax.
I would prefer to have the possibility to use plain html forms and to use javascript only for client validation and animation not using it for critic functionality such as registration.
I can also use the following structure and then reconstruct a dictionary for the profile server-side but I do feel that's it's not generic enough.
email
password
username
avatar
UserSerializer.py
class UserSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True)
profile = ProfileSerializer(required=True)
class Meta:
model = get_user_model()
fields = ('id', 'email', 'password', 'date_joined', 'profile')
def create(self, validated_data):
#profile_data = validated_data.pop('profile')
password = validated_data.pop('password')
user = get_user_model().objects.create_user(**validated_data)
user.set_password(password)
#user.save()
print(user)
#print(profile_data
ProfileSerializer.py
class ProfileSerializer(serializers.ModelSerializer):
class Meta:
model = Profile
fields = ('username',)
So no matter if I am using json or form data, obviously it's waiting for a profile (object) data. I would like to be able to do it using html form.
Any idea how I should approach this ?
If I correctly understood your problem, you may find the Django rest framework useful for this.
The django rest framework have Views that can handle both json and form data and feed them in the same validation mechanism. It basically uses the Content-Type header to choose a parser for the incoming data (more details here). Maybe you may look at what they did or use the library directly.
Hope this helps.
Maybe you can write an ApiView with a FormParser?
See: http://www.django-rest-framework.org/api-guide/parsers/#formparser

When sending information from the client to the server, do I enforce rules on the client side or server side (or both)? [duplicate]

This question already has answers here:
JavaScript: client-side vs. server-side validation
(13 answers)
Closed 7 years ago.
My question is about what is necessary and/or best practice.
Suppose, for example I need some text from an input into my controller, and that text isn't to be blank.
<form action="BaHumBug/Index" method="post" id="xmasTextForm">
<input name="xmasText" type="text" id="xmasTextInput" />
</form>
Do I enforce the rule about no empty text on the client side
$('#xmasTextForm').submit(function(ev) {
{
if ($('#xmasTextForm').val().isWhiteSpace())
{
alert("Fill the input with something, dude!");
return false;
}
}
or the server side
[HttpPost]
public ActionResult Index (string xmasText)
{
if (xmasText.IsWhiteSpace())
{
// ....
}
or do I do both for 2 layers of protection? Or does the choice depend on other factors?
It’s always a good practice to have at least the validation on the controller, this way you’re sure that your application is NOT receiving invalid data.
The validation on client side is also important because you can provide a good feedback for the client when this one takes your forms in a wrong way.
One thing that helps a lot on the good design of your code and controllers is apply TDD(Test driven development methodology) , if you’re familiar you can access this link to get more informed.
Through tests you can design your application by understanding and considering a good coverage of the possible input cases that you may have.
As has been said before - see JavaScript: client-side vs. server-side validation - there's pros for both. But I would say that it' is essential on the server.
Its always good to have validations at client side as well as server side.
Reason being what if someone disable javascript from internet options.In that case if there are no validations at server side,your use case will fail.
You can use annotations [Required] attribute to make it mandatory field.
If JavaScript is enabled,and there is no user input in mandatory field,you will see control will not pass to controller action.
In Case JavaScript is disabled,control will pass to controller action with **ModelState.IsValid** value will be false.
Server side code should be like this:
[HttpPost]
public ActionResult Index (string xmasText)
{
if (ModelState.IsValid)//rather than check of whitespace
{
// ....
}
}

Cannot seem to set a Form's Encoding Type. (Javascript)

I am trying to hardwire an on-the-fly created form to send JSON using the encoding type "application/json".
in jQuery, I would set this as 'contentType' in an $.ajax or a $.post - however for certain reasons, I need to be doing this manually.
I have the following code, but it just doesn't work. It still defaults the enctype to application/x-www-form-urlencoded
data = data;
var form = document.createElement("FORM");
form.style.display = "none";
form.action = url;
form.setAttribute('enctype', 'application/json');
form.method = "post";
Am I trying to set the wrong property, or am I just setting it wrong? Any ideas?
Not sure that 'application/json' is supported as a valid enctype. According to the HTML401 specification:
"W3C User agents must support the content types listed below (application/x-www-form-urlencoded, multipart/form-data). Behavior for other content types is unspecified."
http://www.w3.org/TR/html401/interact/forms.html#form-content-type
So I guess that support for this is down to the browser vendor.
If you want to mimic the way jQuery and other javascript libraries work then you'll be using an xmlhttp request to post your data instead of using a FORM element, you dont need to tell the server what kind of content type you'll be sending when you do this, the server will assume (rightfully) that you are using application/x-www-form-urlencoded .
I don't think a form can do that.
You'll need to do it on the server side. Or if you must do it on client prior to sending (not recommended) then look at a JSON library.
You should check out the w3Schools reference.
form.enctype = enctype;
EDIT - I didn't notice you wanted the form to encode the data into JSON...that's not going to happen. Either use AJAX or process it server side and return the response in JSON.
I believe that you should use
enctype="multipart/form-data"

Categories