G'day gurus,
I'm calling the REST APIs of an enterprise application that shall remain nameless, and they return JSON such as the following:
throw 'allowIllegalResourceCall is false.';
{
"data": ... loads of valid JSON stuff here ...
}
Is this actually valid JSON? If (as I suspect) it isn't, is there any compelling reason for these kinds of shenanigans?
The response I received from the application vendor is that this is done for security purposes, but I'm struggling to understand how this improves security much, if at all.
Thanks in advance!
Peter
According to
http://jsonlint.com/
It is not.
Something like the below is.
{
"data": "test"
}
Are they expecting you to pull the JSon load out of the message above?
Its not a JSON format at all. From your question it seems you are working with enterprise systems like JIVE :). I am also facing same issue with JIVE api. This is the problem with their V3 API. Not standard , but following thing worked for me. (I am not sure if you are talking about JIVE or not)
//invalid jason response... https://developers.jivesoftware.com/community/thread/2153
jiveResponse = jiveResponse.Replace
("throw 'allowIllegalResourceCall is false.';",String.Empty);
There is a valid reason for this: it protects against CSRF attacks. If you include a JSON url as the target of a <script> tag, then the same-origin policy doesn't apply. This means that a malicious site can include the URL of a JSON API, and any authenticated users will successfully request that data.
By appropriately overriding Object.prototype and/or Array.prototype, the malicious site can get any data parsed as an object literal or array literal (and all valid JSON is also valid javascript). The throw statement protects against this by making it impossible to parse javascript included on a page via <script> tags.
Definitely NOT valid JSON. Maybe there's an error in the implementation that is mixing some kind of debug output with the correct output?
And, by no means this is for security reasons. Seems to me this is a plain bug.
throw 'allowIllegalResourceCall is false.'; is certainly not valid JSON.
What MIME type is reported?
It seems they have added that line to prevent JSON Hijacking. Something like that line is required to prevent JSON Hijacking only if you return a JSON array. But they may have added that line above all of their JSON responses for easier implementation.
Before using it, you have to strip out the first line, and then parse the remaining as JSON.
Related
A colleague and I were trying to write the minimal logic that we needed for compacting, validating, parsing, and storing json coming from a client.
Upon doing so, we realized that compacting and validating were two steps that were both being accomplished by json.Compact anyways, since the code indicates json.Compact calls the json Scanner. The scanner then validates json and errors on invalid json.
The docs do not make this explicit, but we think this is the case.
Here is a link: https://forum.golangbridge.org/t/json-compact-appears-to-also-validate-json-but-is-not-documented/23088
Let us know thoughts.
Yes.
json.Compact uses json.scanner while scanning the json. If the scanner encounters invalid JSON sets scanner.err, which is returned by json.Compact if there is an error.
This is the same way json.Valid checks for valid json, by simply scanning the JSON and checking for scanner.err.
Here's the relevant code sections:
https://go.googlesource.com/go/+/go1.16.2/src/encoding/json/indent.go#17
https://go.googlesource.com/go/+/go1.16.2/src/encoding/json/scanner.go#30
I have a REST API that accepts and returns JSON data.
A sample request response is a follows
Request
{
"repos": [
"some-repo",
"test-repo<script>alert(1)</script>"
]
}
Response
{
"error": "Error Message",
"repos": [
"test-repo<script>alert(1)</script>"
]
}
Is my API vulnerable for XSS?. From what I understand, since the Content-Type is set to application/json, the API as such is safe from XSS. The client needs to ensure that the output is encoded to prevent any XSS attacks.
To add an additional layer of security, I can add some input encoding/validation in the API layer.
Please let me know if my assessment is right and any other gotchas that I need to be aware of
I think it's right that any XSS issue here is a vulnerability of the client. If the client inserts HTML into a document, then it is its responsibility to apply any neccessary encoding.
The client knows what encoding is required not the server. Different encoding, or no encoding may be needed in different places for the same data. For example:
If a client did something like:
$(div).html("<b>" + repos + "</b>");
then it would be vulnerable to XSS, so repos would need to be HTML encoded here.
But if it did something like:
$(div).append($("<b>").text(repos));
then HTML encoding would have resulted in HTML entity codes being wrongly displayed to the user.
Or if the client wanted to do some processing of the data, it may want the plaintext data first to do the processing, and then encode it later to output it.
Input validation can help too, but the rules for what is valid input may not align with what is safe to use without encoding. Things like ampersands, quotes and brackets can appear in valid text data too. But if your data can't contain these characters, you can reject the input as invalid.
Your API will not be vulnerable to XSS unless it also provides a UI that consumes it. It will be the clients of your API which could be vulnerable - they will need to make sure they correctly encode any data from your API before they use it in any UI.
I think your api is vulnerable, though the script may not be execute. Talking to XSS prevention, we always suggest decode/validation dangerous characters when the api deals the input. There is a common requirement "clean the data before it store in the DB".
As for your situation, the api just response a json, but we don't know where the data in json will be used to. usually the frontend accept the data without any decode/validation, if that, there will be a xss.
you talk about that the client use decode the data they get from your api. Yes I agree, but frontend always "trust" the backend so that they won't decode the data. but the api server should not trust any input from frontend due to this can be controlled/changed by (malicious)users.
Here's my JSON response for http://localhost:8000/characters/api/users/1?format=json
)]}',
{"id":1,"username":"admin","mage_by_user":[3],"mage_last_updated":"2015-02-11T16:13:16.229Z"}
Notice the )]}', on the first line.
Here is my code that gets called to create the JSON:
class UserSerializer(serializers.ModelSerializer):
mage_by_user = serializers.PrimaryKeyRelatedField(
many=True, queryset=Mage.objects.all())
mage_last_updated = serializers.ReadOnlyField(
source='mage_by_user.updated_date')
class Meta:
model = User
fields = ('id', 'username', 'mage_by_user', 'mage_last_updated',)
Further testing:
I've noticed the title of the page is TypeError at <insert url here>.
This happens with all of my endpoints
If I try to access a non-existent object (userId=2 for instance), then renders 'normally' for DRF, e.g:
{
detail: "Not found"
}
Any idea why this would happen?
Those characters are inserted by the Djangular middleware AngularJsonVulnerabilityMiddleware, to inject Json Vulnerability Protection
A JSON vulnerability allows third party website to turn your JSON resource URL into JSONP request under some conditions. To counter this your server can prefix all JSON requests with following string ")]}',\n". Angular will automatically strip the prefix before processing it as JSON.
Unfortunately, it means it breaks various JSON viewers.
Sorry to not be more help, but this looks like something entirely unrelated to REST framework. There's absolutely no way a JSON response there would ever be rendered in that way.
Perhaps you have a custom renderer configured, that's outputting a malformed response, perhaps you have some broken middleware inserting those characters, perhaps its an issue in the client or whatever environment you're making the requests, or perhaps it's something else entirely unrelated to any of those.
I'd start by trying to narrow down the issue as much as possible - remove all the complexity from the view and serializer and attempt to replicate the behavior in a test case.
Most likely there's some sort of unexpected integration issue you're missing or some otherwise obvious code typo that's being overlooked.
I can't seem to find a definitive answer on this -- what does the p in JSONP stand for?. The candidates I've found so far are padding and prints. Anyone know where the JSONP name came from?
Padding.
from http://en.wikipedia.org/wiki/JSONP
JSONP or "JSON with padding" is a complement to the base JSON data
format, a pattern of usage allowing a page to request data from a
server in a different domain. JSONP is a solution to this problem,
forming an alternative to a more recent method called Cross-Origin
Resource Sharing.
Padding
While the padding (prefix) is typically the name of a callback
function that is defined within the execution context of the browser,
it may also be a variable assignment, an if statement, or any other
Javascript statement. The response to a JSONP request (namely, a
request following the JSONP usage pattern) is not JSON and is not
parsed as JSON; the returned payload can be any arbitrary JavaScript
expression, and it does not need to include any JSON at all. But
conventionally, it is a Javascript fragment that invokes a function
call on some JSON-formatted data.
Said differently, the typical use of JSONP provides cross-domain
access to an existing JSON API, by wrapping a JSON payload in a
function call.
Hope that helped. Google wins!
Stone,
What I know, it stands for 'Padding'. There is a explaination about it on Wikipedia: JsonP
What it does?
It gives you the possibility to make a CROSS-DOMAIN request and get JSON data returned.
Normally via the HTML script tag you call for another JavaScript.
But JsonP provide you a callback function and you can return noraml Json response.
Example:
You create a script tag:
<script type="text/javascript" scr="http://anotherDomain/Car?CarId=5&jsonp=GiveCarResponse"></script>
In this script the GiveCarResponse is the callback function on the other Domain. Invoking this function will result in a Json response. In example:
{"CarId":5, "Brand":"BMVV", "GAS": false}
Does this make sense?
From wikipedia, it stands for "padding" (or with padding).
http://en.wikipedia.org/wiki/JSONP
Umm ... you've seen the wikipedia page, and you mistrust its accuracy?
This standards site seems to confirm the "with padding".
It basically means to add a calling function around JSON.
AJAX can be called from your own server only and is not a cross domain. So to load data from different servers at client side, you make a JSONP request, basically you load a normal javascript file from other server just like you include a normal javascript file. Bust as JSON is not a valid javascript file, JSON is wrapped up in a function call to make it valid js file. the wrapped up function (already in your code) then extracts that data and show it on your page.
We are in the middle of a ongoing discussion about how to handle REST exceptions.
Response Content type : JSON
Two solutions we have:
Throw all the unchecked exceptions as a JSON response.
Send Request Invalid Response code.
Arguments:
When its a error, why return JSON? Just send a invalid response code.
Counter Argument:
Response code are too technical to handle for normal developers.
Whats your say??
For a JSON API I recently developed I do both. I always respond with valid JSON (well, assuming I respond at all). If I detect an invalid request, I use status 400. If I detect a server error (which I don't believe is caused by an invalid request), I use a 5xx status. The JSON object contains a special key that is only set for errors, with a string value.
I think this is a good solution that respects REST principles, and can be used in multiple ways. The same solution is used by some other JSON APIs, such as Yahoo Search. Try http://search.yahooapis.com/ImageSearchService/V1/imageSearch?appid=YahooDemo&output=json .
Use error codes like for HTTP. So 50* for any exception cause by some internal problem. And 40* for bad arguments. Avoid using your own defined codes as far as its possible. The idea is to have a "uniform" interface.
In general.
204 for success without sending any content
200 for success with a json representation of the resource
And if its not a successful operation return appropriate response code. You can choose to optionally return a json. To simplify things you can have a common format (json) for all error responses.
http://en.wikipedia.org/wiki/REST is a must read before you freeze on your api specs.