تزریق xml
از Secure Coding
در نرم افزار هایی که از فرمت 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();
}
}