Merge tag '4.7.17.4' into develop

4.7.17.4

# Conflicts:
#	config/firefly.php
#	resources/views/v1/transactions/convert.twig
This commit is contained in:
James Cole 2019-08-02 17:10:55 +02:00
commit 3435cb937c
No known key found for this signature in database
GPG Key ID: C16961E655E74B5E
10 changed files with 87 additions and 59 deletions

View File

@ -1,3 +1,7 @@
# 4.7.17.4 (API 0.9.2)
- Several XSS issues, found by [@dayn1ne](https://github.com/dayn1ne).
# 4.7.17.3 (API 0.9.2) # 4.7.17.3 (API 0.9.2)
- XSS bug in file uploads (x2), found by [@dayn1ne](https://github.com/dayn1ne). - XSS bug in file uploads (x2), found by [@dayn1ne](https://github.com/dayn1ne).

View File

@ -15,8 +15,8 @@ const pkgdef :Spk.PackageDefinition = (
manifest = ( manifest = (
appTitle = (defaultText = "Firefly III"), appTitle = (defaultText = "Firefly III"),
appVersion = 29, appVersion = 30,
appMarketingVersion = (defaultText = "4.7.17.3"), appMarketingVersion = (defaultText = "4.7.17.4"),
actions = [ actions = [
# Define your "new document" handlers here. # Define your "new document" handlers here.

View File

@ -1,7 +1,7 @@
sudo: required sudo: required
language: bash language: bash
env: env:
- VERSION=4.7.17.3 - VERSION=4.7.17.4
dist: xenial dist: xenial

View File

@ -125,7 +125,7 @@ class CreateController extends Controller
*/ */
public function createFromBill(Request $request, Bill $bill) public function createFromBill(Request $request, Bill $bill)
{ {
$request->session()->flash('info', (string)trans('firefly.instructions_rule_from_bill', ['name' => $bill->name])); $request->session()->flash('info', (string)trans('firefly.instructions_rule_from_bill', ['name' => e($bill->name)]));
$this->createDefaultRuleGroup(); $this->createDefaultRuleGroup();
$this->createDefaultRule(); $this->createDefaultRule();

View File

@ -60,6 +60,9 @@ class NewFinTSJobHandler implements FinTSConfigurationInterface
$config['fints_password'] = (string)(Crypt::encrypt($data['fints_password']) ?? ''); $config['fints_password'] = (string)(Crypt::encrypt($data['fints_password']) ?? '');
$config['apply-rules'] = 1 === (int)$data['apply_rules']; $config['apply-rules'] = 1 === (int)$data['apply_rules'];
// sanitize FinTS URL.
$config['fints_url'] = $this->validURI($config['fints_url']) ? $config['fints_url'] : '';
$this->repository->setConfiguration($this->importJob, $config); $this->repository->setConfiguration($this->importJob, $config);
$incomplete = false; $incomplete = false;
@ -107,4 +110,21 @@ class NewFinTSJobHandler implements FinTSConfigurationInterface
$this->repository->setUser($importJob->user); $this->repository->setUser($importJob->user);
} }
/**
* @param string $fints_url
*
* @return bool
*/
private function validURI(string $fintsUri): bool
{
$res = filter_var($fintsUri, FILTER_VALIDATE_URL);
if (false === $res) {
return false;
}
$scheme = parse_url($fintsUri, PHP_URL_SCHEME);
return 'https' === $scheme;
}
} }

View File

@ -2,6 +2,11 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/). This project adheres to [Semantic Versioning](http://semver.org/).
## [4.7.17.4 (API 0.9.2)] - 2019-08-02
### Security
- Several XSS issues, found by [@dayn1ne](https://github.com/dayn1ne).
## [4.7.17.3 (API 0.9.2)] - 2019-07-16 ## [4.7.17.3 (API 0.9.2)] - 2019-07-16
### Security ### Security

View File

@ -124,29 +124,29 @@ return [
'single_user_mode' => true, 'single_user_mode' => true,
'is_demo_site' => false, 'is_demo_site' => false,
], ],
'encryption' => null === env('USE_ENCRYPTION') || env('USE_ENCRYPTION') === true, 'encryption' => null === env('USE_ENCRYPTION') || env('USE_ENCRYPTION') === true,
'version' => '4.8.0', 'version' => '4.7.17.4',
'api_version' => '0.10.0', 'api_version' => '0.9.2',
'db_version' => 11, 'db_version' => 10,
'maxUploadSize' => 15242880, 'maxUploadSize' => 15242880,
'send_error_message' => env('SEND_ERROR_MESSAGE', true), 'send_error_message' => env('SEND_ERROR_MESSAGE', true),
'site_owner' => env('SITE_OWNER', ''), 'site_owner' => env('SITE_OWNER', ''),
'send_registration_mail' => env('SEND_REGISTRATION_MAIL', true), 'send_registration_mail' => env('SEND_REGISTRATION_MAIL', true),
'demo_username' => env('DEMO_USERNAME', ''), 'demo_username' => env('DEMO_USERNAME', ''),
'demo_password' => env('DEMO_PASSWORD', ''), 'demo_password' => env('DEMO_PASSWORD', ''),
'is_sandstorm' => env('IS_SANDSTORM', 'unknown'), 'is_sandstorm' => env('IS_SANDSTORM', 'unknown'),
'is_docker' => env('IS_DOCKER', 'unknown'), 'is_docker' => env('IS_DOCKER', 'unknown'),
'bunq_use_sandbox' => env('BUNQ_USE_SANDBOX', false), 'bunq_use_sandbox' => env('BUNQ_USE_SANDBOX', false),
'fixer_api_key' => env('FIXER_API_KEY', ''), 'fixer_api_key' => env('FIXER_API_KEY', ''),
'mapbox_api_key' => env('MAPBOX_API_KEY', ''), 'mapbox_api_key' => env('MAPBOX_API_KEY', ''),
'trusted_proxies' => env('TRUSTED_PROXIES', ''), 'trusted_proxies' => env('TRUSTED_PROXIES', ''),
'search_result_limit' => env('SEARCH_RESULT_LIMIT', 50), 'search_result_limit' => env('SEARCH_RESULT_LIMIT', 50),
'send_report_journals' => envNonEmpty('SEND_REPORT_JOURNALS', true), 'send_report_journals' => envNonEmpty('SEND_REPORT_JOURNALS', true),
'analytics_id' => env('ANALYTICS_ID', ''), 'analytics_id' => env('ANALYTICS_ID', ''),
'disable_frame_header' => env('DISABLE_FRAME_HEADER', false), 'disable_frame_header' => env('DISABLE_FRAME_HEADER', false),
'login_provider' => envNonEmpty('LOGIN_PROVIDER', 'eloquent'), 'login_provider' => envNonEmpty('LOGIN_PROVIDER', 'eloquent'),
'cer_provider' => envNonEmpty('CER_PROVIDER', 'fixer'), 'cer_provider' => envNonEmpty('CER_PROVIDER', 'fixer'),
'allowedMimes' => [ 'allowedMimes' => [
/* plain files */ /* plain files */
'text/plain', 'text/plain',

View File

@ -42,7 +42,7 @@
<em> <em>
{{ trans('firefly.no_audit_activity', {{ trans('firefly.no_audit_activity',
{ {
account_name: account.name, account_name: account.name|escape,
url: url, url: url,
start: start.formatLocalized(monthAndDayFormat), start: start.formatLocalized(monthAndDayFormat),
end: end.formatLocalized(monthAndDayFormat), end: end.formatLocalized(monthAndDayFormat),
@ -56,7 +56,7 @@
{{ trans('firefly.audit_end_balance', {{ trans('firefly.audit_end_balance',
{ {
account_name: account.name, account_name: account.name|escape,
url: url, url: url,
end: auditData[account.id].end, end: auditData[account.id].end,
balance: formatAmountByAccount(account,auditData[account.id].endBalance) balance: formatAmountByAccount(account,auditData[account.id].endBalance)
@ -67,7 +67,7 @@
<p style="padding:10px;"> <p style="padding:10px;">
{{ trans('firefly.audit_end_balance', {{ trans('firefly.audit_end_balance',
{ {
account_name: account.name, account_name: account.name|escape,
url: url, url: url,
end: auditData[account.id].dayBefore, end: auditData[account.id].dayBefore,
balance: formatAmountByAccount(account, auditData[account.id].dayBeforeBalance) balance: formatAmountByAccount(account, auditData[account.id].dayBeforeBalance)

View File

@ -284,14 +284,14 @@
{{ ExpandedForm.staticText('date', journal.date.formatLocalized(monthAndDayFormat)) }} {{ ExpandedForm.staticText('date', journal.date.formatLocalized(monthAndDayFormat)) }}
#} #}
{# in case of withdrawal #} {# in case of withdrawal #}
{#
{% if journalType.type == "Withdrawal" %} {% if sourceType.type == "Withdrawal" %}
{{ ExpandedForm.staticText('source_account_asset', '<a href="'~route('accounts.show',[sourceAccount.id])~'">'~sourceAccount.name~'</a>') }} {{ ExpandedForm.staticText('source_account_asset', '<a href="'~route('accounts.show',[sourceAccount.id])~'">'~sourceAccount.name|escape~'</a>') }}
<!-- if destination is cash, show (cash) --> {# if destination is cash, show (cash) #}
{% if destinationAccount.accountType.type == "Cash account" %} {% if destinationAccount.accountType.type == "Cash account" %}
{{ ExpandedForm.staticText('destination_account_expense', '<span class="text-success">(cash)</a>') }} {{ ExpandedForm.staticText('destination_account_expense', '<span class="text-success">(cash)</a>') }}
{% else %} {% else %}
{{ ExpandedForm.staticText('destination_account_expense', '<a href="'~route('accounts.show',[destinationAccount.id])~'">'~destinationAccount.name~'</a>') }} {{ ExpandedForm.staticText('destination_account_expense', '<a href="'~route('accounts.show',[destinationAccount.id])~'">'~destinationAccount.name|escape~'</a>') }}
{% endif %} {% endif %}
{% endif %} {% endif %}
@ -303,17 +303,16 @@
{% if sourceAccount.accountType.type == "Cash account" %} {% if sourceAccount.accountType.type == "Cash account" %}
{{ ExpandedForm.staticText('source_account_revenue', '<span class="text-success">(cash)</a>') }} {{ ExpandedForm.staticText('source_account_revenue', '<span class="text-success">(cash)</a>') }}
{% else %} {% else %}
{{ ExpandedForm.staticText('source_account_revenue', '<a href="'~route('accounts.show',[sourceAccount.id])~'">'~sourceAccount.name~'</a>') }} {{ ExpandedForm.staticText('source_account_revenue', '<a href="'~route('accounts.show',[sourceAccount.id])~'">'~sourceAccount.name|escape~'</a>') }}
{% endif %} {% endif %}
{{ ExpandedForm.staticText('destination_account_asset', '<a href="'~route('accounts.show',[destinationAccount.id])~'">'~destinationAccount.name~'</a>') }} {{ ExpandedForm.staticText('destination_account_asset', '<a href="'~route('accounts.show',[destinationAccount.id])~'">'~destinationAccount.name|escape~'</a>') }}
{% endif %} {% endif %}
#} #}
{# in case of transfer #} {# in case of transfer #}
{# {% if sourceType.type == "Transfer" %}
{% if journalType.type == "Transfer" %} {{ ExpandedForm.staticText('source_account_asset', '<a href="'~route('accounts.show',[sourceAccount.id])~'">'~sourceAccount.name|escape~'</a>') }}
{{ ExpandedForm.staticText('source_account_asset', '<a href="'~route('accounts.show',[sourceAccount.id])~'">'~sourceAccount.name~'</a>') }} {{ ExpandedForm.staticText('destination_account_asset', '<a href="'~route('accounts.show',[destinationAccount.id])~'">'~destinationAccount.name|escape~'</a>') }}
{{ ExpandedForm.staticText('destination_account_asset', '<a href="'~route('accounts.show',[destinationAccount.id])~'">'~destinationAccount.name~'</a>') }}
{% endif %} {% endif %}
#} #}
@ -328,9 +327,9 @@
{ {
amount: positiveAmount|formatAmount, amount: positiveAmount|formatAmount,
sourceRoute: route('accounts.show', [sourceAccount.id]), sourceRoute: route('accounts.show', [sourceAccount.id]),
sourceName: sourceAccount.name, sourceName: sourceAccount.name|escape,
destinationRoute: route('accounts.show', [destinationAccount.id]), destinationRoute: route('accounts.show', [destinationAccount.id]),
destinationName: destinationAccount.name, destinationName: destinationAccount.name|escape,
})|raw }} })|raw }}
</em> </em>
</p> </p>
@ -341,7 +340,7 @@
{% if destinationAccount.accountType.type == "Cash account" %} {% if destinationAccount.accountType.type == "Cash account" %}
{{ ExpandedForm.text('source_account_revenue', '') }} {{ ExpandedForm.text('source_account_revenue', '') }}
{% else %} {% else %}
{{ ExpandedForm.text('source_account_revenue', destinationAccount.name) }} {{ ExpandedForm.text('source_account_revenue', destinationAccount.name|escape) }}
{% endif %} {% endif %}
{% endif %} {% endif %}
#} #}
@ -353,9 +352,9 @@
{ {
amount: positiveAmount|formatAmount, amount: positiveAmount|formatAmount,
sourceRoute: route('accounts.show', [sourceAccount.id]), sourceRoute: route('accounts.show', [sourceAccount.id]),
sourceName: sourceAccount.name, sourceName: sourceAccount.name|escape,
destinationRoute: route('accounts.show', [destinationAccount.id]), destinationRoute: route('accounts.show', [destinationAccount.id]),
destinationName: destinationAccount.name, destinationName: destinationAccount.name|escape,
})|raw }} })|raw }}
</em></p> </em></p>
@ -378,9 +377,9 @@
{ {
amount: positiveAmount|formatAmount, amount: positiveAmount|formatAmount,
sourceRoute: route('accounts.show', [sourceAccount.id]), sourceRoute: route('accounts.show', [sourceAccount.id]),
sourceName: sourceAccount.name, sourceName: sourceAccount.name|escape,
destinationRoute: route('accounts.show', [destinationAccount.id]), destinationRoute: route('accounts.show', [destinationAccount.id]),
destinationName: destinationAccount.name, destinationName: destinationAccount.name|escape,
})|raw }} })|raw }}
</em> </em>
</p> </p>
@ -393,7 +392,7 @@
{% if sourceAccount.accountType.type == "Cash account" %} {% if sourceAccount.accountType.type == "Cash account" %}
{{ ExpandedForm.text('destination_account_expense', '') }} {{ ExpandedForm.text('destination_account_expense', '') }}
{% else %} {% else %}
{{ ExpandedForm.text('destination_account_expense', destinationAccount.name) }} {{ ExpandedForm.text('destination_account_expense', destinationAccount.name|escape) }}
{% endif %} {% endif %}
{% endif %} {% endif %}
@ -408,9 +407,9 @@
{ {
amount: positiveAmount|formatAmount, amount: positiveAmount|formatAmount,
sourceRoute: route('accounts.show', [sourceAccount.id]), sourceRoute: route('accounts.show', [sourceAccount.id]),
sourceName: sourceAccount.name, sourceName: sourceAccount.name|escape,
destinationRoute: route('accounts.show', [destinationAccount.id]), destinationRoute: route('accounts.show', [destinationAccount.id]),
destinationName: destinationAccount.name, destinationName: destinationAccount.name|escape,
})|raw }} })|raw }}
</em> </em>
</p> </p>
@ -433,9 +432,9 @@
{ {
amount: positiveAmount|formatAmount, amount: positiveAmount|formatAmount,
sourceRoute: route('accounts.show', [sourceAccount.id]), sourceRoute: route('accounts.show', [sourceAccount.id]),
sourceName: sourceAccount.name, sourceName: sourceAccount.name|escape,
destinationRoute: route('accounts.show', [destinationAccount.id]), destinationRoute: route('accounts.show', [destinationAccount.id]),
destinationName: destinationAccount.name, destinationName: destinationAccount.name|escape,
})|raw }} })|raw }}
</em> </em>
</p> </p>
@ -446,7 +445,7 @@
</em> </em>
</p> </p>
{{ ExpandedForm.text('destination_account_expense', destinationAccount.name) }} {{ ExpandedForm.text('destination_account_expense', destinationAccount.name|escape) }}
{% endif %} {% endif %}
#} #}
@ -461,9 +460,9 @@
{ {
amount: positiveAmount|formatAmount, amount: positiveAmount|formatAmount,
sourceRoute: route('accounts.show', [sourceAccount.id]), sourceRoute: route('accounts.show', [sourceAccount.id]),
sourceName: sourceAccount.name, sourceName: sourceAccount.name|escape,
destinationRoute: route('accounts.show', [destinationAccount.id]), destinationRoute: route('accounts.show', [destinationAccount.id]),
destinationName: destinationAccount.name, destinationName: destinationAccount.name|escape,
})|raw }} })|raw }}
</em> </em>
</p> </p>
@ -474,7 +473,7 @@
</em> </em>
</p> </p>
{{ ExpandedForm.text('source_account_revenue', sourceAccount.name) }} {{ ExpandedForm.text('source_account_revenue', sourceAccount.name|escape) }}
{% endif %} {% endif %}
#} #}

View File

@ -12,14 +12,14 @@
<div class="col-lg-6 col-lg-offset-3 col-md-6 col-sm-12"> <div class="col-lg-6 col-lg-offset-3 col-md-6 col-sm-12">
<div class="box box-danger"> <div class="box box-danger">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">{{ trans('firefly.delete_journal_link', {source: link.source.description, destination: link.destination.description, source_link: route('transactions.show', [link.source_id]) , destination_link: route('transactions.show',link.destination_id)})|raw }}</h3> <h3 class="box-title">{{ trans('firefly.delete_journal_link', {source: link.source.description|escape, destination: link.destination.description|escape, source_link: route('transactions.show', [link.source_id]) , destination_link: route('transactions.show',link.destination_id)})|raw }}</h3>
</div> </div>
<div class="box-body"> <div class="box-body">
<p class="text-danger"> <p class="text-danger">
{{ trans('form.permDeleteWarning') }} {{ trans('form.permDeleteWarning') }}
</p> </p>
<p> <p>
{{ trans('form.journal_link_areYouSure', {source: link.source.description, destination: link.destination.description, source_link: route('transactions.show', [link.source_id]) , destination_link: route('transactions.show',link.destination_id)})|raw }} {{ trans('form.journal_link_areYouSure', {source: link.source.description|escape, destination: link.destination.description|escape, source_link: route('transactions.show', [link.source_id]) , destination_link: route('transactions.show',link.destination_id)})|raw }}
</p> </p>
</div> </div>
<div class="box-footer"> <div class="box-footer">