Merge pull request #471 from ladybirdweb/hot-fix-patch

Hot fix patch
This commit is contained in:
Manish Verma
2017-05-15 18:53:28 +05:30
committed by GitHub
17 changed files with 153 additions and 101 deletions

View File

@@ -12,6 +12,7 @@ use Illuminate\Auth\Access\AuthorizationException;
// use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; // use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Foundation\Validation\ValidationException; use Illuminate\Foundation\Validation\ValidationException;
use Illuminate\Session\TokenMismatchException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class Handler extends ExceptionHandler class Handler extends ExceptionHandler
@@ -171,6 +172,8 @@ class Handler extends ExceptionHandler
// } else { // } else {
// return parent::render($request, $e); // return parent::render($request, $e);
// } // }
case $e instanceof TokenMismatchException:
return redirect()->back()->with('fails', \Lang::get('lang.session-expired'));
default: default:
return $this->render500($request, $e); return $this->render500($request, $e);
} }

View File

@@ -9,8 +9,8 @@ use App\Model\helpdesk\Ticket\Ticket_Thread;
use Config; use Config;
use Storage; use Storage;
class StorageController extends Controller class StorageController extends Controller {
{
protected $default; protected $default;
protected $driver; protected $driver;
protected $root; protected $root;
@@ -25,8 +25,7 @@ class StorageController extends Controller
protected $rackspace_endpoint; protected $rackspace_endpoint;
protected $rackspace_url_type; protected $rackspace_url_type;
public function __construct() public function __construct() {
{
$this->default = $this->defaults(); $this->default = $this->defaults();
$this->driver = $this->driver(); $this->driver = $this->driver();
$this->root = $this->root(); $this->root = $this->root();
@@ -41,8 +40,7 @@ class StorageController extends Controller
$this->rackspace_username = $this->rackspaceUsername(); $this->rackspace_username = $this->rackspaceUsername();
} }
protected function settings($option) protected function settings($option) {
{
$settings = new CommonSettings(); $settings = new CommonSettings();
$setting = $settings->getOptionValue('storage', $option); $setting = $settings->getOptionValue('storage', $option);
$value = ''; $value = '';
@@ -53,8 +51,7 @@ class StorageController extends Controller
return $value; return $value;
} }
public function defaults() public function defaults() {
{
$default = 'local'; $default = 'local';
if ($this->settings('default')) { if ($this->settings('default')) {
$default = $this->settings('default'); $default = $this->settings('default');
@@ -63,13 +60,11 @@ class StorageController extends Controller
return $default; return $default;
} }
public function driver() public function driver() {
{
return $this->settings('default'); return $this->settings('default');
} }
public function root() public function root() {
{
$root = storage_path('app'); $root = storage_path('app');
if ($this->settings('root')) { if ($this->settings('root')) {
$root = $this->settings('root'); $root = $this->settings('root');
@@ -78,58 +73,47 @@ class StorageController extends Controller
return $root; return $root;
} }
public function s3Key() public function s3Key() {
{
return $this->settings('s3_key'); return $this->settings('s3_key');
} }
public function s3Region() public function s3Region() {
{
return $this->settings('s3_region'); return $this->settings('s3_region');
} }
public function s3Secret() public function s3Secret() {
{
return $this->settings('s3_secret'); return $this->settings('s3_secret');
} }
public function s3Bucket() public function s3Bucket() {
{
return $this->settings('s3_bucket'); return $this->settings('s3_bucket');
} }
public function rackspaceKey() public function rackspaceKey() {
{
return $this->settings('root'); return $this->settings('root');
} }
public function rackspaceRegion() public function rackspaceRegion() {
{
return $this->settings('rackspace_region'); return $this->settings('rackspace_region');
} }
public function rackspaceUsername() public function rackspaceUsername() {
{
return $this->settings('rackspace_username'); return $this->settings('rackspace_username');
} }
public function rackspaceContainer() public function rackspaceContainer() {
{
return $this->settings('rackspace_container'); return $this->settings('rackspace_container');
} }
public function rackspaceEndpoint() public function rackspaceEndpoint() {
{
return $this->settings('rackspace_endpoint'); return $this->settings('rackspace_endpoint');
} }
public function rackspaceUrlType() public function rackspaceUrlType() {
{
return $this->settings('rackspace_url_type'); return $this->settings('rackspace_url_type');
} }
protected function setFileSystem() protected function setFileSystem() {
{
$config = $this->config(); $config = $this->config();
//dd($config); //dd($config);
foreach ($config as $key => $con) { foreach ($config as $key => $con) {
@@ -144,43 +128,40 @@ class StorageController extends Controller
return Config::get('filesystem'); return Config::get('filesystem');
} }
protected function config() protected function config() {
{
return [ return [
'default' => $this->default, 'default' => $this->default,
'cloud' => 's3', 'cloud' => 's3',
'disks' => $this->disks(), 'disks' => $this->disks(),
]; ];
} }
protected function disks() protected function disks() {
{
return [ return [
'local' => [ 'local' => [
'driver' => 'local', 'driver' => 'local',
'root' => $this->root.'/attachments', 'root' => $this->root . '/attachments',
], ],
's3' => [ 's3' => [
'driver' => 's3', 'driver' => 's3',
'key' => $this->s3_key, 'key' => $this->s3_key,
'secret' => $this->s3_secret, 'secret' => $this->s3_secret,
'region' => $this->s3_region, 'region' => $this->s3_region,
'bucket' => $this->s3_bucket, 'bucket' => $this->s3_bucket,
], ],
'rackspace' => [ 'rackspace' => [
'driver' => 'rackspace', 'driver' => 'rackspace',
'username' => $this->rackspace_username, 'username' => $this->rackspace_username,
'key' => $this->rackspace_key, 'key' => $this->rackspace_key,
'container' => $this->rackspace_container, 'container' => $this->rackspace_container,
'endpoint' => $this->rackspace_endpoint, 'endpoint' => $this->rackspace_endpoint,
'region' => $this->rackspace_region, 'region' => $this->rackspace_region,
'url_type' => $this->rackspace_url_type, 'url_type' => $this->rackspace_url_type,
], ],
]; ];
} }
public function upload($data, $filename, $type, $size, $disposition, $thread_id) public function upload($data, $filename, $type, $size, $disposition, $thread_id) {
{
$upload = new Ticket_attachments(); $upload = new Ticket_attachments();
$upload->thread_id = $thread_id; $upload->thread_id = $thread_id;
$upload->name = $filename; $upload->name = $filename;
@@ -188,10 +169,14 @@ class StorageController extends Controller
$upload->size = $size; $upload->size = $size;
$upload->poster = $disposition; $upload->poster = $disposition;
$upload->driver = $this->default; $upload->driver = $this->default;
$upload->path = $this->root; $upload->path = $this->root. DIRECTORY_SEPARATOR.'attachments';
if ($this->default !== 'database') { if ($this->default !== 'database') {
$this->setFileSystem(); $this->setFileSystem();
Storage::disk($this->default)->put($filename, $data); Storage::disk($this->default)->put($filename, $data);
$storagePath = Storage::disk($this->default)->getDriver()->getAdapter()->getPathPrefix() . $filename;
if (mime(\File::mimeType($storagePath)) != 'image' || mime(\File::extension($storagePath)) != 'image') {
chmod($storagePath, 1204);
}
} else { } else {
$upload->file = $data; $upload->file = $data;
} }
@@ -200,51 +185,67 @@ class StorageController extends Controller
} }
} }
public function saveAttachments($thread_id, $attachments = []) public function saveAttachments($thread_id, $attachments = []) {
{ $disposition = 'ATTACHMENT';
if (is_array($attachments) && count($attachments) > 0) { $thread = '';
foreach ($attachments as $attachment) { foreach ($attachments as $attachment) {
if (is_object($attachment)) {
if (method_exists($attachment, 'getStructure')) {
$structure = $attachment->getStructure();
if (isset($structure->disposition)) {
$disposition = $structure->disposition;
}
$filename = rand(1111, 9999) . "_" . $attachment->getFileName();
$type = $attachment->getMimeType();
$size = $attachment->getSize();
$data = $attachment->getData();
} else {
$filename = rand(1111, 9999) . "_" . $attachment->getClientOriginalName();
$type = $attachment->getMimeType();
$size = $attachment->getSize();
$data = file_get_contents($attachment->getRealPath());
}
$this->upload($data, $filename, $type, $size, $disposition, $thread_id);
$thread = $this->updateBody($attachment, $thread_id, $filename);
}
}
return $thread;
}
public function updateBody($attachment, $thread_id, $filename) {
$threads = new Ticket_Thread();
$thread = $threads->find($thread_id);
$disposition = 'ATTACHMENT';
if (is_object($attachment)) {
if (method_exists($attachment, 'getStructure')) {
$structure = $attachment->getStructure(); $structure = $attachment->getStructure();
$disposition = 'ATTACHMENT';
if (isset($structure->disposition)) { if (isset($structure->disposition)) {
$disposition = $structure->disposition; $disposition = $structure->disposition;
} }
$filename = str_random(16).'-'.$attachment->getFileName();
$type = $attachment->getMimeType();
$size = $attachment->getSize();
$data = $attachment->getData();
$this->upload($data, $filename, $type, $size, $disposition, $thread_id);
$this->updateBody($attachment, $thread_id, $filename);
} }
} }
}
public function updateBody($attachment, $thread_id, $filename)
{
$structure = $attachment->getStructure();
$disposition = 'ATTACHMENT';
if (isset($structure->disposition)) {
$disposition = $structure->disposition;
}
if ($disposition == 'INLINE' || $disposition == 'inline') { if ($disposition == 'INLINE' || $disposition == 'inline') {
$id = str_replace('>', '', str_replace('<', '', $structure->id)); $id = str_replace('>', '', str_replace('<', '', $structure->id));
$threads = new Ticket_Thread();
$thread = $threads->find($thread_id);
$body = $thread->body; $body = $thread->body;
$body = str_replace('cid:'.$id, $filename, $body); // dd($id,$filename,$body);
$body = str_replace('cid:' . $id, $filename, $body);
// dd($body);
$thread->body = $body; $thread->body = $body;
$thread->save(); $thread->save();
} }
return $thread;
} }
public function getFile($drive, $name) public function getFile($drive, $name, $root) {
{ if ($drive != "database") {
//dd($drive,$name); $root = $root . DIRECTORY_SEPARATOR . $name;
if ($drive != 'database') { if (\File::exists($root)) {
$this->setFileSystem(); chmod($root, 0755);
if (Storage::disk($this->default)->exists($name)) { return \File::get($root);
return Storage::disk($this->default)->get($name);
} }
} }
} }
} }

View File

@@ -764,10 +764,12 @@ class UserController extends Controller
if (Input::file('profile_pic')) { if (Input::file('profile_pic')) {
// fetching picture name // fetching picture name
$name = Input::file('profile_pic')->getClientOriginalName(); $name = Input::file('profile_pic')->getClientOriginalName();
// dd($name);
// dd(str_replace(" ", "_", $name));
// fetching upload destination path // fetching upload destination path
$destinationPath = 'uploads/profilepic'; $destinationPath = 'uploads/profilepic';
// adding a random value to profile picture filename // adding a random value to profile picture filename
$fileName = rand(0000, 9999).'.'.$name; $fileName = rand(0000, 9999).'.'.str_replace(" ", "_", $name);
// moving the picture to a destination folder // moving the picture to a destination folder
Input::file('profile_pic')->move($destinationPath, $fileName); Input::file('profile_pic')->move($destinationPath, $fileName);
// saving filename to database // saving filename to database

View File

@@ -229,16 +229,18 @@ class FormController extends Controller
$ticketId = Tickets::where('ticket_number', '=', $result[0])->first(); $ticketId = Tickets::where('ticket_number', '=', $result[0])->first();
$thread = Ticket_Thread::where('ticket_id', '=', $ticketId->id)->first(); $thread = Ticket_Thread::where('ticket_id', '=', $ticketId->id)->first();
if ($attachments != null) { if ($attachments != null) {
foreach ($attachments as $attachment) { $storage = new \App\FaveoStorage\Controllers\StorageController();
if ($attachment != null) { $storage->saveAttachments($thread->id, $attachments);
$name = $attachment->getClientOriginalName(); // foreach ($attachments as $attachment) {
$type = $attachment->getClientOriginalExtension(); // if ($attachment != null) {
$size = $attachment->getSize(); // $name = $attachment->getClientOriginalName();
$data = file_get_contents($attachment->getRealPath()); // $type = $attachment->getClientOriginalExtension();
$attachPath = $attachment->getRealPath(); // $size = $attachment->getSize();
$ta->create(['thread_id' => $thread->id, 'name' => $name, 'size' => $size, 'type' => $type, 'file' => $data, 'poster' => 'ATTACHMENT']); // $data = file_get_contents($attachment->getRealPath());
} // $attachPath = $attachment->getRealPath();
} // $ta->create(['thread_id' => $thread->id, 'name' => $name, 'size' => $size, 'type' => $type, 'file' => $data, 'poster' => 'ATTACHMENT']);
// }
// }
} }
// dd($result); // dd($result);
return Redirect::back()->with('success', Lang::get('lang.Ticket-has-been-created-successfully-your-ticket-number-is').' '.$result[0].'. '.Lang::get('lang.Please-save-this-for-future-reference')); return Redirect::back()->with('success', Lang::get('lang.Ticket-has-been-created-successfully-your-ticket-number-is').' '.$result[0].'. '.Lang::get('lang.Please-save-this-for-future-reference'));
@@ -246,6 +248,7 @@ class FormController extends Controller
return Redirect::back()->withInput($request->except('password'))->with('fails', Lang::get('lang.failed-to-create-user-tcket-as-mobile-has-been-taken')); return Redirect::back()->withInput($request->except('password'))->with('fails', Lang::get('lang.failed-to-create-user-tcket-as-mobile-has-been-taken'));
} }
} catch (\Exception $ex) { } catch (\Exception $ex) {
dd($ex);
return redirect()->back()->with('fails', $ex->getMessage()); return redirect()->back()->with('fails', $ex->getMessage());
} }
// dd($result); // dd($result);

View File

@@ -101,7 +101,7 @@ class GuestController extends Controller
// fetching upload destination path // fetching upload destination path
$destinationPath = 'uploads/profilepic'; $destinationPath = 'uploads/profilepic';
// adding a random value to profile picture filename // adding a random value to profile picture filename
$fileName = rand(0000, 9999).'.'.$name; $fileName = rand(0000, 9999).'.'.str_replace(" ", "_", $name);
// moving the picture to a destination folder // moving the picture to a destination folder
Input::file('profile_pic')->move($destinationPath, $fileName); Input::file('profile_pic')->move($destinationPath, $fileName);
// saving filename to database // saving filename to database

View File

@@ -4,9 +4,21 @@ namespace App\Http\Middleware;
use Closure; use Closure;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier; use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
use Lang;
class VerifyCsrfToken extends BaseVerifier class VerifyCsrfToken extends BaseVerifier
{ {
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array
*/
protected $except = [
'CheckSerial',
'api/v1/*'
];
/** /**
* Handle an incoming request. * Handle an incoming request.
* *

View File

@@ -25,13 +25,20 @@ class Ticket_attachments extends Model
$drive = $this->driver; $drive = $this->driver;
$name = $this->name; $name = $this->name;
$root = $this->path; $root = $this->path;
if (($drive == 'database' || !$drive) && $value && base64_decode($value, true) === false) { if (($drive == 'database' || !$drive) && $value && base64_decode($value, true) === false) {
$value = base64_encode($value); $value = base64_encode($value);
} }
if ($drive && $drive !== 'database') { if ($drive && $drive !== 'database') {
$storage = new \App\FaveoStorage\Controllers\StorageController(); $storage = new \App\FaveoStorage\Controllers\StorageController();
$content = $storage->getFile($drive, $name); $content = $storage->getFile($drive, $name, $root);
$value = base64_encode($content); if ($content) {
$value = base64_encode($content);
if (mime($this->type) != 'image') {
$root = $root . "/" . $name;
chmod($root, 1204);
}
}
} }
return $value; return $value;
@@ -52,7 +59,6 @@ class Ticket_attachments extends Model
return '<li style="background-color:#f4f4f4;"><span class="mailbox-attachment-icon has-img">'.$var.'</span><div class="mailbox-attachment-info"><b style="word-wrap: break-word;">'.$this->name.'</b><br/><p>'.$value.'</p></div></li>'; return '<li style="background-color:#f4f4f4;"><span class="mailbox-attachment-icon has-img">'.$var.'</span><div class="mailbox-attachment-info"><b style="word-wrap: break-word;">'.$this->name.'</b><br/><p>'.$value.'</p></div></li>';
} else { } else {
//$var = '<a href="' . URL::route('image', array('image_id' => $attachment->id)) . '" target="_blank"><img style="max-width:200px;height:133px;" src="data:'.$attachment->type.';base64,' . base64_encode($data) . '"/></a>';
$var = '<a style="max-width:200px;height:133px;color:#666;" href="'.\URL::route('image', ['image_id' => $this->id]).'" target="_blank"><span class="mailbox-attachment-icon" style="background-color:#fff; font-size:18px;">'.strtoupper(str_limit($this->type, 15)).'</span><div class="mailbox-attachment-info"><span ><b style="word-wrap: break-word;">'.$this->name.'</b><br/><p>'.$value.'</p></span></div></a>'; $var = '<a style="max-width:200px;height:133px;color:#666;" href="'.\URL::route('image', ['image_id' => $this->id]).'" target="_blank"><span class="mailbox-attachment-icon" style="background-color:#fff; font-size:18px;">'.strtoupper(str_limit($this->type, 15)).'</span><div class="mailbox-attachment-info"><span ><b style="word-wrap: break-word;">'.$this->name.'</b><br/><p>'.$value.'</p></span></div></a>';
return '<li style="background-color:#f4f4f4;">'.$var.'</li>'; return '<li style="background-color:#f4f4f4;">'.$var.'</li>';

View File

@@ -44,13 +44,18 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
if ($info) { if ($info) {
$pic = $this->checkArray('avatar', $info); $pic = $this->checkArray('avatar', $info);
} }
if (!$pic) { if (!$pic && $value) {
$pic = asset('uploads/profilepic/'.$value); $pic = "";
$file = asset('uploads/profilepic/' . $value);
if ($file) {
$type = pathinfo($file, PATHINFO_EXTENSION);
$data = file_get_contents($file);
$pic = 'data:image/' . $type . ';base64,' . base64_encode($data);
}
} }
if (!$value) { if (!$value) {
$pic = \Gravatar::src($this->attributes['email']); $pic = \Gravatar::src($this->attributes['email']);
} }
return $pic; return $pic;
} }

View File

@@ -33,7 +33,7 @@ return [
| This tells about aplication current version. | This tells about aplication current version.
| |
*/ */
'version' => 'Community 1.9.4', 'version' => 'Community 1.9.5',
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Application Name | Application Name

View File

@@ -21,6 +21,13 @@
| | | || | | || | | || | | || | | || | | || | | || | | | | | | || | | || | | || | | || | | || | | || | | || | | |
| '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' | | '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' |
'----------------' '----------------' '----------------' '----------------' '----------------' '----------------' '----------------' '----------------' '----------------' '----------------' '----------------' '----------------' '----------------' '----------------' '----------------' '----------------'
|=====================================================
| v1.9.5 (security hot fixt patch2)
|=====================================================
## Bug Fixed
Prevents execution of backdoor scripts
Prevents users from uploading PHP files into user's profile picture
Handling token mismatch error when the page is opened for too long and session gets expired
|===================================================== |=====================================================
| v1.9.4 (security hot fixt patch) | v1.9.4 (security hot fixt patch)

View File

@@ -1157,5 +1157,6 @@ return [
'search' => 'Search...', 'search' => 'Search...',
//update 21-12-2016 //update 21-12-2016
'selected-user-is-already-the-owner' => 'Selected user is already the owner of this ticket.', 'selected-user-is-already-the-owner' => 'Selected user is already the owner of this ticket.',
//updated 15-5-2017
'session-expired' => 'Session expired or invalid, please try again.',
]; ];

View File

@@ -1594,4 +1594,6 @@ return [
'search' => 'Search...', 'search' => 'Search...',
//update 21-12-2016 //update 21-12-2016
'selected-user-is-already-the-owner' => 'Selected user is already the owner of this ticket.', 'selected-user-is-already-the-owner' => 'Selected user is already the owner of this ticket.',
//updated 15-5-2017
'session-expired' => 'Session expired or invalid, please try again.',
]; ];

View File

@@ -1565,5 +1565,7 @@ return [
'search' => 'Rechercher...', 'search' => 'Rechercher...',
//update 21-12-2016 //update 21-12-2016
'selected-user-is-already-the-owner' => 'L\'utilisateur sélectionné est déjà le propriétaire du ticket.', 'selected-user-is-already-the-owner' => 'L\'utilisateur sélectionné est déjà le propriétaire du ticket.',
//updated 15-5-2017
'session-expired' => 'Session expired or invalid, please try again.',
]; ];

View File

@@ -1117,4 +1117,6 @@ return [
'search' => 'Search...', 'search' => 'Search...',
//update 21-12-2016 //update 21-12-2016
'selected-user-is-already-the-owner' => 'Selected user is already the owner of this ticket.', 'selected-user-is-already-the-owner' => 'Selected user is already the owner of this ticket.',
//updated 15-5-2017
'session-expired' => 'Session expired or invalid, please try again.',
]; ];

View File

@@ -1611,4 +1611,6 @@ return [
'search' => 'Search...', 'search' => 'Search...',
//update 21-12-2016 //update 21-12-2016
'selected-user-is-already-the-owner' => 'Selected user is already the owner of this ticket.', 'selected-user-is-already-the-owner' => 'Selected user is already the owner of this ticket.',
//updated 15-5-2017
'session-expired' => 'Session expired or invalid, please try again.',
]; ];

View File

@@ -1556,5 +1556,7 @@ return [
'search' => 'Search...', 'search' => 'Search...',
//update 21-12-2016 //update 21-12-2016
'selected-user-is-already-the-owner' => 'Selected user is already the owner of this ticket.', 'selected-user-is-already-the-owner' => 'Selected user is already the owner of this ticket.',
//updated 15-5-2017
'session-expired' => 'Session expired or invalid, please try again.',
]; ];

View File

@@ -1065,4 +1065,6 @@ return [
'search' => 'Search...', 'search' => 'Search...',
//update 21-12-2016 //update 21-12-2016
'selected-user-is-already-the-owner' => 'Selected user is already the owner of this ticket.', 'selected-user-is-already-the-owner' => 'Selected user is already the owner of this ticket.',
//updated 15-5-2017
'session-expired' => 'Session expired or invalid, please try again.',
]; ];