تزریق xml: تفاوت بین نسخه‌ها

از Secure Coding

(صفحه‌ای تازه حاوی «در نرم افزار هایی که از فرمت xml برای انتقال اطلاعات استفاده می کنند، اگر به در...» ایجاد کرد)
 
(بدون تفاوت)

نسخهٔ کنونی تا ‏۱۹ دسامبر ۲۰۱۹، ساعت ۱۱:۲۸

در نرم افزار هایی که از فرمت xml برای انتقال اطلاعات استفاده می کنند، اگر به درستی نوع ارتباط و موجودیت ها بررسی و کنترل نشود امکان تزریق xml وجود خواهد داشت.

برای مثال در کد زیر اطلاعات دو user را مشاهده می کنید.

<?xml version="1.0" encoding="ISO-8859-1"?> 
<users> 
	<user> 
		<username>gandalf</username> 
		<password>!c3</password> 
		<userid>0</userid>
		<mail>[email protected]</mail>
	</user> 
	<user> 
		<username>Stefan0</username> 
		<password>w1s3c</password> 
		<userid>500</userid>
		<mail>[email protected]</mail>
	</user> 
</users>


حال اگر مهاجم اطلاعات username، password و mail را توسط uri زیر در xml بالا درج کند xml injection رخ داده است.

http://www.example.com/addUser.php?username=tony&password=Un6R34kb!e&[email protected]


محتوای xml بعد از تزریق

<?xml version="1.0" encoding="ISO-8859-1"?> 
<users> 
	<user> 
		<username>gandalf</username> 
		<password>!c3</password> 
		<userid>0</userid>
		<mail>[email protected]</mail>
	</user> 
	<user> 
		<username>Stefan0</username> 
		<password>w1s3c</password> 
		<userid>500</userid>
		<mail>[email protected]</mail>
	</user> 
	<user> 
		<username>tony</username> 
		<password>Un6R34kb!e</password> 
		<userid>500</userid>
		<mail>[email protected]</mail>
	</user> 
</users>

روش های جلوگیری[ویرایش]

روش های جلوگیری در PHP[ویرایش]

مثال 1)

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


	<head>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

		<title>XML Bomb Denial-of-Service</title>

		<?php require(dirname(__FILE__)."../../../bootstrap.php") ?>

	</head>
	 <body>


		 <!-- Sidebar -->
	 <div id="wrapper">

		 <div class="col-md-3">
		 <?php require(dirname(__FILE__)."../../../sidebar.php") ?>
	</div>

			<div id="page-content-wrapper">
						<div class="container-fluid">
								<div class="row">
										<div class="col-lg-12">


    </html>
<?php
	$simple = $_POST['name'];
	$p = xml_parser_create();
	xml_parse_into_struct($p, $simple, $vals, $index);
	xml_parser_free($p);
	echo "<br><br>The following array was created from your XML data\n <br><br>";
	print_r($index);
	echo "\nVals array\n";
	print_r($vals);
	 get_server_memory_usage();
	 get_server_cpu_usage();
function get_server_memory_usage(){
    //shows server memory usage
    if (stristr(PHP_OS, 'Linux'))
    {
		$free = shell_exec('free');
		$free = (string)trim($free);
		$free_arr = explode("\n", $free);
		$mem = explode(" ", $free_arr[1]);
		$mem = array_filter($mem);
		$mem = array_merge($mem);
		$memory_usage = $mem[2]/$mem[1]*100;
		print "<br><br><br> The server memory usage is ".$memory_usage;
	}
	else
	{
	$cmd = 'typeperf  -sc 1  "\Processor(_Total)\% Processor Time"';
	exec($cmd, $lines, $retval);
	if($retval == 0) {
		$values = str_getcsv($lines[2]);
		print "<br><br><br> The server memory usage is ".floatval($values[1]);
	} else {
		return false;
	}
	}
}
function get_server_cpu_usage(){
    //shows server CPU Usage
{
    $load=array();
    if (stristr(PHP_OS, 'win'))
    {
    $output = array();
    exec( 'tasklist ', $output );
    foreach ($output as $value)
    {
        $ex=explode(" ",$value);
        $count_ex=count($ex);
        if (eregi(" ".getmypid()." Console",$value))
        {
            $memory_size=$ex[$count_ex-2]." Kb";
            print "<br><br>The server CPU usage is ".$memory_size;
        }
    }
    }
    else
    {
        $load = sys_getloadavg();
        print "<br><br>The server CPU usage is ".$load[0];
    }
    return $load;
}
}
?>

راه حل 1)

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


	<head>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

		<title>XML Bomb Denial-of-Service</title>

		<?php require(dirname(__FILE__)."../../../bootstrap.php") ?>

	</head>
	 <body>


		 <!-- Sidebar -->
	 <div id="wrapper">

		 <div class="col-md-3">
		 <?php require(dirname(__FILE__)."../../../sidebar.php") ?>
	</div>

			<div id="page-content-wrapper">
						<div class="container-fluid">
								<div class="row">
										<div class="col-lg-12">


    </html>
<?php
	$simple = addslashes($_POST['name']);
	$p = xml_parser_create();
	xml_parse_into_struct($p, $simple, $vals, $index);
	xml_parser_free($p);
	echo "<br><br>The following array was created from your XML data\n <br><br>";
	print_r($index);
	echo "\nVals array\n";
	print_r($vals);
	 get_server_memory_usage();
	 get_server_cpu_usage();
function get_server_memory_usage(){
    //shows server memory usage
    if (stristr(PHP_OS, 'Linux'))
    {
		$free = shell_exec('free');
		$free = (string)trim($free);
		$free_arr = explode("\n", $free);
		$mem = explode(" ", $free_arr[1]);
		$mem = array_filter($mem);
		$mem = array_merge($mem);
		$memory_usage = $mem[2]/$mem[1]*100;
		print "<br><br><br> The server memory usage is ".$memory_usage;
	}
	else
	{
	$cmd = 'typeperf  -sc 1  "\Processor(_Total)\% Processor Time"';
	exec($cmd, $lines, $retval);
	if($retval == 0) {
		$values = str_getcsv($lines[2]);
		print "<br><br><br> The server memory usage is ".floatval($values[1]);
	} else {
		return false;
	}
	}
}
function get_server_cpu_usage(){
    //shows server CPU Usage
{
    $load=array();
    if (stristr(PHP_OS, 'win'))
    {
    $output = array();
    exec( 'tasklist ', $output );
    foreach ($output as $value)
    {
        $ex=explode(" ",$value);
        $count_ex=count($ex);
        if (eregi(" ".getmypid()." Console",$value))
        {
            $memory_size=$ex[$count_ex-2]." Kb";
            print "<br><br>The server CPU usage is ".$memory_size;
        }
    }
    }
    else
    {
        $load = sys_getloadavg();
        print "<br><br>The server CPU usage is ".$load[0];
    }
    return $load;
}
}
?>


روش های جلوگیری در ASP.NET[ویرایش]

مثال 1)

XmlDocument doc = new XmlDocument();
doc.LoadXml(template);
XmlElement list = doc.CreateElement(conn.XmlListTagName);
foreach (EaiItem updateItem in itemList)
{
    XmlElement item = doc.CreateElement( conn.XmlItemTagName );
    foreach(String itemAttrib in updateItem.ItemAttributes.Keys)
    {
        item.SetAttribute(itemAttrib, updateItem.ItemAttributes[itemAttrib]);
    }
    item.InnerXml = updateItem.ItemFieldXml;
    list.AppendChild(item);
}
doc.LastChild.AppendChild(list);

راه حل 1)

XmlDocument doc = new XmlDocument();
doc.LoadXml(template);
XmlElement list = doc.CreateElement(conn.XmlListTagName);
foreach (EaiItem updateItem in itemList)
{
    XmlElement item = doc.CreateElement( conn.XmlItemTagName );
    foreach(String itemAttrib in updateItem.ItemAttributes.Keys)
    {
        item.SetAttribute(itemAttrib, updateItem.ItemAttributes[itemAttrib]);
    }
    item.InnerText = updateItem.ItemFieldXml;
    list.AppendChild(item);
}
doc.LastChild.AppendChild(list);

روش های جلوگیری در JAVA[ویرایش]

مثال 1)

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
 
public class OnlineStore {
  private static void createXMLStreamBad(final BufferedOutputStream outStream,
      final String quantity) throws IOException {
    String xmlString = "<item>\n<description>Widget</description>\n"
        + "<price>500</price>\n" + "<quantity>" + quantity
        + "</quantity></item>";
    outStream.write(xmlString.getBytes());
    outStream.flush();
  }
}

راه حل 1)

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
 
public class OnlineStore {
  private static void createXMLStream(final BufferedOutputStream outStream,
      final String quantity) throws IOException, NumberFormatException {
    // Write XML string only if quantity is an unsigned integer (count).
    int count = Integer.parseUnsignedInt(quantity);
    String xmlString = "<item>\n<description>Widget</description>\n"
        + "<price>500</price>\n" + "<quantity>" + count + "</quantity></item>";
    outStream.write(xmlString.getBytes());
    outStream.flush();
  }
}

راه حل 2)

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
 
import javax.xml.XMLConstants;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
 
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
 
public class OnlineStore {
 
  private static void createXMLStream(final BufferedOutputStream outStream,
      final String quantity) throws IOException {
    String xmlString;
    xmlString = "<item>\n<description>Widget</description>\n"
        + "<price>500.0</price>\n" + "<quantity>" + quantity
        + "</quantity></item>";
    InputSource xmlStream = new InputSource(new StringReader(xmlString));
    // Build a validating SAX parser using our schema
    SchemaFactory sf = SchemaFactory
        .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
    DefaultHandler defHandler = new DefaultHandler() {
      public void warning(SAXParseException s) throws SAXParseException {
        throw s;
      }
      public void error(SAXParseException s) throws SAXParseException {
        throw s;
      }
      public void fatalError(SAXParseException s) throws SAXParseException {
        throw s;
      }
    };
    StreamSource ss = new StreamSource(new File("schema.xsd"));
    try {
      Schema schema = sf.newSchema(ss);
      SAXParserFactory spf = SAXParserFactory.newInstance();
      spf.setSchema(schema);
      SAXParser saxParser = spf.newSAXParser();
      // To set the custom entity resolver,
      // an XML reader needs to be created
      XMLReader reader = saxParser.getXMLReader();
      reader.setEntityResolver(new CustomResolver());
      saxParser.parse(xmlStream, defHandler);
    } catch (ParserConfigurationException x) {
      throw new IOException("Unable to validate XML", x);
    } catch (SAXException x) {
      throw new IOException("Invalid quantity", x);
    }
    // Our XML is valid, proceed
    outStream.write(xmlString.getBytes());
    outStream.flush();
  }
}