2

静的なウェブサイトをAWS S3でホストしたいと考えています。それにはメールを送るための「お問い合わせ」ページが含まれています。ユーザが送信ボタンをクリックするとAWS APIゲートウェイに要求が送信され、APIゲートウェイがラムダ機能をトリガし、ラムダ機能がメールを管理者に送信します。それにはいくつか問題があります。私たちがサーバーにWebサイトをホストするときには、送信要求の自動化や不正行為を防ぐためにcaptchaを使用することができます。この場合、誰かがそれを知っている私のAPIゲートウェイのURLを誤って(URLにクエリ文字列を渡すことによって、より多くのリクエストを送ることができます)。私の質問はです。私のウェブサイトから送信依頼が要求されていることを知るにははCaptchaの代わりに使用する方法はありますか?AWS APIゲートウェイのURLを不正アクセスから保護するにはどうすればよいですか?

+0

リクエストごとに、それは創造にAPIから検証されたキャプチャとのセッションを必要とするので、あなたはGoogeキャプチャを経由して同じことを達成することができます。キャプチャ以外の何かを使うのはなぜですか? – Ashan

+0

キャプチャを検証する方法は、サーバーを使用しないでください。 –

+0

キャプチャを検証するAPIゲートウェイとラムダを使用します。もう1つの選択肢は、レートベースのブロッキングにCloudFrontとAWS WAFを使用することです。 – Ashan

答えて

1

グーグルのreCAPTCHAを統合する非常に単純に見える -

  1. 検証ユーザーキャプチャ(https://developers.google.com/recaptcha/docs/display
  2. 検証と応答(https://developers.google.com/recaptcha/docs/verify

- に侵入

https://developers.google.com/recaptcha/intro これはAPIゲートウェイのエンドポイントとIで簡単に達成できますあなたの秘密はラムダ(おそらくenv変数になるでしょう、サイトキーはs3静的サイトに入ります)

とにかくあなた自身の検証メカニズムを設計してみませんか?送信する前にユーザーの電話番号を要求してください(または送信...)。次に、この番号を取得し、SNS経由でotpを送信するAPIゲートウェイエンドポイントを呼び出します。ユーザーがこのotp(別のAPIゲートウェイ呼び出し)を確認すると、管理者メールのみが送信されます(さらに処理してください)。あなたはこのotpをバリデーションされたブールフラグでいくつかのrdsとして保存することができます。これらのAPIゲートウェイエンドポイントは、実際には認証専用で、クラウドフロントで自動的に拡張されるため、心配する必要はありません。

+0

ありがとうございます。私は、クエリ文字列でフォームデータを渡し、メールを送信するためにバックエンドのPythonラムダ関数を使用するAPIゲートウェイのURLを使用しています。私のフォームにGoogleのキャプチャを追加する場合。 googleのキャプチャでユーザーによって入力されたAPIゲートウェイURLのクエリ文字列でデータを渡す方法 –

+0

ユーザーが入力したクエリ文字列は返されません。 Google APIはそれを確認し、ユーザーの応答トークンを提供します。これはreCAPTCHAによって提供され、サイトのユーザーを確認します。ラムダに送信して、この応答が正しいかどうかを確認してください。 - https://developers.google.com/recaptcha/docs/verify –

+0

ありがとうございます、ついに私はaws lambdaで自分の仕事を完了し、Googleのcaptchaを検証しました。有用。一度はありがとうございます –

0

httpのRefererヘッダーを使用できます。ブラウザによって設定されます。

+0

私のシナリオでは参照元ヘッダーがどのように役立つのか –

+0

HttpRequestのヘッダーのReferrerを参照してください。送信後に取得されています.. ReferrerがあなたのWebページを提供すると感じます –

1

S3静的サイト上のサーバレスSPAサイト上のお問い合わせフォームのAPI Gatewayおよびラムダ

を使用して検証reCAPTCHAのあなたはどのような方法を使用することができますが、私は、「角度-reCAPTCHAの」サービス(https://github.com/VividCortex/angular-recaptcha)とAngularJSを使用recaptcha値を取得してPOSTする。

バックエンドでは、ラムダ関数を呼び出してrecaptcha値を検証して何かを行うAPIゲートウェイを使用できます。 NodeJSとRecaptcha2(https://www.npmjs.com/package/recaptcha2)を使用してトークンを検証します。ボーナスとして

をハンドルバーを使用してSES

var reCAPTCHA = require('recaptcha2') 

module.exports.sendemail = (event, context, callback) => { 

    // parse the data that was sent from API Gateway 
    var eventData = JSON.parse(event.body); 

    // Prepare the recaptcha connection to Google 
    var recaptcha = new reCAPTCHA({ 
     siteKey: process.env.RECAPTCHA_KEY, 
     secretKey: process.env.RECAPTCHA_SECRET 
    }) 

    // Validate the recaptcha value 
    recaptcha.validate(eventData.recaptcha) 
     .then(function(){ 
      // validated ok 
      console.log("ReCaptcha Valid") 


      ... DO STUFF HERE ... 


     }) 
     .catch(function(errorCodes){ 

      // invalid recaptcha 
      console.log("ReCaptcha Not Valid") 

      // translate error codes to human readable text 
      console.log(recaptcha.translateErrors(errorCodes)); 

      // send a fail message with cors headers back to the UI 
      var response = { 
       statusCode: 500, 
       headers: { 
        "Access-Control-Allow-Origin" : "*", 
        "Access-Control-Allow-Credentials" : true 
       }, 
       body: JSON.stringify({"message":"Error: Invalid Recaptcha"}) 
      } 
      callback(null, response); 
     }); 
}; 

例template宣言の電子メール、ここで私は、HTML /テキストテンプレートを使用して電子メールを送信するために再利用するいくつかのコードです:に値を注入する

  • ハンドルバーは、電子メールを送信するテンプレートSES。
  • ドメイン名でSESを設定し、ラムダに "ses:SendEmail"と "ses:SendEmailRaw"を許可していることを確認してください。
  • 関数をデプロイするときに環境変数を追加すると、コードが再利用可能になり、ソースコードから秘密が保護されます。
  • サーバーレスアプリケーションを展開するには、Serverless Frameworkの使用を強くお勧めします。 https://serverless.com

私のために御馳走を作品:)

'use strict'; 

var AWS = require('aws-sdk'); 
var ses = new AWS.SES(); 
var reCAPTCHA = require('recaptcha2') 
var fs = require('fs'); 
var Handlebars = require('handlebars'); 

module.exports.sendemail = (event, context, callback) => { 

    // parse the data that was sent from API Gateway 
    var eventData = JSON.parse(event.body); 

    // Prepare the recaptcha connection to Google 
    var recaptcha = new reCAPTCHA({ 
     siteKey: process.env.RECAPTCHA_KEY, 
     secretKey: process.env.RECAPTCHA_SECRET 
    }) 

    // Validate the recaptcha value 
    recaptcha.validate(eventData.recaptcha) 
     .then(function(){ 
      // validated ok 
      console.log("reCAPTCHA Valid") 

      // Read the HTML template from the package root 
      fs.readFile('./contact/email_template.html", function (err, emailHtmlTemplate) { 
       if (err) { 
        console.log("Unable to load HTML Template"); 
        throw err; 
       } 
       // Read the TEXT template from the package root 
       fs.readFile('./contact/email_template.txt", function (err, emailTextTemplate) { 
        if (err) { 
         console.log("Unable to load TEXT Template"); 
         throw err; 
        } 

        // Gather data to be injected to the templates 
        var emailData = { 
         "websiteaddress": process.env.WEBSITEADDRESS, 
         "websitename": process.env.WEBSITENAME, 
         "content": null, 
         "email": process.env.EMAIL_TO, 
         "event": eventData 
        }; 

        // Use Handlebars to compile the template and inject values into the title (used in subject and body of email) 
        var templateTitle = Handlebars.compile(process.env.EMAIL_TITLE); 
        var titleText = templateTitle(emailData); 
        console.log(titleText); 

        // Add title to the values object 
        emailData.title = titleText; 

        // Use Handlebars to compile email plaintext body 
        var templateText = Handlebars.compile(emailTextTemplate.toString()); 
        var bodyText = templateText(emailData); 
        console.log(bodyText); 

        // Use Handlebars to compile email html body 
        var templateHtml = Handlebars.compile(emailHtmlTemplate.toString()); 
        var bodyHtml = templateHtml(emailData); 
        console.log(bodyHtml); 

        // Prepare the SES payload 
           var params = { 
               Destination: { 
                   ToAddresses: [ 
                       process.env.EMAIL_TO 
                   ] 
               }, 
               Message: { 
                   Body: { 
                       Text: { 
                           Data: bodyText, 
                           Charset: 'UTF-8' 
                       }, 
           Html: { 
            Data: bodyHtml 
           }, 
                   }, 
                   Subject: { 
                       Data: titleText, 
                       Charset: 'UTF-8' 
                   } 
               }, 
               Source: process.env.EMAIL_FROM 
           } 
        console.log(JSON.stringify(params,null,4)); 

        // Send SES Email 
           ses.sendEmail(params, function(err,data){ 
         if(err) { 
          console.log(err,err.stack); // error 

          // Handle SES send errors 
          var response = { 
           statusCode: 500, 
           headers: { 
            "Access-Control-Allow-Origin" : "*", 
            "Access-Control-Allow-Credentials" : true 
           }, 
           body: JSON.stringify({"message":"Error: Unable to Send Message"}) 
          } 
          callback(null, response); 
         } 
         else { 
          console.log(data); // success 

          // SES send was successful 
          var response = { 
           statusCode: 200, 
           headers: { 
            "Access-Control-Allow-Origin" : "*", 
            "Access-Control-Allow-Credentials" : true 
           }, 
           body: JSON.stringify({"message":"Message Sent"}) 
          } 
          callback(null, response); 
         } 
        }); 

       }); //end of load text template 
      }); //end of load html template 


     }) 
     .catch(function(errorCodes){ 

      // invalid recaptcha 
      console.log("reCAPTCHA Not Valid") 

      // translate error codes to human readable text 
      console.log(recaptcha.translateErrors(errorCodes)); 

      // send a fail message with cors headers back to the UI 
      var response = { 
       statusCode: 500, 
       headers: { 
        "Access-Control-Allow-Origin" : "*", 
        "Access-Control-Allow-Credentials" : true 
       }, 
       body: JSON.stringify({"message":"Error: Invalid Recaptcha"}) 
      } 
      callback(null, response); 
    }); 
}; 
+0

ありがとうございます、しかし私は疑いがほとんどありません。私は、クエリ文字列でフォームデータを渡し、メールを送信するためにバックエンドのPythonラムダ関数を使用するAPIゲートウェイのURLを使用しています。私のフォームにGoogleのキャプチャを追加する場合。どのようにGoogleのキャプチャでユーザーによって入力されたAPIゲートウェイのURLでクエリ文字列でデータを渡すにはPHPで –

+0

私たちはこれを変数$ data = $ _POST ['g-recaptcha-response'] javascriptと同じです。 –

+0

'var eventData = JSON.parse(event.body);'は入力変数を取得し、 'eventData.recaptcha'はrecaptchaの値です。 'eventData.contactFormMessageFromUser'または 'eventData.contactFormEmailAddressFromUser' –

関連する問題