Merge branch 'fix_sql_injection' into storageareas

This commit is contained in:
Isaac Connor 2016-12-08 14:58:50 -05:00
commit ced701f56f
3 changed files with 85 additions and 43 deletions

View File

@ -1,5 +1,9 @@
<?php <?php
# Moved up here because it is used in several spots.
# These are the valid columns that you can filter on.
$filterFields = array( 'Component', 'ServerId', 'Pid', 'Level', 'File', 'Line' );
switch ( $_REQUEST['task'] ) switch ( $_REQUEST['task'] )
{ {
case 'create' : case 'create' :
@ -31,68 +35,85 @@ switch ( $_REQUEST['task'] )
if ( !canView( 'System' ) ) if ( !canView( 'System' ) )
ajaxError( 'Insufficient permissions to view log entries' ); ajaxError( 'Insufficient permissions to view log entries' );
$servers = Server::find_all(); $servers = Server::find_all();
$servers_by_Id = array(); $servers_by_Id = array();
# There is probably a better way to do this. # There is probably a better way to do this.
foreach ( $servers as $server ) { foreach ( $servers as $server ) {
$servers_by_Id[$server->Id()] = $server; $servers_by_Id[$server->Id()] = $server;
} }
$minTime = isset($_POST['minTime'])?$_POST['minTime']:NULL; $minTime = isset($_POST['minTime'])?$_POST['minTime']:NULL;
$maxTime = isset($_POST['maxTime'])?$_POST['maxTime']:NULL; $maxTime = isset($_POST['maxTime'])?$_POST['maxTime']:NULL;
$limit = isset($_POST['limit'])?$_POST['limit']:100; $limit = 100;
$filter = isset($_POST['filter'])?$_POST['filter']:array(); if ( isset($_POST['limit']) ) {
$sortField = isset($_POST['sortField'])?$_POST['sortField']:'TimeKey'; if ( ! is_integer( $_POST['limit'] ) ) {
Error("Invalid value for limit " . ?$_POST['limit'] );
} else {
$limit = $_POST['limit'];
}
}
$sortField = 'TimeKey';
if ( isset($_POST['sortField']) ) {
if ( ! in_array( $_POST['sortField'], $filterFields ) and ( $_POST['sortField'] != 'TimeKey' ) ) {
Error("Invalid sort field " . $_POST['sortField'] );
} else {
$sortField = $_POST['sortField']
}
}
$sortOrder = (isset($_POST['sortOrder']) and $_POST['sortOrder']) == 'asc' ? 'asc':'desc'; $sortOrder = (isset($_POST['sortOrder']) and $_POST['sortOrder']) == 'asc' ? 'asc':'desc';
$filter = isset($_POST['filter'])?$_POST['filter']:array();
$filterFields = array( 'Component', 'ServerId', 'Pid', 'Level', 'File', 'Line' ); $total = dbFetchOne( 'SELECT count(*) AS Total FROM Logs', 'Total' );
$total = dbFetchOne( "SELECT count(*) AS Total FROM Logs", 'Total' );
$sql = 'SELECT * FROM Logs'; $sql = 'SELECT * FROM Logs';
$where = array(); $where = array();
$values = array(); $values = array();
if ( $minTime ) { if ( $minTime ) {
$where[] = "TimeKey > ?"; $where[] = "TimeKey > ?";
$values[] = $minTime; $values[] = $minTime;
} elseif ( $maxTime ) { } elseif ( $maxTime ) {
$where[] = "TimeKey < ?"; $where[] = "TimeKey < ?";
$values[] = $maxTime; $values[] = $maxTime;
} }
foreach ( $filter as $field=>$value ) { foreach ( $filter as $field=>$value ) {
if ( $field == 'Level' ){ if ( ! in_array( $field, $fileFields ) ) {
$where[] = $field." <= ?"; Error("$field is not in valid filter fields");
$values[] = $value; continue;
} else { }
$where[] = $field." = ?"; if ( $field == 'Level' ){
$values[] = $value; $where[] = $field." <= ?";
} $values[] = $value;
} } else {
if ( count($where) ) $where[] = $field." = ?";
$values[] = $value;
}
}
if ( count($where) )
$sql.= ' WHERE '.join( ' AND ', $where ); $sql.= ' WHERE '.join( ' AND ', $where );
$sql .= " order by ".$sortField." ".$sortOrder." limit ".$limit; $sql .= " order by ".$sortField." ".$sortOrder." limit ".$limit;
$logs = array(); $logs = array();
foreach ( dbFetchAll( $sql, NULL, $values ) as $log ) { foreach ( dbFetchAll( $sql, NULL, $values ) as $log ) {
$log['DateTime'] = preg_replace( '/^\d+/', strftime( "%Y-%m-%d %H:%M:%S", intval($log['TimeKey']) ), $log['TimeKey'] ); $log['DateTime'] = preg_replace( '/^\d+/', strftime( "%Y-%m-%d %H:%M:%S", intval($log['TimeKey']) ), $log['TimeKey'] );
$log['Server'] = ( $log['ServerId'] and isset($servers_by_Id[$log['ServerId']]) ) ? $servers_by_Id[$log['ServerId']]->Name() : ''; $log['Server'] = ( $log['ServerId'] and isset($servers_by_Id[$log['ServerId']]) ) ? $servers_by_Id[$log['ServerId']]->Name() : '';
$logs[] = $log; $logs[] = $log;
} }
$options = array(); $options = array();
$where = array(); $where = array();
$values = array(); $values = array();
foreach( $filter as $field=>$value ) { foreach( $filter as $field=>$value ) {
if ( $field == 'Level' ) { if ( $field == 'Level' ) {
$where[$field] = $field." <= ?"; $where[$field] = $field." <= ?";
$values[$field] = $value; $values[$field] = $value;
} else { } else {
$where[$field] = $field." = ?"; $where[$field] = $field." = ?";
$values[$field] = $value; $values[$field] = $value;
} }
} }
foreach( $filterFields as $field ) foreach( $filterFields as $field )
{ {
$sql = "SELECT DISTINCT $field FROM Logs WHERE NOT isnull($field)"; $sql = "SELECT DISTINCT $field FROM Logs WHERE NOT isnull($field)";
$fieldWhere = array_diff_key( $where, array( $field=>true ) ); $fieldWhere = array_diff_key( $where, array( $field=>true ) );
$fieldValues = array_diff_key( $values, array( $field=>true ) ); $fieldValues = array_diff_key( $values, array( $field=>true ) );
if ( count($fieldWhere) ) if ( count($fieldWhere) )
$sql.= " AND ".join( ' AND ', $fieldWhere ); $sql.= " AND ".join( ' AND ', $fieldWhere );
$sql.= " ORDER BY $field ASC"; $sql.= " ORDER BY $field ASC";
@ -147,8 +168,15 @@ switch ( $_REQUEST['task'] )
} }
//$limit = isset($_POST['limit'])?$_POST['limit']:1000; //$limit = isset($_POST['limit'])?$_POST['limit']:1000;
$filter = isset($_POST['filter'])?$_POST['filter']:array(); $filter = isset($_POST['filter'])?$_POST['filter']:array();
$sortField = isset($_POST['sortField'])?$_POST['sortField']:'TimeKey'; $sortField = 'TimeKey';
$sortOrder = isset($_POST['sortOrder'])?$_POST['sortOrder']:'asc'; if ( isset($_POST['sortField']) ) {
if ( ! in_array( $_POST['sortField'], $filterFields ) and ( $_POST['sortField'] != 'TimeKey' ) ) {
Error("Invalid sort field " . $_POST['sortField'] );
} else {
$sortField = $_POST['sortField']
}
}
$sortOrder = (isset($_POST['sortOrder']) and $_POST['sortOrder']) == 'asc' ? 'asc':'desc';
$servers = Server::find_all(); $servers = Server::find_all();
$servers_by_Id = array(); $servers_by_Id = array();
@ -216,7 +244,7 @@ switch ( $_REQUEST['task'] )
foreach ( dbFetchAll( $sql, NULL, $values ) as $log ) foreach ( dbFetchAll( $sql, NULL, $values ) as $log )
{ {
$log['DateTime'] = preg_replace( '/^\d+/', strftime( "%Y-%m-%d %H:%M:%S", intval($log['TimeKey']) ), $log['TimeKey'] ); $log['DateTime'] = preg_replace( '/^\d+/', strftime( "%Y-%m-%d %H:%M:%S", intval($log['TimeKey']) ), $log['TimeKey'] );
$log['Server'] = ( $log['ServerId'] and isset($servers_by_Id[$log['ServerId']]) ) ? $servers_by_Id[$log['ServerId']]->Name() : ''; $log['Server'] = ( $log['ServerId'] and isset($servers_by_Id[$log['ServerId']]) ) ? $servers_by_Id[$log['ServerId']]->Name() : '';
$logs[] = $log; $logs[] = $log;
} }
switch( $format ) switch( $format )

View File

@ -6,7 +6,7 @@ class Frame {
public function __construct( $IdOrRow ) { public function __construct( $IdOrRow ) {
$row = NULL; $row = NULL;
if ( $IdOrRow ) { if ( $IdOrRow ) {
if ( is_integer( $IdOrRow ) or is_numeric( $IdOrRow ) ) { if ( is_integer( $IdOrRow ) ) {
$row = dbFetchOne( 'SELECT * FROM Frames WHERE Id=?', NULL, array( $IdOrRow ) ); $row = dbFetchOne( 'SELECT * FROM Frames WHERE Id=?', NULL, array( $IdOrRow ) );
if ( ! $row ) { if ( ! $row ) {
Error("Unable to load Frame record for Id=" . $IdOrRow ); Error("Unable to load Frame record for Id=" . $IdOrRow );
@ -84,7 +84,15 @@ class Frame {
$values = array_values( $parameters ); $values = array_values( $parameters );
} }
if ( $limit ) { if ( $limit ) {
$sql .= ' LIMIT ' . $limit; if ( is_integer( $limit ) ) {
$sql .= ' LIMIT ' . $limit;
} else {
$backTrace = debug_backtrace();
$file = $backTrace[1]['file'];
$line = $backTrace[1]['line'];
Error("Invalid value for limit($limit) passed to Frame::find from $file:$line");
return;
}
} }
$results = dbFetchAll( $sql, NULL, $values ); $results = dbFetchAll( $sql, NULL, $values );
if ( $results ) { if ( $results ) {

View File

@ -63,9 +63,15 @@ class Server {
) ); ) );
$values = array_values( $parameters ); $values = array_values( $parameters );
} }
if ( $limit ) { if ( is_integer( $limit ) ) {
$sql .= ' LIMIT ' . $limit; $sql .= ' LIMIT ' . $limit;
} } else {
$backTrace = debug_backtrace();
$file = $backTrace[1]['file'];
$line = $backTrace[1]['line'];
Error("Invalid value for limit($limit) passed to Server::find from $file:$line");
return;
}
$results = dbFetchAll( $sql, NULL, $values ); $results = dbFetchAll( $sql, NULL, $values );
if ( $results ) { if ( $results ) {
return array_map( function($id){ return new Server($id); }, $results ); return array_map( function($id){ return new Server($id); }, $results );