Created
August 20, 2018 04:13
-
-
Save iseebi/126f246271dadf1ad73ee02b422b36d2 to your computer and use it in GitHub Desktop.
[PHP] 入力されたHTMLにscriptタグが入っていないか検証する
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Model\Validation; | |
use Cake\Validation\Validation; | |
use DOMDocument; | |
class HtmlInputValidation extends Validation | |
{ | |
/** | |
* セキュアでないHTMLが入力されていないか確認する | |
* <script> タグと on から始まる属性が入っている場合はセキュアでないとする。 | |
* @param $value | |
* @return bool | |
*/ | |
public static function isSecureHtml($value) | |
{ | |
if (empty($value)) { | |
return true; | |
} | |
$domDocument = new DOMDocument(); | |
$domDocument->loadHTML($value); | |
$xmlString = $domDocument->saveXML(); | |
$xmlObject = simplexml_load_string($xmlString); | |
return HtmlInputValidation::validateNode($xmlObject->body); | |
} | |
/** | |
* isSecureHtml の再帰処理関数 | |
* @param $node \SimpleXMLElement | |
* @return bool | |
*/ | |
private static function validateNode($node) | |
{ | |
foreach ($node->attributes() as $name => $attr) { | |
if ((strlen($name)) > 1 && (strtolower(substr($name, 0, 2)) == 'on')) { | |
var_dump($name); | |
return false; | |
} | |
} | |
foreach ($node->children() as $child) { | |
$name = $child->getName(); | |
if (strtolower($name) == 'script') { | |
return false; | |
} | |
if (!HtmlInputValidation::validateNode($child)) { | |
return false; | |
} | |
} | |
return true; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Model\Table; | |
class SampleTable extends Table | |
{ | |
public function validationDefault(Validator $validator) | |
{ | |
$validator->setProvider('HtmlInput', 'App\Model\Validation\HtmlInputValidation'); | |
$validator | |
->scalar('text') | |
->requirePresence('text', 'create') | |
->notEmpty('text') | |
->add('body1', 'htmlSecure', [ | |
'rule' => ['isSecureHtml'], | |
'provider' => 'HtmlInput', | |
'message' => '不正なタグが入力されています', | |
]); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
// 正常パターン | |
$html = <<<DOC | |
<p style="color:red">test1<a href="#">hoge</a></p> | |
<p>test2<a href="#">hoge</a></p> | |
DOC; | |
*/ | |
/* | |
// HTMLが不正パターン | |
$html = <<<DOC | |
p style="color:red">test1<a href="#">hoge</a></p> | |
<p>test2<a href="#">hoge</a></p> | |
DOC; | |
*/ | |
/* | |
// empty | |
$html = ''; | |
*/ | |
/* | |
// onclick 埋められたパターン | |
$html = <<<DOC | |
<p style="color:red">test1<a href="#" onclick="alert(1);">hoge</a></p> | |
<p>test2<a href="#">hoge</a></p> | |
DOC; | |
*/ | |
// <script> 埋められたパターン | |
$html = <<<DOC | |
<p style="color:red">test1<a href="#">hoge</a></p> | |
<p>test2<a href="#">hoge</a></p> | |
<script>alert(1);</script> | |
DOC; | |
function validateNode($node) | |
{ | |
foreach ($node->attributes() as $name => $attr) { | |
if ((strlen($name)) > 1 && (strtolower(substr($name, 0, 2)) == 'on')) { | |
return false; | |
} | |
} | |
foreach ($node->children() as $child) { | |
$name = $child->getName(); | |
if (strtolower($name) == 'script') { | |
return false; | |
} | |
if (!validateNode($child)) { | |
return false; | |
} | |
} | |
return true; | |
} | |
function validateHtml($html) { | |
if (empty($html)) { | |
return true; | |
} | |
$domDocument = new DOMDocument(); | |
$domDocument->loadHTML($html); | |
$xmlString = $domDocument->saveXML(); | |
$xmlObject = simplexml_load_string($xmlString); | |
return validateNode($xmlObject->body); | |
} | |
if (validateHtml($html)) { | |
echo "HTML is secure."; | |
} | |
else { | |
echo "HTML is insecure!"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment