Skip to content

Commit

Permalink
2023.04.02 Merge branch 'FixSetCookies' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
monkenWu committed Apr 2, 2023
2 parents 70a9cd6 + 5175e8c commit 24e3b57
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 50 deletions.
13 changes: 12 additions & 1 deletion dev/app/Config/Filters.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,18 @@ class Filters extends BaseConfig
public $globals = [
'before' => [
// 'honeypot',
// 'csrf',
'csrf'=>[
'except' => [
'basicTest/formparamsandquery',
'basicTest/formparams',
'basicTest/cookieCreate',
'FileUploadTest/fileUpload',
'FileUploadTest/fileMultipleUpload',
'testRest',
'testRest/*',
'sessionTest/createdSession'
],
],
// 'invalidchars',
],
'after' => [
Expand Down
2 changes: 1 addition & 1 deletion dev/app/Config/Security.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ class Security extends BaseConfig
*
* @var bool
*/
public $redirect = true;
public $redirect = false;

/**
* --------------------------------------------------------------------------
Expand Down
43 changes: 43 additions & 0 deletions dev/app/Controllers/BasicTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,47 @@ public function i18n()
{
echo lang('Burner.negotiate');
}

/**
* test cookie
*/
public function cookieCreate()
{
$text1 = $this->request->getGet('text1');
$text2 = $this->request->getGet('text2');
$text3 = $this->request->getGet('text3');

$this->response->setCookie('text1', $text1, 3600);
$this->response->setCookie('text2', $text2, 3600);
$this->response->setCookie('text3', $text3, 3600);

return $this->respond(['status' => true]);
}

/**
* csrf test
*/
public function csrfCreate()
{
$token = csrf_token();
$hash = csrf_hash();
$body = <<< HTML
<form action="/basicTest/csrfVerify" method="post">
<input name="{$token}" value='{$hash}' />
<input type="text" name="text1" />
<input type="submit" value="submit" />
</form>
HTML;
return $body;
}

/**
* csrf verify
*/
public function csrfVerify()
{
$text = $this->request->getPost('text1');
return $this->respond($text, 200);
}

}
80 changes: 80 additions & 0 deletions dev/tests/CIBurner/httpTest/BasicTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,84 @@ public function testI18n()
$this->assertSame(200, $response->getStatusCode());
$this->assertSame('正體中文', $response->getBody());
}

public function testSetCookies()
{
$text1 = md5(uniqid().'text1');
$text2 = md5(uniqid().'text2');
$text3 = md5(uniqid().'text3');
$query = http_build_query([
'text1' => $text1,
'text2' => $text2,
'text3' => $text3,
]);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://localhost:8080/basicTest/cookieCreate?' . $query);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
//get url query
$output = curl_exec($ch);
curl_close($ch);
$cookies = [];
preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', $output, $matches);
foreach ($matches[1] as $item) {
parse_str($item, $cookie);
$cookies = array_merge($cookies, $cookie);
}

foreach ($cookies as $key => $value) {
$this->assertSame(${$key}, $value);
}
}

public function testCsrf()
{
//config
config('Security');
$tokenName = config('Security')->tokenName;
$headerName = config('Security')->headerName;
$client = Services::curlrequest([
'base_uri' => 'http://localhost:8080/',
], null, null, false);

//get csrf key
$getCsrfKey = function() use ($client){
$response = $client->get('/basicTest/csrfCreate');
$this->assertSame(200, $response->getStatusCode());
$setCookie = $response->getHeaders()['Set-Cookie']->getValue();
$csrf = explode('=', explode(';', $setCookie)[0]);
return $csrf;
};

//csrf form teset
$csrf = $getCsrfKey();
$text1 = md5(uniqid().'text1');
$response = $client->post('basicTest/csrfVerify', [
'headers' => [
'Cookie' => "{$csrf[0]}={$csrf[1]}",
],
'form_params' => [
$tokenName => $csrf[1],
'text1' => $text1,
],
]);
$this->assertSame(200, $response->getStatusCode());
$this->assertSame($text1, $response->getBody());

//csrf header test
$csrf = $getCsrfKey();
$text1 = md5(uniqid().'text1');
$response = $client->post('basicTest/csrfVerify', [
'headers' => [
'Cookie' => "{$csrf[0]}={$csrf[1]}",
$headerName => $csrf[1],
],
'form_params' => [
'text1' => $text1,
],
]);
$this->assertSame(200, $response->getStatusCode());
$this->assertSame($text1, $response->getBody());
}
}
98 changes: 50 additions & 48 deletions src/Bridge/ResponseBridge.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Monken\CIBurner\Bridge;

use Config\App;
use Config\Security;
use Laminas\Diactoros\Response;
use Laminas\Diactoros\Response\InjectContentTypeTrait;
use Laminas\Diactoros\Stream;
Expand All @@ -26,6 +27,7 @@ public function __construct(
$this->getCi4StatusCode($ci4Response),
$this->getCi4Headers($ci4Response)
);

}

private function getCi4ContentType(\CodeIgniter\HTTP\Response $ci4Response): string
Expand All @@ -35,48 +37,15 @@ private function getCi4ContentType(\CodeIgniter\HTTP\Response $ci4Response): str

private function getCi4Headers(\CodeIgniter\HTTP\Response $ci4Response): array
{
if (session_status() === PHP_SESSION_ACTIVE) {
$sessionID = session_id();
$sessionName = session_name();
$cookiesSessionID = $this->_rRequest->getCookieParams()[$sessionName] ?? '';
$cookiesParams = session_get_cookie_params();
$config = config(App::class);

if ($cookiesSessionID === '') {
$cookieStr = $this->getCookieString(
$sessionName,
$sessionID,
(time() + $cookiesParams['lifetime']),
$cookiesParams['path'],
$cookiesParams['domain'],
$cookiesParams['secure'],
$cookiesParams['httponly']
);
$ci4Response->setHeader('Set-Cookie', $cookieStr);
} elseif ($cookiesSessionID !== $sessionID) {
$cookieStr = $this->getCookieString(
$sessionName,
'',
time(),
$config->cookiePath,
$config->cookieDomain,
$config->cookieSecure,
$config->cookieHTTPOnly
);
$ci4Response->setHeader('Set-Cookie', $cookieStr);
}

unset($_SESSION);
session_write_close();
session_id(null);
}

$setCookiesArray = $this->ci4Cookies($ci4Response);
$ci4headers = $ci4Response->headers();
$headers = [];

foreach ($ci4headers as $key => $value) {
$headers[$key] = $value->getValueLine();
}
if (count($setCookiesArray) !== 0) {
$headers['Set-Cookie'] = $setCookiesArray;
}

return $headers;
}
Expand Down Expand Up @@ -105,20 +74,53 @@ private function getCookieString($name, $value = null, $expire = 0, $path = '/',
return $str;
}

private function getcookie($name)
private function ci4Cookies(\CodeIgniter\HTTP\Response $ci4Response): array
{
$cookies = [];
$headers = headers_list();

foreach ($headers as $header) {
if (strpos($header, 'Set-Cookie: ') === 0) {
$value = str_replace('&', urlencode('&'), substr($header, 12));
parse_str(current(explode(';', $value, 1)), $pair);
$cookies = array_merge_recursive($cookies, $pair);
}
$result = [];
$cookies = $ci4Response->getCookies();
foreach ($cookies as $cookie) {
$headerString = $cookie->toHeaderString();
$result[] = $headerString;
}

return $cookies[$name] ?? false;
//Session
if (session_status() === PHP_SESSION_ACTIVE) {
$sessionID = session_id();
$sessionName = session_name();
$cookiesSessionID = $this->_rRequest->getCookieParams()[$sessionName] ?? '';
$cookiesParams = session_get_cookie_params();
$config = config(App::class);

if ($cookiesSessionID === '') {
$cookieStr = $this->getCookieString(
$sessionName,
$sessionID,
(time() + $cookiesParams['lifetime']),
$cookiesParams['path'],
$cookiesParams['domain'],
$cookiesParams['secure'],
$cookiesParams['httponly']
);
$result[] = $cookieStr;
} elseif ($cookiesSessionID !== $sessionID) {
$cookieStr = $this->getCookieString(
$sessionName,
'',
time(),
$config->cookiePath,
$config->cookieDomain,
$config->cookieSecure,
$config->cookieHTTPOnly
);
$result[] = $cookieStr;
}

unset($_SESSION);
session_write_close();
session_id(null);
}

return $result;
}

private function getCi4StatusCode(\CodeIgniter\HTTP\Response $ci4Response): int
Expand Down

0 comments on commit 24e3b57

Please sign in to comment.