Moderate severityNVD Advisory· Published Nov 13, 2021· Updated Aug 3, 2024
Cross-Site Request Forgery (CSRF) in firefly-iii/firefly-iii
CVE-2021-3921
Description
firefly-iii is vulnerable to Cross-Site Request Forgery (CSRF)
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
grumpydictator/firefly-iiiPackagist | < 5.6.3 | 5.6.3 |
Affected products
1- Range: unspecified
Patches
147fa9e39561aFix huntr.dev logout issue.
9 files changed · +27 −14
resources/views/v1/auth/login.twig+3 −3 modified@@ -61,7 +61,7 @@ <div class="login-box-body"> <p class="login-box-msg">{{ 'sign_in_to_start'|_ }}</p> - <form action="{{ URL.to('/login') }}" method="post"> + <form action="{{ route('login') }}" method="post"> <input type="hidden" name="_token" value="{{ csrf_token() }}"/> <div class="form-group has-feedback"> @@ -88,10 +88,10 @@ </div> </form> {% if allowRegistration %} - <a href="{{ URL.to('/register') }}" class="text-center">{{ 'register_new_account'|_ }}</a><br> + <a href="{{ route('register') }}" class="text-center">{{ 'register_new_account'|_ }}</a><br> {% endif %} {% if allowReset %} - <a href="{{ URL.to('/password/reset') }}">{{ 'forgot_my_password'|_ }}</a> + <a href="{{ route('password.reset.request') }}">{{ 'forgot_my_password'|_ }}</a> {% endif %} </div> {% endblock %}
resources/views/v1/auth/passwords/email.twig+2 −2 modified@@ -27,7 +27,7 @@ {% else %} <p class="login-box-msg">{{ 'reset_password'|_ }}</p> - <form role="form" method="POST" action="{{ URL.to('/password/email') }}"> + <form role="form" method="POST" action="{{ route('password.email') }}"> <input type="hidden" name="_token" value="{{ csrf_token() }}"/> <div class="form-group has-feedback"> @@ -43,7 +43,7 @@ </form> {% endif %} - <a href="{{ URL.to('/login') }}">{{ 'want_to_login'|_ }}</a><br> + <a href="{{ route('login') }}">{{ 'want_to_login'|_ }}</a><br> {% if allowRegistration %} <a href="{{ route('register') }}" class="text-center">{{ 'register_new_account'|_ }}</a><br> {% endif %}
resources/views/v1/auth/passwords/reset.twig+1 −1 modified@@ -40,7 +40,7 @@ </form> - <a href="{{ URL.to('/login') }}">{{ 'want_to_login'|_ }}</a><br> + <a href="{{ route('login') }}">{{ 'want_to_login'|_ }}</a><br> {% if allowRegistration %} <a href="{{ route('register') }}" class="text-center">{{ 'register_new_account'|_ }}</a><br> {% endif %}
resources/views/v1/auth/register.twig+3 −3 modified@@ -15,7 +15,7 @@ <div class="register-box-body"> <p class="login-box-msg">{{ 'register_new_account'|_ }}</p> - <form id="register" method="POST" action="{{ URL.to('/register') }}"> + <form id="register" method="POST" action="{{ route('register') }}"> <input type="hidden" name="_token" value="{{ csrf_token() }}"> <div class="form-group has-feedback"> @@ -41,8 +41,8 @@ </div> </form> - <a href="{{ URL.to('/login') }}">{{ 'want_to_login'|_ }}</a><br> - <a href="{{ URL.to('/password/reset') }}">{{ 'forgot_my_password'|_ }}</a> + <a href="{{ route('login') }}">{{ 'want_to_login'|_ }}</a><br> + <a href="{{ route('password.reset.request') }}">{{ 'forgot_my_password'|_ }}</a> </div> {% include 'v1.partials.password-modal' %}
resources/views/v1/partials/menu-sidebar.twig+6 −1 modified@@ -221,9 +221,14 @@ {% endif %} </ul> </li> + + {% if 'remote_user_guard' != authGuard or '' != logoutUri %} + <form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;"> + <input type="hidden" name="_token" value="{{ csrf_token() }}" /> + </form> <li> - <a href="{{ route('logout') }}"> + <a href="{{ route('logout') }}" onclick="event.preventDefault();document.getElementById('logout-form').submit();"> <span class="fa fa-sign-out fa-fw"></span> <span>{{ 'logout'|_ }}</span> </a>
resources/views/v1/profile/index.twig+6 −1 modified@@ -52,7 +52,12 @@ <a href="{{ route('profile.change-password') }}">{{ 'change_your_password'|_ }}</a> </li> {% endif %} - <li><a href="{{ route('logout') }}">{{ 'logout'|_ }}</a></li> + + <form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;"> + <input type="hidden" name="_token" value="{{ csrf_token() }}" /> + </form> + + <li><a href="{{ route('logout') }}" onclick="event.preventDefault();document.getElementById('logout-form').submit();">{{ 'logout'|_ }}</a></li> {% if true == isInternalAuth and true == isInternalIdentity %} <li>
resources/views/v2/auth/register.twig+1 −1 modified@@ -86,7 +86,7 @@ </a> </li> <li> - <a href="{{ URL.to('/login') }}">{{ 'want_to_login'|_ }}</a> + <a href="{{ route('login') }}">{{ 'want_to_login'|_ }}</a> </li> <li> <a href="{{ route('password.reset.request') }}">{{ 'forgot_my_password'|_ }}</a>
resources/views/v2/partials/layout/navbar.twig+4 −1 modified@@ -50,6 +50,9 @@ </li> <!-- Notifications Dropdown Menu --> <li class="nav-item dropdown"> + <form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;"> + <input type="hidden" name="_token" value="{{ csrf_token() }}" /> + </form> <a class="nav-link" data-toggle="dropdown" href="#"> <span class="far fa-user"></span> </a> @@ -62,7 +65,7 @@ <span class="fas fa-fw fa-cogs mr-2"></span> {{ 'preferences'|_ }} </a> <div class="dropdown-divider"></div> - <a href="{{ route('logout') }}" class="dropdown-item"> + <a href="{{ route('logout') }}" class="dropdown-item" onclick="event.preventDefault();document.getElementById('logout-form').submit();"> <span class="fas fa-sign-out-alt mr-2"></span> {{ 'logout'|_ }} </a> </div>
routes/web.php+1 −1 modified@@ -81,7 +81,7 @@ static function () { ['middleware' => 'user-simple-auth', 'namespace' => 'FireflyIII\Http\Controllers'], static function () { Route::get('error', ['uses' => 'DebugController@displayError', 'as' => 'error']); - Route::any('logout', ['uses' => 'Auth\LoginController@logout', 'as' => 'logout']); + Route::post('logout', ['uses' => 'Auth\LoginController@logout', 'as' => 'logout']); Route::get('flush', ['uses' => 'DebugController@flush', 'as' => 'flush']); //Route::get('routes', ['uses' => 'DebugController@routes', 'as' => 'routes']); Route::get('debug', 'DebugController@index')->name('debug');
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/advisories/GHSA-q2cv-94xm-qvg4ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2021-3921ghsaADVISORY
- github.com/firefly-iii/firefly-iii/commit/47fa9e39561a9ec9e210e4023d090a7b33381684ghsax_refsource_MISCWEB
- huntr.dev/bounties/724d3fd5-9f04-45c4-98d6-35a7d15468f5ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.