Skip to content

Commit 44c884f

Browse files
Improved frame breaker
1 parent e43ae86 commit 44c884f

File tree

2 files changed

+63
-19
lines changed

2 files changed

+63
-19
lines changed

.gitattributes

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
*.php text eol=lf
2+
*.js text eol=lf
3+
*.css text eol=lf
4+
*.less text eol=lf
5+
*.scss text eol=lf
6+
*.sass text eol=lf
7+
*.tpl text eol=lf
8+
*.properties text eol=lf
9+
*.txt text eol=lf
10+
*.md text eol=lf
11+
*.htaccess text eol=lf
12+
*.service text eol=lf
13+
*.html text eol=lf
14+
*.sql text eol=lf
15+
*.ini text eol=lf
16+
*.json text eol=lf
17+
*.yml text eol=lf
18+
*.yarnclean text eol=lf
19+
*.lock text eol=lf
20+
*.yarn-integrity text eol=lf
21+
22+
.github/ export-ignore
23+
tests/ export-ignore
24+
.travis.yml export-ignore
25+
.scrutinizer.yml export-ignore
26+
.sensiolabs.yml export-ignore

src/Csrf.php

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,13 @@ class Csrf
121121
*/
122122
public static $frameBreaker = true;
123123

124+
/**
125+
* Which window should be verified? It is used to check if the system is loaded in the frame.
126+
*
127+
* @var string top/parent
128+
*/
129+
public static $windowVerification = 'top';
130+
124131
/**
125132
* Whether or not CSRF Magic should be allowed to start a new session in order
126133
* to determine the key.
@@ -148,12 +155,14 @@ class Csrf
148155
/**
149156
* Rewrites <form> on the fly to add CSRF tokens to them. This can also
150157
* inject our JavaScript library.
158+
*
159+
* @param mixed $buffer
151160
*/
152161
public static function obHandler($buffer)
153162
{
154163
if (!static::$isHtml) {
155164
// not HTML until proven otherwise
156-
if (stripos($buffer, '<html') !== false) {
165+
if (false !== stripos($buffer, '<html')) {
157166
static::$isHtml = true;
158167
} else {
159168
// Customized to take the partial HTML with form
@@ -165,7 +174,8 @@ public static function obHandler($buffer)
165174
foreach ($headers as $header) {
166175
if (static::$isHtml) {
167176
break;
168-
} elseif (stripos('Content-type', $header) !== false && stripos('/html', $header) === false) {
177+
}
178+
if (false !== stripos('Content-type', $header) && false === stripos('/html', $header)) {
169179
static::$isHtml = false;
170180
}
171181
}
@@ -181,7 +191,7 @@ public static function obHandler($buffer)
181191
$input = "<input type='hidden' name='" . static::$inputName . "' value=\"$tokens\"$endSlash>";
182192
$buffer = preg_replace('#(<form[^>]*method\s*=\s*["\']post["\'][^>]*>)#i', '$1' . $input, $buffer);
183193
if (static::$frameBreaker && !static::$isPartial) {
184-
$buffer = preg_replace('/<\/head>/', '<script type="text/javascript" nonce="' . static::$cspToken . '">if (top != self && top.location.origin + top.location.pathname != self.location.origin + self.location.pathname) {top.location.href = self.location.href;}</script></head>', $buffer, $count);
194+
$buffer = preg_replace('/<\/head>/', '<script type="text/javascript" nonce="' . static::$cspToken . '">if (' . static::$windowVerification . ' != self && ' . static::$windowVerification . '.location.origin + ' . static::$windowVerification . '.location.pathname != self.location.origin + self.location.pathname) {' . static::$windowVerification . '.location.href = self.location.href;}</script></head>', $buffer, $count);
185195
}
186196
if (($js = static::$rewriteJs) && !static::$isPartial) {
187197
$buffer = preg_replace(
@@ -208,7 +218,7 @@ public static function obHandler($buffer)
208218
*/
209219
public static function check($fatal = true)
210220
{
211-
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
221+
if ('POST' !== $_SERVER['REQUEST_METHOD']) {
212222
return true;
213223
}
214224
static::start();
@@ -227,10 +237,10 @@ public static function check($fatal = true)
227237
$ok = true;
228238
} while (false);
229239
if ($fatal && !$ok) {
230-
if (trim($tokens, 'A..Za..z0..9:;,') !== '') {
240+
if ('' !== trim($tokens, 'A..Za..z0..9:;,')) {
231241
$tokens = 'hidden';
232242
}
233-
call_user_func(static::$callback, $tokens);
243+
\call_user_func(static::$callback, $tokens);
234244
}
235245
return $ok;
236246
}
@@ -270,7 +280,7 @@ public static function getTokens()
270280
if (!$secret) {
271281
return 'invalid';
272282
}
273-
if (static::$user !== false) {
283+
if (false !== static::$user) {
274284
return 'user:' . static::hash(static::$user);
275285
}
276286
if (static::$allowIp) {
@@ -290,7 +300,7 @@ public static function flattenpost($data)
290300

291301
public static function flattenpost2($level, $key, $data)
292302
{
293-
if (!is_array($data)) {
303+
if (!\is_array($data)) {
294304
return [$key => $data];
295305
}
296306
$ret = [];
@@ -326,10 +336,12 @@ public static function callback($tokens)
326336
/**
327337
* Checks if a composite token is valid. Outward facing code should use this
328338
* instead of csrf_check_token().
339+
*
340+
* @param mixed $tokens
329341
*/
330342
public static function checkTokens($tokens)
331343
{
332-
if (is_string($tokens)) {
344+
if (\is_string($tokens)) {
333345
$tokens = explode(';', $tokens);
334346
}
335347
foreach ($tokens as $token) {
@@ -349,11 +361,11 @@ public static function checkTokens($tokens)
349361
*/
350362
public static function checkToken($token)
351363
{
352-
if (strpos($token, ':') === false) {
364+
if (false === strpos($token, ':')) {
353365
return false;
354366
}
355-
list($type, $value) = explode(':', $token, 2);
356-
if (strpos($value, ',') === false) {
367+
[$type, $value] = explode(':', $token, 2);
368+
if (false === strpos($value, ',')) {
357369
return false;
358370
}
359371
$tokenExplode = explode(',', $token, 2);
@@ -387,7 +399,7 @@ public static function checkToken($token)
387399
if (!static::getSecret()) {
388400
return false;
389401
}
390-
if (static::$user === false) {
402+
if (false === static::$user) {
391403
return false;
392404
}
393405
return $value === static::hash(static::$user, $time);
@@ -397,7 +409,7 @@ public static function checkToken($token)
397409
}
398410
// do not allow IP-based checks if the username is set, or if
399411
// the browser sent cookies
400-
if (static::$user !== false) {
412+
if (false !== static::$user) {
401413
return false;
402414
}
403415
if (!empty($_COOKIE)) {
@@ -413,14 +425,17 @@ public static function checkToken($token)
413425

414426
/**
415427
* Sets a configuration value.
428+
*
429+
* @param mixed $key
430+
* @param mixed $val
416431
*/
417432
public static function conf($key, $val)
418433
{
419-
if (!isset(static::$$key)) {
434+
if (!isset(static::${$key})) {
420435
trigger_error('No such configuration ' . $key, E_USER_WARNING);
421436
return;
422437
}
423-
static::$$key = $val;
438+
static::${$key} = $val;
424439
}
425440

426441
/**
@@ -441,7 +456,7 @@ public static function getSecret()
441456
if (static::$secret) {
442457
return static::$secret;
443458
}
444-
$file = self::$dirSecret . DIRECTORY_SEPARATOR . self::$fileNameSecret;
459+
$file = self::$dirSecret . \DIRECTORY_SEPARATOR . self::$fileNameSecret;
445460
$secret = '';
446461
if (file_exists($file)) {
447462
include $file;
@@ -463,8 +478,8 @@ public static function getSecret()
463478
public static function generateSecret()
464479
{
465480
$r = '';
466-
for ($i = 0; $i < 32; $i++) {
467-
$r .= chr(mt_rand(0, 255));
481+
for ($i = 0; $i < 32; ++$i) {
482+
$r .= \chr(mt_rand(0, 255));
468483
}
469484
$r .= time() . microtime();
470485
return sha1($r);
@@ -473,6 +488,9 @@ public static function generateSecret()
473488
/**
474489
* Generates a hash/expiry double. If time isn't set it will be calculated
475490
* from the current time.
491+
*
492+
* @param mixed $value
493+
* @param mixed|null $time
476494
*/
477495
public static function hash($value, $time = null)
478496
{

0 commit comments

Comments
 (0)