dongyi1982 2012-10-21 14:59 采纳率: 0%
浏览 171
已采纳

PHP如何限制域发送POST请求[关闭]

I need to restrict POST request from specific domain. As far I know, HTTP_REFERER checking cannot be a good solution because it can be spoofed. So what can be the good solution when two different websites from different technology and web servers will work together?

  • 写回答

1条回答 默认 最新

  • dongshuo9350 2012-10-21 15:53
    关注

    Heres a method you could try, by adding a hidden field within your form that is session values that are set server side. This way if the form has not originated from your server the session would not have been set and the values would not match.

    Example:

    <?php 
    session_start();
    
    if($_SERVER['REQUEST_METHOD']=='POST'){
        if(isset($_SESSION['security']) && 
           isset($_SESSION['security_key']) && 
           !empty($_POST[$_SESSION['security_key']]) && 
           $_POST[$_SESSION['security_key']] == $_SESSION['security'])
        {
            /* forms post is from domain as session would 
               not have been started and security would not have been set */
            echo 'good';
        }else{
            /* forms post is not from domain */
            echo 'bad';
        }
        $_SESSION['security_key'] = sha1(microtime(true)+1);
        $_SESSION['security'] = sha1(microtime(true));
    }else{
        $_SESSION['security_key'] = sha1(microtime(true)+1);
        $_SESSION['security'] = sha1(microtime(true));
    }
    ?>
    
    <form method="POST" action="">
      <input type="hidden" name="<?=$_SESSION['security_key'];?>" value="<?=$_SESSION['security'];?>"/>
      <p><input type="text" name="Text" size="20"><input type="submit" value="Submit"></p>
    </form>
    

    Alternatively you could use encryption instead of hashing, that way you could check the values:

    <?php 
    session_start();
    define('SECURE_KEY',$_SERVER['SERVER_NAME']);
    
    if($_SERVER['REQUEST_METHOD']=='POST'){
        if(isset($_SESSION['security_key']) && isset($_SESSION['security'])){
            //Decrypt
            list($servername,$userip) = explode('X',decrypt(base64_decode($_SESSION['security'])));
    
            //Check the decrypted values
            if($servername == $_SERVER['SERVER_NAME'] && $userip == $_SERVER['REMOTE_ADDR']){
                /* forms post is from domain as session would
                not have been started and security would not have been set */
                echo 'good';
            }else{
                echo 'bad';
            }
    
        }else{
            /* forms post is not from domain */
            echo 'bad';
        }
    
        $_SESSION['security_key'] = sha1(microtime(true));
        $_SESSION['security'] = base64_encode(encrypt($_SERVER['SERVER_NAME'].'X'.$_SERVER['REMOTE_ADDR']));
    }else{
        $_SESSION['security_key'] = sha1(microtime(true));
        $_SESSION['security'] = base64_encode(encrypt($_SERVER['SERVER_NAME'].'X'.$_SERVER['REMOTE_ADDR']));
    }
    
    function encrypt($string, $key = 'PrivateKey', $secret = 'SecretKey', $method = 'AES-256-CBC') {
        // hash
        $key = hash('sha256', $key);
        // create iv - encrypt method AES-256-CBC expects 16 bytes
        $iv = substr(hash('sha256', $secret), 0, 16);
        // encrypt
        $output = openssl_encrypt($string, $method, $key, 0, $iv);
        // encode
        return base64_encode($output);
    }
    
    function decrypt($string, $key = 'PrivateKey', $secret = 'SecretKey', $method = 'AES-256-CBC') {
        // hash
        $key = hash('sha256', $key);
        // create iv - encrypt method AES-256-CBC expects 16 bytes
        $iv = substr(hash('sha256', $secret), 0, 16);
        // decode
        $string = base64_decode($string);
        // decrypt
        return openssl_decrypt($string, $method, $key, 0, $iv);
    }
    ?>
    
    <form method="POST" action="">
      <input type="hidden" name="<?=$_SESSION['security_key'];?>" value="<?=$_SESSION['security'];?>"/>
      <p><input type="text" name="Text" size="20"><input type="submit" value="Submit"></p>
    </form>
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料