BookStack icon indicating copy to clipboard operation
BookStack copied to clipboard

AWS S3 Secure Image Upload

Open svarlamov opened this issue 7 years ago • 5 comments

For Feature Requests

Desired Feature: Secure image uploads (require auth) with S3 storage backend (the S3 version of #551 / #665)

Expected Behavior

Same user experience as local secure uploads, but via AWS S3 signed URLs. Also -- and I'm not sure how this would work now since the local secure feature has already been released -- but ideally it wouldn't use a 'new' storage method, but just add an 'authed images' flag. However, I'm sure that there's a good reason why it was implemented with a new storage method previously... Ideally, there would also be a streamlined way to migrate to secure images as well.

svarlamov avatar Mar 25 '18 11:03 svarlamov

I'm not sure if I should create another feature request, but I too would like to see something like this build into Bookstack. Perhaps a more broader idea in the sense that it applies to maybe mounting a S3 bucket that can can operate outside of Bookstack to include media assets in bookstack. My use case is videos mainly. If uploading to S3 storage, it puts the video into a page as an attachment. But if I want to embed it from a bucket that is 'publicly' available a signed url would be much better than a direct url to prevent unauthorized access or a sharing of a URL bypassing Bookstack. S3 complaint storage supports this. Cloudflare supports this in their streaming service as well.

https://developers.cloudflare.com/stream/viewing-videos/securing-your-stream https://docs.min.io/docs/upload-files-from-browser-using-pre-signed-urls.html

Both uploads and downloads for S3 type storage would be great. This likely would require handling these type of attachments differently than local storage. This would allow using a true cdn to serve content authenticated without needing to load it through bookstack attachment process. Context would be loaded for example via cdn.domain.com rather than bookstackdomain.com/attachment/3

cb3inco avatar Apr 01 '21 05:04 cb3inco

Does anyone have a workaround for this?

muhzak avatar Oct 20 '23 00:10 muhzak

We implemented a logical theme for signed s3 image urls:

functions.php:

use BookStack\Facades\Theme;
use BookStack\Http\Controller;
use BookStack\Theming\ThemeEvents;
use Illuminate\Contracts\Filesystem\Filesystem;
use Illuminate\Filesystem\FilesystemManager;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Route;

class S3Controller extends Controller{
    
    public function __construct(
        protected FilesystemManager $fileSystem,
    ) {
    }

    public function signedRedirect($path){
        $disk = $this->fileSystem->disk('s3');
        $url = $disk->temporaryUrl($path, Carbon::now()->addMinutes(5));
        return redirect()->away($url);
    }
}

Theme::listen(ThemeEvents::ROUTES_REGISTER_WEB, function(){
    Route::middleware('auth')->group(function(){
        Route::get('/s3/{path}', [S3Controller::class, 'signedRedirect'])->where('path', '.*');
    });
});

.env:

STORAGE_TYPE=s3
STORAGE_S3_KEY=your-key
STORAGE_S3_SECRET=your-secret
STORAGE_S3_BUCKET=your-bucket
STORAGE_S3_REGION=your-region
STORAGE_S3_ENDPOINT=https://s3.your-region.your-provider.tld
STORAGE_URL=https://your.bookstack.domain.tld/s3/

The STORAGE_URL points to the S3Controller which is redirecting to the signed s3 url. The signed URLs are only valid for 5 minutes and the S3Controller itself requires a valid BookStack session.

zivillian avatar Oct 23 '24 16:10 zivillian

What I have tested looks like that Presigned URLs is also required with Garage .

I tested with following config:

STORAGE_TYPE=s3 STORAGE_S3_KEY=keyxxx STORAGE_S3_SECRET=secretxxx STORAGE_S3_BUCKET=bookstack-bucket STORAGE_S3_ENDPOINT=https://s3.domain.com STORAGE_S3_REGION=garage STORAGE_URL=https://s3.domain.com/bookstack-bucket

Image upload worked but Bookstack showed only links instead of image and when clicked link I got Forbidden: Garage does not support anonymous access yet

timnis avatar Jun 11 '25 12:06 timnis

Would love to see this feature added please.

ryanmortier avatar Oct 14 '25 12:10 ryanmortier