All Projects → dmjio → s3-signer

dmjio / s3-signer

Licence: BSD-2-Clause License
☁️ Presigned S3 URLs for Haskell

Programming Languages

haskell
3896 projects
Nix
1067 projects

Projects that are alternatives of or similar to s3-signer

Questions
Web app inspired by Quora, allowing users ask question and get answers
Stars: ✭ 15 (-34.78%)
Mutual labels:  aws-s3, ajax
amazonka-s3-streaming
Provides a conduit based interface to uploading data to S3 using the Multipart API
Stars: ✭ 19 (-17.39%)
Mutual labels:  aws-s3
punic
Punic is a remote cache CLI built for Carthage and Apple .xcframework
Stars: ✭ 25 (+8.7%)
Mutual labels:  aws-s3
Exopite-Multifilter-Multi-Sorter-WordPress-Plugin
Display and/or sort/filter any page or post types by multiple taxonomies or terms (like post by categories and/or tags) with AJAX. Exopite multifilter, multi-sortable, multi selectable, multi filterable sortable Wordpress Plugin.
Stars: ✭ 18 (-21.74%)
Mutual labels:  ajax
micell
A collection of functions for front-end development
Stars: ✭ 16 (-30.43%)
Mutual labels:  ajax
Facial-Recognition-Attendance-System
An attendance system which uses facial recognition to detect which people are present in any image.
Stars: ✭ 48 (+108.7%)
Mutual labels:  aws-s3
php-ajax
A simple Ajax App with PHP backend
Stars: ✭ 53 (+130.43%)
Mutual labels:  ajax
jquery-ajaxSubmit
Effortlessly submit forms using AJAX and JSON.
Stars: ✭ 39 (+69.57%)
Mutual labels:  ajax
moodle-tool objectfs
Object file storage system for Moodle
Stars: ✭ 61 (+165.22%)
Mutual labels:  aws-s3
Flask-Resize
Flask extension for resizing, cropping and caching images.
Stars: ✭ 47 (+104.35%)
Mutual labels:  aws-s3
dog days
Using AWS RDS and S3 to store data about my dogs' vaccination and medical records. Creating an R shiny app to keep track of and share records with vets. 🐶 🐶
Stars: ✭ 44 (+91.3%)
Mutual labels:  aws-s3
Contact-Form-PHP
Simple and secure contact form using Ajax, validations inputs, SMTP protocol and Google reCAPTCHA v3 in PHP.
Stars: ✭ 28 (+21.74%)
Mutual labels:  ajax
anyfs
Portable file system for Node
Stars: ✭ 17 (-26.09%)
Mutual labels:  aws-s3
jaulp-wicket
This project is a collection of Apache Wicket components and utilities.
Stars: ✭ 14 (-39.13%)
Mutual labels:  ajax
bilibili-parse
bilibili视频html5直播&下载&API(待修复)
Stars: ✭ 16 (-30.43%)
Mutual labels:  ajax
axios-endpoints
Axios endpoints helps you to create a more concise endpoint mapping with axios.
Stars: ✭ 41 (+78.26%)
Mutual labels:  ajax
laravel-uppy-s3-multipart-upload
Multipart Uploads using Laravel, AWS S3, and Uppy
Stars: ✭ 30 (+30.43%)
Mutual labels:  aws-s3
grafana-s3-plugin
Grafana Plugin for querying files on AWS S3 using S3 Select API
Stars: ✭ 21 (-8.7%)
Mutual labels:  aws-s3
tsrpc
A TypeScript RPC framework, with runtime type checking and serialization, support both HTTP and WebSocket. It is very suitable for website / APP / games, and absolutely comfortable to full-stack TypeScript developers.
Stars: ✭ 866 (+3665.22%)
Mutual labels:  ajax
desafiosInternos
Resultado da peregrinação com resolução de dúvidas interessantes
Stars: ✭ 15 (-34.78%)
Mutual labels:  ajax

s3-signer

Hackage Hackage Dependencies Haskell Programming Language BSD3 License Build Status

s3-signer is intended to be an aid in building secure cloud-based services with AWS. This library generates cryptographically secure URLs that expire at a user-defined interval. These URLs can be used to offload the process of uploading and downloading large files, freeing your webserver to focus on other things.

Features

  • Minimal depedencies
  • Web framework agnostic
  • Reduces web server load
  • Simple API
  • Ideal for AJAX direct-to-s3 upload scenarios

Documentation

S3 Query String Request Authentication

Implementation

AWS Specification

Signature = URL-Encode( Base64( HMAC-SHA1( YourSecretAccessKeyID,UTF-8-Encoding-Of( StringToSign ) ) ) );

Haskell Implementation

module Network.S3.Sign  ( sign ) where

import           Crypto.Hash.SHA1       (hash)
import           Crypto.MAC.HMAC        (hmac)
import qualified Data.ByteString.Base64 as B64
import           Data.ByteString.UTF8   (ByteString)
import           Network.HTTP.Types.URI (urlEncode)

-- | HMAC-SHA1 Encrypted Signature
sign :: ByteString -> ByteString -> ByteString
sign secretKey url = urlEncode True . B64.encode $ hmac hash 64 secretKey url

Use Case

{-# LANGUAGE OverloadedStrings #-}

module Main where

import           Network.S3

main :: IO ()
main = print =<< generateS3URL credentials request
  where
     credentials = S3Keys "<public-key-goes-here>" "<secret-key-goes-here>"
     request     = S3Request S3GET "application/zip" "bucket-name" "file-name.extension" 3 -- 3 secs until expired

Result

S3URL {
      signedRequest =
         "https://bucket-name.s3.amazonaws.com/file-name.extension?AWSAccessKeyId=<public-key-goes-here>&Expires=1402346638&Signature=1XraY%2Bhp117I5CTKNKPc6%2BiihRA%3D"
     }

Snap integration - Downloads

-- Quick and dirty example
type FileID = ByteString

makeS3URL :: FileID -> IO S3URL
makeS3URL fileId = generateS3URL credentials request
  where
    credentials = S3Keys "<public-key-goes-here>" "<secret-key-goes-here>"
    request     = S3Request S3GET "application/zip" "bucket-name" (fileId <> ".zip") 3 

downloadFile :: Handler App (AuthManager App) ()
downloadFile = method POST $ currentUserId >>= maybe the404 handleDownload
  where handleDownload uid = do
          Just fileId <- getParam "fileId"
          -- Ensure file being requested belongs to user else 403...
          S3URL url <- liftIO $ makeS3URL fileId
          redirect' url 302

Direct to S3 AJAX Uploads

  • Configure S3 Bucket CORS Policy settings
  • CORS Docs
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>https://my-url-goes-here.com</AllowedOrigin>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>
  • Retrieve PUT Request URL via AJAX
type FileID = ByteString

makeS3URL :: FileID -> IO S3URL
makeS3URL fileId = generateS3URL credentials request
  where
    credentials = S3Keys "<public-key-goes-here>" "<secret-key-goes-here>"
    request     = S3Request S3PUT "application/zip" "bucket-name" (fileId <> ".zip") 3 

getUploadURL :: Handler App (AuthManager App) ()
getUploadURL = method POST $ currentUserId >>= maybe the404 handleDownload
  where handleDownload _ = do
          Just fileId <- getParam "fileId"
          writeJSON =<< Data.Text.Encoding.decodeUtf8 <$> liftIO (makeS3URL fileId)
  • Embed FileReader blob data to request
  • Send upload request
var xhr = new XMLHttpRequest();
xhr.open('PUT', url /* S3-URL generated from server */);
xhr.setRequestHeader('Content-Type', 'application/zip'); /* whatever http-content-type makes sense */
xhr.setRequestHeader('x-amz-acl', 'public-read');

/* upload completion check */
xhr.onreadystatechange = function(e) {
    if (this.readyState === 4 && this.status === 200) 
          console.log('upload complete');
};

/* Amazon gives you progress information on AJAX Uploads */
xhr.upload.addEventListener("progress", function(evt) {
       if (evt.lengthComputable) {
          var v = (evt.loaded / evt.total) * 100,
          val = Math.round(v) + '%',
          console.log('Completed: ' + val);
      }
}, false);

/* error handling */
xhr.upload.addEventListener("error", function(evt) {
   console.log("There has been an error :(");
}, false);

/* Commence upload */
xhr.send(file); // file here is a blob from the file reader API

File Reader Info

How to read file data from the browser

Troubleshoooting

  • Why do I keep getting 403 forbidden when I attempt to upload or download from a pre-signed URL?
    • Ask yourself the following:
      • Are my keys specified correctly?
      • Did I configure the CORS settings on my bucket properly?
      • Still trouble? Make an issue
  • Why are my URLs expiring faster than the specified time?

FAQ

  • Why didn't you use HMAC-SHA256?
    • It's 30% slower, and for all intents and purposes no more secure than HMAC-SHA1 (no known vulnerabilities exist for it, to my knowledge). Plain SHA1 is a different story. Collisions can be found, but there is no known way to apply those to HMAC-SHA1.
    • For the curious SHA-1 is broken
    • For the paranoid (Schneier quote from same article above)
    • Relevant SO Post

This attack builds on previous attacks on SHA-0 and SHA-1, and is a major, major cryptanalytic result. It pretty much puts a bullet into SHA-1 as a hash function for digital signatures (although it doesn't affect applications such as HMAC where collisions aren't important).

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].