C ++ / CURL - 通过PHP传递数据请求安全吗?

时间:2015-08-19 16:18:27

标签: php c++ curl request

我正在尝试使用curl将数据发送到我的PHP文件,然后我可以执行所有其他操作,例如使用salt散列密码/数据,运行数据库查询eco。它似乎工作正常,但只有一个问题。我不知道如何使用授权令牌来保护它。我希望能够仅使用书面应用程序从我的PHP文件中查询数据。如果人们可以通过网络浏览器访问链接,我可以看到这会成为一个问题。

如果有人需要类似的东西,我在下面加入了我的代码。

的main.cpp

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <curl/curl.h>
#include <sha.h>
#include <hex.h>

using namespace std;
using namespace CryptoPP;

size_t size = 0;
size_t write_to_string(void *ptr, size_t size, size_t count, void *stream) {
    ((string*)stream)->append((char*)ptr, 0, size*count);
    return size*count;
}

template <class T>
string QueryDB(initializer_list<T> list) // Use initialize_list to query an undefined number of params
{
    CURL *curl;
    CURLcode res;

    string submitdata = "", query_result;

    int i = 1;
    for (auto elem : list) // For each param append to the submitdata string
    {
        if (i == 1) { // If first param, we append "?"
            string d = "?" + to_string(i) + "=" + elem;
            submitdata.append(d);
        } else if (i > 1) { // If not first param, we append "&" as it's the second, third, fourth ... param
            string d = "&" + to_string(i) + "=" + elem;
            submitdata.append(d);
        }
        i++;
    }

    curl_global_init(CURL_GLOBAL_ALL);
    curl = curl_easy_init();

    if (curl)
    {
        string loginurl = string("http://localhost/login.php");

        curl_easy_setopt(curl, CURLOPT_USERPWD, "randomhttpuser:randomhttppassword");
        curl_easy_setopt(curl, CURLOPT_URL, (loginurl + submitdata).c_str());
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_to_string);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &query_result);
        curl_easy_setopt(curl, CURLOPT_TIMEOUT, 20L);
        res = curl_easy_perform(curl);

        if (res != CURLE_OK)
            fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
        curl_easy_cleanup(curl);
    }
    else {
        query_result = "CONNECTION FAILED";
    }
    curl_global_cleanup();

    return query_result;
}

string SHA256Hash(string input)
{
    SHA256 hash;
    string hashed_input;

    StringSource ss(input, true, new HashFilter(hash, new HexEncoder(new StringSink(hashed_input))));

    return hashed_input;
}

int main()
{
    string username = "testuser";
    string raw_password = "testpass";

    // Hash password and send it as a query to PHP file
    // query_result will hold the value of REQUEST response
    auto hashed_password = SHA256Hash(raw_password);
    auto query_result = QueryDB({ username, hashed_password });

    cout << "=========================================== [ POST ] ===========================================" << endl;
    cout << "User: " << username.c_str() << endl;
    cout << "Raw Password: " << raw_password.c_str() << endl;
    cout << "Hashed password: " << hashed_password.c_str() << endl;
    cout << "========================================== [ REQUEST ] =========================================" << endl;
    cout << query_result.c_str() << endl;


    Sleep(15 * 1000);
    return 0;
}

的login.php

<?php

$reqparams = array();

function AddStringToArray($name,$string) {
    global $reqparams;
    $reqparams[$name] = $string;
}

/* Check if specified param exists in reqparams array */
function GetRequestParam($value) {
    global $reqparams;

    if (array_key_exists($value, $reqparams)) {
        $returnvalue = $reqparams[$value];
    } else {
        $returnvalue = "INVALID PARAMETER";
    }

    return $returnvalue;
}

$authuser = "randomhttpuser";
$authpw = "randomhttppassword";
$authorized = False;

if (!isset($_SERVER['PHP_AUTH_USER'])) {
    header('WWW-Authenticate: Basic realm="My Realm"');
    header('HTTP/1.0 401 Unauthorized');
    echo 'Failed to authorize!';
    exit;
} else {

    if($_SERVER['PHP_AUTH_USER'] == $authuser && $_SERVER['PHP_AUTH_PW'] == $authpw)
    {
        $authorized = True;
    } else {
        $authorized = False;
        die('Failed to authorize!');
    }
}

if($authorized == True)
{
    /* Store each REQUEST and it's value in the $reqparams array using AddStringToArray function */
    foreach ($_REQUEST as $key => $value)  
    {
        $value = addslashes($value);
        $value = strip_tags($value);

        AddStringToArray($key, $value);
    }

    /* You should remember in which order you called the params in your REQUEST query or if you really want, you can just use:

    $variable = $_REQUEST['param_name'];

    However, if an undefined param is specified, it will result in an warning and ruin your output, if you manually parse it */

    $user = GetRequestParam(1);
    $pass = GetRequestParam(2);

    /* GetRequestParam returns 'INVALID_PARAMETER' instead of a warning that an undefined param was requested */
    $invalid_param = GetRequestParam(42);

    /* Re-hash password with a salt that's stored in the PHP file only, before using or comparing it to the value stored in database or doing whatever else */
    $salt = $user . $pass . "secretkey42";
    $salt_hashed_passsword = strtoupper(hash('sha256', $salt));

    echo "User: $user";
    echo "\nHashed Password: $salt_hashed_passsword (Salt)";
}

?>

编辑:我可以使用HTTP标头,但是无法撤消我的应用并滥用它吗?

编辑:我目前决定使用HTTP身份验证作为临时措施。

我在PHP文件中存储了一个随机生成的用户名和密码,并将它们与使用CURLOPT_USERPWD在我的cpp应用程序的HTTP头中发送的PHP_AUTH_USER / PW进行比较:

curl_easy_setopt(curl, CURLOPT_USERPWD, "randomhttpusername:randomhttppassword");

希望这至少会让黑客更难一点。首先,他必须使用我的应用程序来获取用户/密码,甚至在此之后他只能查询响应是否密码属于指定用户 - 因为我的大多数查询都是硬编码的。您甚至可以存储失败登录的次数,并暂时禁止他使用x个时间。其余的查询在登录返回true后进行。

我还更新了上面的代码,使用我所做的更改,并添加了一些评论,如果你太懒,不能逐行检查代码。请随意向我提供一些有关如何改进代码或优化以便更好地使用的提示。

1 个答案:

答案 0 :(得分:0)

根据我的理解,您希望使用auth令牌实现某种登录系统。在这种情况下,OAuth可以完成这项工作。这是一篇写在SitePoint上的教程,可以指导您完成整个过程。