VYPR
Moderate severityNVD Advisory· Published Jul 18, 2019· Updated Aug 4, 2024

CVE-2019-13647

CVE-2019-13647

Description

Firefly III before 4.7.17.3 is vulnerable to stored XSS due to lack of filtration of user-supplied data in image file content. The JavaScript code is executed during attachments/view/$file_id$ attachment viewing. NOTE: It is asserted that an attacker must have the same access rights as the user in order to be able to execute the vulnerability

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Firefly III before 4.7.17.3 is vulnerable to stored XSS via malicious SVG files, allowing arbitrary JavaScript execution when viewing attachments.

Vulnerability

Firefly III versions prior to 4.7.17.3 are susceptible to stored cross-site scripting (XSS) due to insufficient sanitization of user-supplied image file content. An attacker can upload a specially crafted SVG file containing embedded JavaScript code. When the attachment is viewed via the /attachments/view/{id} endpoint, the browser renders the SVG and executes the malicious script [1][4].

Exploitation

To exploit this vulnerability, an attacker must have user-level access to the Firefly III instance and the ability to upload attachments (e.g., to a transaction). The attacker uploads an SVG file with embedded JavaScript, such as the proof-of-concept provided in the issue report [4]. Any user who subsequently views that attachment will trigger the XSS payload. The attacker does not need elevated privileges beyond those of a regular user, but the attack requires the victim to view the malicious attachment [1].

Impact

Successful exploitation allows the attacker to execute arbitrary JavaScript in the context of the victim's session. This can lead to session hijacking, data exfiltration, or unauthorized actions performed on behalf of the victim. The vulnerability is classified as stored XSS with a CVSS score yet to be assigned by NVD, but the impact is significant for affected installations [1].

Mitigation

The issue was addressed in Firefly III version 4.7.17.3. The fix introduces a Content-Security-Policy (CSP) header that restricts script execution, style, and other resources when viewing attachments, effectively preventing the injected JavaScript from running [2]. Users are strongly advised to upgrade to the latest version to mitigate this vulnerability.

AI Insight generated on May 22, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
grumpydictator/firefly-iiiPackagist
< 4.7.17.34.7.17.3

Affected products

2

Patches

1
531161db0902

Fixes #2338

https://github.com/firefly-iii/firefly-iiiJames ColeJul 16, 2019via ghsa
2 files changed · +24 6
  • app/Http/Controllers/AttachmentController.php+18 4 modified
    @@ -78,7 +78,7 @@ public function delete(Attachment $attachment)
         /**
          * Destroy attachment.
          *
    -     * @param Request    $request
    +     * @param Request $request
          * @param Attachment $attachment
          *
          * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
    @@ -131,7 +131,7 @@ public function download(Attachment $attachment)
         /**
          * Edit an attachment.
          *
    -     * @param Request    $request
    +     * @param Request $request
          * @param Attachment $attachment
          *
          * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
    @@ -178,7 +178,7 @@ function (Attachment $attachment) {
          * Update attachment.
          *
          * @param AttachmentFormRequest $request
    -     * @param Attachment            $attachment
    +     * @param Attachment $attachment
          *
          * @return RedirectResponse
          */
    @@ -211,13 +211,27 @@ public function update(AttachmentFormRequest $request, Attachment $attachment):
          * @return LaravelResponse
          * @throws FireflyException
          */
    -    public function view(Attachment $attachment): LaravelResponse
    +    public function view(Request $request, Attachment $attachment): LaravelResponse
         {
             if ($this->repository->exists($attachment)) {
                 $content = $this->repository->getContent($attachment);
     
    +            // prevent XSS by adding a new secure header.
    +            $csp = [
    +                "default-src 'none'",
    +                "object-src 'none'",
    +                "script-src 'none'",
    +                "style-src 'none'",
    +                "base-uri 'none'",
    +                "font-src 'none'",
    +                "connect-src 'none'",
    +                "img-src 'none'",
    +                "manifest-src 'none'",
    +            ];
    +
                 return response()->make(
                     $content, 200, [
    +                            'Content-Security-Policy' => implode('; ', $csp),
                                 'Content-Type'        => $attachment->mime,
                                 'Content-Disposition' => 'inline; filename="' . $attachment->filename . '"',
                             ]
    
  • app/Http/Middleware/SecureHeaders.php+6 2 modified
    @@ -36,7 +36,7 @@ class SecureHeaders
          * Handle an incoming request. May not be a limited user (ie. Sandstorm env. or demo user).
          *
          * @param \Illuminate\Http\Request $request
    -     * @param \Closure                 $next
    +     * @param \Closure $next
          *
          * @return mixed
          */
    @@ -85,7 +85,11 @@ public function handle(Request $request, Closure $next)
             if (false === $disableFrameHeader || null === $disableFrameHeader) {
                 $response->header('X-Frame-Options', 'deny');
             }
    -        $response->header('Content-Security-Policy', implode('; ', $csp));
    +
    +        // content security policy may be set elsewhere.
    +        if (!$response->headers->has('Content-Security-Policy')) {
    +            $response->header('Content-Security-Policy', implode('; ', $csp));
    +        }
             $response->header('X-XSS-Protection', '1; mode=block');
             $response->header('X-Content-Type-Options', 'nosniff');
             $response->header('Referrer-Policy', 'no-referrer');
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.