تزریق 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(); } }