JSONP safety precautions are divided into the following points:
1. Prevent accidental truncation of callback parameters JS code, special character single quotation marks, newline characters are at risk.
2, prevent callback parameter malicious tagging (such as script), resulting in XSS vulnerability
3, prevent cross-domain request misuse, prevent illegal site malicious call
For the 3rd, we can limit the refer by the source White list match , and the cookietoken mechanism
The first two points, the traditional approach is divided into the following types:
1, Pure manual filter special characters , quotation brackets, etc., once the potential malicious characters are found the service side rejected, return error.
This approach is more stringent, but the attendant problem is that the failure rate will increase, especially for external developers.
And there are many variants of malicious characters in JS , this method needs to enumerate all illegal characters, and there may be omissions.
We should not block out potentially malicious characters because there are certain requirements that need to be passed in and stored.
2, for the callback parameter for the thorough format check , or mandatory convention to specify the format . Basically can solve the security problem completely,
But the same is not completely transparent to the caller, the user needs to know the relevant restrictions and conventions, may cause unnecessary communication costs.
3, return the package to add header head, to enforce the specified MIME type , avoid parsing in HTML, prevent XSS vulnerability.
It seems to be a perfect solution.
But strangely, in some versions of Firefox, the browser will still parse the HTML as it is directly accessing the MIME-type JAVASCRIPT request.
It may be a flaw in the design of the browser, but it ignores the header we set. There is no guarantee that all browsers will be parsed strictly by MIME type.
Our focus has always been on how to limit user input, but consider the issue from another level, and perhaps it will be a little more enlightened.
Let's look at the features of JS itself.
The essence of JSONP is to construct a global callback function, and then load the script tag to trigger the callback function.
Usually we use functions to write this.
function test () {}test ();
The global function, by default, is a member of window. You can also display the write as
Window.test = function () {};window.test ();
While the members of the object in JS can be accessed using the string index, it is further transformed into
window[' Test ']=function () {};window[' Test '] ();
Do you notice now that we have completely limited the function name to the character string context,
Theoretically, as long as the anti-injection work is done, the callback parameter is unlikely to jump out of the string context to execute code unexpectedly.
In PHP , for example, a single string prevents injection and can even be implemented directly using the Json_encode string.
window[' Alert ("123"); ABC '] ();
The above callback parameter, although there is a risk of injection, can be strictly restricted to the inside of the string because of the callback parameter, only as text, not accidentally executed
But there are still XSS vulnerabilities.
Look at the following example
window[' <script>alert (123);</script> '] ();
Although we have guaranteed <script> strictly within the quotation marks, will not cause JS injection, but directly in the browser input the JSONP request will still follow HTML parsing , resulting in XSS
Vulnerabilities, even if the header is set up is difficult to guard against.
Further, we only need to ensure that the browser does not appear in plaintext <> tags, then the problem can be completely resolved.
The basic idea is to do a urlencode on the service side. and the output decodeuricomponent (' ##### ') to circumvent the display angle brackets.
The UrlEncode string, which may contain only alphanumeric%, also solves the problem of injection
Finally, a short code is attached. Fundamentally solve the JSONP security problem
$callback = UrlEncode ($_get[' callback ')
echo "Window[decodeuricomponent (' {$callback} ')] ({ret:0,msg: ' OK '});"
Request 1:http://www.test.com/a.php?callback=alert (123); ABC
Response 1:window[decodeuricomponent (' alert (123)%3BABC ')] ({ret:0,msg: ' OK '});
Request 2:http://www.test.com/a.php?callback=<script>alert (123);</script>
Response 2:window[decodeuricomponent ('%3cscript%3ealert (123)%3b%3c%2fscript%3e ')] ({ret:0,msg: ' OK '});
The above examples demonstrate that the JSONP security vulnerability has been completely circumvented, and even if there are malicious parameters that are attempted to inject, the program can still be fully operational to trigger callbacks.
Source
?
Resolving JsonP security Issues