什么是PHP_SELF变量?
PHP_SELF是一个返回正在执行的当前脚本的变量。此变量返回当前文件的名称和路径(来自根文件夹)。您可以在FORM的操作字段中使用此变量。您还需要注意某些漏洞。我们将在本文中讨论所有这些要点。
我们现在看一些例子。
echo $_SERVER['PHP_SELF'];
a)假设您的php文件位于以下地址:
http://www.yourserver.com/form-action.php
在这种情况下,PHP_SELF将包含:
"/form-action.php"
b)假设您的php文件位于以下地址:
http://www.yourserver.com/dir1/form-action.php
对于此URL,PHP_SELF将为:
"/dir1/form-action.php"
在表单的action字段中使用PHP_SELF变量
PHP_SELF变量的常见用法是在<form>标记的action字段中。当用户按下“提交”按钮时,FORM的操作字段指示提交表单数据的位置。通常与表单的处理程序具有相同的PHP页面。
但是,如果您在操作字段中提供文件的名称,以防您碰巧重命名该文件,则还需要更新操作字段; 或者你的表格将停止工作。
使用PHP_SELF变量,您可以编写更多通用代码,可以在任何页面上使用,而无需编辑操作字段。
考虑一下,你有一个名为form-action.php的文件,并希望在提交表单后加载相同的页面。通常的表单代码是:
<form method="post" action="form-action.php" >
我们可以使用PHP_SELF变量而不是“form-action.php”。代码变成:
<form name="form1" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>" >
“form-action.php”的完整代码
这是组合代码,包含表单和PHP脚本。
<?php
if(isset($_POST['submit']))
{
$name = $_POST['name'];
echo "User Has submitted the form and entered this name : <b> $name </b>";
echo "<br>You can use the following form again to enter a new name.";
}
?>
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
<input type="text" name="name"><br>
<input type="submit" name="submit" value="Submit Form"><br>
</form>
此PHP代码位于HTML部分之上,将首先执行。第一行代码是检查表单是否已提交。提交按钮的名称是“提交”。按下提交按钮时,$_POST['submit']将设置并且IF条件将变为真。在这种情况下,我们显示用户输入的名称。
如果表单未提交,IF条件将为FALSE,因为没有值$_POST['submit'] ,PHP代码将不会被执行。在这种情况下,仅显示表单。
什么是PHP_SELF漏洞以及如何避免它们
PHP_SELF变量用于获取当前文件的名称和路径,但黑客也可以使用它。如果在页面中使用了PHP_SELF,则用户可以输入斜杠(/),然后输入一些跨站点脚本(XSS)命令来执行。
<form name="test" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
现在,如果用户在地址栏中输入了正常的URL,
http://www.yourdomain.com/form-action.php
则上述代码将被翻译为:
<form name="test" action="form-action.php" method="post">
这是正常情况。
现在考虑用户通过在浏览器的地址栏中输入以下URL来调用此脚本:
http://www.yourdomain.com/form-action.php/"><script>alert('xss')</script><foo"
在这种情况下,PHP处理后代码变为:
<form name="test" method="post" action="form-action.php"/>
<script>alert('xss')</script><foo"">
您可以看到此代码添加了脚本标记和警报命令。加载此页面后,用户将看到一个警告框。这只是一个如何利用PHP_SELF变量的简单示例。
可以在“script”标记之间添加任何JavaScript代码。<script>....HERE....</script>。黑客可以链接到可能位于另一台服务器上的JavaScript文件。例如,该JavaScript文件可以保存可以改变全局变量的恶意代码,也可以将表单提交到另一个地址以捕获用户数据。
一个有趣的练习
当我们的注入落在标记属性上时,我们试图突破它而没有成功,因为关闭标记并开始新标记所需的大于号(>)被替换为减号( - ):
因此,我们将尝试使用事件处理程序来使用内联注入:
再次没有成功,但这次是因为javascript块(第11行到第17行)清理了每个字符串,其中“on”后跟或不是间隔符(%09,%0A,%0C,%0D或%20)和document.location.href(第15行)中的等号(=),即处理URL的属性。
javascript函数eventFilter()在文档主体加载时调用(第3行),操作在运行时构建的页面(参见 DOM),因此尽管它在源上正确反映,但注入不起作用
但是如果我们创建一个任意属性并且只是保持其值打开,那么注入后的所有代码都将被更改为其值:
这样,只有当浏览器的HTML解析器找到下一个单引号(')时才会关闭“1”属性,该引用位于“不要做坏事”这个短语上。我们注入的表单标记将在下一个大于符号(>)中关闭,该标记位于</ h6>标记中。
输入字段与提交按钮一起消失,javascript函数完全禁用(全部从第8行到第18行)。因为在页面中没有更多元素可以交互,“style”属性也被“ - ”替换,我们不能在我们的目标标记之后注入任何东西,我们无法触发我们提供的事件处理程序
所以这是最后一招。在当前的Firefox浏览器中,我们有以下处理程序,在源代码中只需要一个脚本块来触发它们:
onafterscriptexecute
onbeforescriptexecute