Witam,
Od pewnego czasu mam problem z jedna develeoperka ktora stworzyla nowy formularz RMA w PHP. Formualrz jednorazowo ma przyjac do 100 numerow seryjnych w formacie: 26-5142733. Problem polega na tym, ze zwiekszym w PHP i ModSecurity obie wartosci PCRE do 1000000 i dalej dostaje false positive z ModSecurity. Pytanie czy definitywnie winne jest ModSecurity, czy skrypt jest delikatnie mowiac skopany (nie znam sie na php)?
Wycinak loga z ModSecurity:
Kod
--31a0a96a-Z--
--f2b83a40-A--
[12/Dec/2016:14:28:51 +0000] WE60I38AAQEAADIZJGUAAAAA 1.2.3.4 33245 1.2.3.5 443
--f2b83a40-B--
POST /warranty/get_warranty.php HTTP/1.1
Host: rma.domain.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: https://rma.domain.com/warranty/
Content-Length: 356
DNT: 1
Connection: keep-alive
--f2b83a40-C--
data=26-5142733%0A26-5142734%0A26-5142735%0A26-5142736%0A26-5142737%0A26-5142738%0A26-5142739%0A26-5142740%0A26-5142741%0A26-5142742%0A26-5142743%0A26-5142744%0A26-5142745%0A26-5142746%0A26-5142747%0A26-5142748%0A26-5142749%0A26-5142750%0A26-5142751%0A26-5142752%0A26-5142753%0A26-5142754%0A26-5142755%0A26-5142756%0A26-5142757%0A26-5142758%0A26-5142759%0A
--f2b83a40-F--
HTTP/1.1 403 Forbidden
Strict-Transport-Security: max-age=15768000
Content-Length: 234
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1
--f2b83a40-E--
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /warranty/get_warranty.php
on this server.<br />
</p>
</body></html>
--f2b83a40-H--
Message: Rule 7fc35b3599d0 [id "942360"][file "/usr/share/owasp-modsecurity-crs/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf"][line "451"] - Execution error - PCRE limits exceeded (-8): (null).
Message: Access denied with code 403 (phase 2). Match of "streq 0" against "TX:MSC_PCRE_LIMITS_EXCEEDED" required. [file "/etc/modsecurity/modsecurity.conf"] [line "107"] [id "200005"] [msg "ModSecurity internal error flagged: TX:MSC_PCRE_LIMITS_EXCEEDED"]
Action: Intercepted (phase 2)
Apache-Handler: application/x-httpd-php
Stopwatch: 1481552931298259 4802 (- - -)
Stopwatch2: 1481552931298259 4802; combined=2622, p1=456, p2=1992, p3=0, p4=0, p5=134, sr=63, sw=40, l=0, gc=0
Response-Body-Transformed: Dechunked
Producer: ModSecurity for Apache/2.8.0 (http://www.modsecurity.org/); OWASP_CRS/3.0.0.
Server: Apache
Engine-Mode: "ENABLED"
Kod get_warranty.php
<div class="row bottom1">
<div class="container">
<h1>STB Warranty Result</h1>
</div><!-- container -->
</div>
<div class="row bottom1_background"></div>
<div class="row about_content">
<div class="container">
<div class="col-lg-12 col-xs-12">
<?php
if ( $_POST['data'] ) {
include "js/function.php";
try {
throw new Exception("No entry found.");
}
$database = loadDatabase("","","database");
// CREATE TEMP mt1 TABLE
$aryField = array( 'SN' ); setQuery( $database, createTempTable( 'mt1', $aryField ) );
// Split input data and insert into mt1 table
setQuery( $database, insertTempTable( 'mt1', $aryField, removeEmpty($aryData) ) );
/* Remove inaccurate serial numbers
$query = "DELETE FROM mt1 WHERE SN NOT LIKE '__-_______'";
setQuery( $database, $query );*/
// Remove duplicate SN and set LIMIT of 100 units only
$query = "CREATE TEMPORARY TABLE t1 AS (
SELECT SN AS Find, customer_name, SN AS oSN
FROM mt1
LEFT JOIN repair_report AS a
ON mt1.SN = a.unit_serial_number AND a.customer_rma != 'INVENTORY' AND a.current_status NOT IN ('UTR')
GROUP BY SN
ORDER BY complete_date DESC
LIMIT 0, 100)";
setQuery( $database, $query );
//---- Start to find the original serials -----------//
$query = "SELECT Find, customer_name FROM t1";
$result = getQuery( $database, $query );
while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
//----- Find the original serials along same customer ----//
$serial = $row['Find'];
$customer = $row['customer_name'];
$is_end = 1;
do {
$query = "SELECT fail_unit_serial_number
FROM repair_report
WHERE customer_name = ? AND unit_serial_number = ? AND fail_unit_serial_number LIKE '__-_______'
ORDER BY complete_date DESC";
$stmt = $database -> prepare( $query );
$stmt->bind_param( "ss", $customer, $serial );
$stmt->execute();
$stmt->store_result();
if ( $stmt->num_rows > 0 ) {
$stmt->bind_result( $fail_serial );
$stmt->fetch();
$serial = $fail_serial;
} else {
$is_end = 0;
}
$stmt->close();
} while( $is_end > 0 );
//---------------- Update the original serial ----------//
$query = "UPDATE t1 SET oSN = '". $serial ."' WHERE Find = '". $row['Find'] ."'";
setQuery( $database, $query );
}
mysqli_free_result( $result );
//-------- End finding the original seiral -------------//
// Find the warranty status for the original SN
$query = "CREATE TEMPORARY TABLE showCase AS (
SELECT Find, oSN, (additional_warranty_month + 12) AS given_warranty_month, database_sale_order, customer, CASE WHEN customer_ship_date = '0000-00-00' THEN manufacturer_ship_date ELSE customer_ship_date END AS customer_ship_date
FROM t1 LEFT JOIN production_shipment AS a
ON t1.oSN = a.unit_serial_number )";
setQuery( $database, $query );
//--------- For EU warranty by prefix and sale order --------------//
$query = "UPDATE showCase AS t1, customer_order_detail AS a SET t1.given_warranty_month = (a.given_warranty_month + t1.given_warranty_month - 12) WHERE t1.database_sale_order = a.database_sale_order AND SUBSTRING(t1.Find,1,2) = a.serial_prefix";
setQuery( $database, $query );
//---------- For CCI Kamai500 3 year warranty ----------------------//
$query = "UPDATE showCase SET given_warranty_month = given_warranty_month + 24 WHERE customer LIKE 'CCI %' AND SUBSTRING(Find,1,2) = '26'";
setQuery( $database, $query );
//---------- For CCI Amulet400 2 year warranty ----------------------//
$query = "UPDATE showCase SET given_warranty_month = given_warranty_month + 12 WHERE customer LIKE 'CCI %' AND SUBSTRING(Find,1,2) = '20'";
setQuery( $database, $query );
//---------- For P&T 15 month warranty ----------------------------//
$query = "UPDATE showCase SET given_warranty_month = given_warranty_month + 3 WHERE customer LIKE 'P%&%T%' OR customer LIKE 'P%and%T%' OR customer LIKE 'Advanced Media%' OR customer LIKE 'Confluent%'";
setQuery( $database, $query );
//---------- All customer get addition 12 month warranty period ---//
$query = "UPDATE showCase SET given_warranty_month = given_warranty_month + 12 WHERE customer_ship_date >= '2016-08-01'";
setQuery( $database, $query );
$query = "SELECT Find AS SN, SUBSTRING(Find,1,2) AS Model, CASE WHEN customer_ship_date IS NULL THEN 'Not Found' ELSE DATE_ADD(customer_ship_date, INTERVAL given_warranty_month MONTH) END AS ship_date FROM showCase ORDER BY ship_date DESC, Find ASC ";
$result = getQuery( $database, $query );
//Drawing Tables for second phase of submit serial numbers
echo "<div class='result_data'>"; echo "Total ". mysqli_num_rows
( $result ) ." records found.<br>"; generateTables( $result );
?>
</div></div>
<div class="disclaimer">
<ul style="border: 1px solid #DDD; border-radius: 10px; padding: 20px 40px; margin-top: 20px;"><b style="font-size:16px; margin-left: -20px; display: block;">The product is considered out of warranty if any of the following conditions apply:</b>
<li>The Company product serial number has been defaced or removed.</li>
<li>Damage has occurred to the product caused by normal wear and tear, accident, negligence, abuse, misuse, misapplication, willful damage, acts of God, or use with non-Companyproducts.</li>
<li>Damage has occurred to the product due to not adhering to instructions on use and care of product.</li>
<li>The Company product or a part of the product has been modified, had alterations, or repairs done to it without the written permission of Company.</li>
<li>Damage has occurred to the Company product due to improper installation, abnormal working conditions, or effects of excessive electrical current or voltage, whether or not caused by lightning.</li>
</ul>
</div>
<?php
mysqli_close($database);
} catch( Exception $e ) {
echo "<font color=red>ERROR: ". $e->getMessage(). "</font>"; }
} else {
echo "<font color=red>ERROR: Invalid Input Data.</font>"; }
?>
</div><!-- operators -->
</div><!-- container -->
</div>