Cross-site Port Attack

An application is vulnerable to Cross Site Port Attacks if the application processes user supplied URLs and does not verify/sanitize the backend response received from remote servers before sending it back to the client. An attacker can send crafted queries to a vulnerable web application to proxy attacks to external Internet facing servers, intranet devices and the web server itself using the advertised functionality of the vulnerable web application. The responses, in certain cases, can be studied to identify service availability (port status, banners etc.) and even fetch data from remote services in unconventional ways.

XSPA allows attackers to abuse available functionality in most web applications to port scan intranet and external Internet facing servers, fingerprint internal (non-Internet exposed) network aware services, perform banner grabbing, identify web application frameworks, exploit vulnerable programs, run code on reachable machines, exploit web application vulnerabilities listening on internal networks, read local files using the file protocol and much more. XSPA has been discovered with Facebook, where it was possible to port scan any Internet facing server using Facebook’s IP addresses. Consecutively, XSPA was also discovered in several other prominent web applications on the Internet, including Google, Apigee, StatMyWeb,,, Pinterest, Yahoo, Adobe Omniture and several others. We will take a look at the vulnerabilities that were present in the above mentioned web applications that could be used to launch attacks and perform port scans on remote servers and intranet devices using predefined functionality.

Examples of Implementation

Let us look at some examples of PHP implementations of file fetching via user supplied URLs. XSPA affects web applications written in any language as long as they let users decide where the data would be fetched from. Please note the examples shown below are neither clean nor secure, however most of the parts of the code outlined below have been obtained from real world application sources.

    1.    PHP file_get_contents:
    if (isset($_POST['url'])) 
    $content = file_get_contents($_POST['url']); 
    $filename = './images/'.rand().'img1.jpg'; 
    file_put_contents($filename, $content); 
    echo $_POST['url'].""; 
    $img = "<img src=\"".$filename."\"/>"; 
    echo $img; 

This implementation fetches data as requested by a user (an image in this case) using the filegetcontents PHP function and saves it to a file with a randomly generated filename on the disk. The HTML img attribute then displays the image to the user.

    2.    PHP fsockopen() function:
    function GetFile($host,$port,$link) 
    $fp = fsockopen($host, intval($port), $errno, $errstr, 30); 
    if (!$fp) { 
    echo "$errstr (error number $errno) \n"; 
    } else { 
    $out = "GET $link HTTP/1.1\r\n"; 
    $out .= "Host: $host\r\n"; 
    $out .= "Connection: Close\r\n\r\n"; 
    $out .= "\r\n"; 
    fwrite($fp, $out); 
    while (!feof($fp)) { 
    $contents.= fgets($fp, 1024); 
    return $contents; 

This implementation fetches data as requested by a user (any file or HTML) using the fsockopen PHP function. This function establishes a TCP connection to a socket on the server and performs a raw data transfer.

    3.    PHP curl_exec() function:
    if (isset($_POST['url']))
    $link = $_POST['url'];
    $curlobj = curl_init();
    curl_setopt($curlobj, CURLOPT_POST, 0);
    curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1);

    $filename = './curled/'.rand().'.txt';
    file_put_contents($filename, $result); 
    echo $result;

This is another very common implementation that fetches data using cURL via PHP. The file/data is downloaded and stored to disk under the 'curled' folder and appended with a random number and the '.txt' file extension.