有人可以离线编辑javascript文件来运行恶意代码吗?

时间:2014-01-21 08:48:18

标签: javascript php jquery html xss

我担心与我网站的javascript文件有关的内容,我不确定这是否可行。

当有人访问网站时会下载Js文件,如果有人编辑了下载的js脚本并插入了他自己的代码,然后刷新了网站。在新刷新中,网站将读取已编辑的Js文件并运行恶意代码。恶意代码可能用于以正常方式在服务器上运行某些代码。

示例:

用户只能在其页面中发布文章:

HTML

文章表单只会在用户的页面中显示。

<?php
if( $user->id == $page->userID )
{
?>    
<form>
<h1>Add new article:</h1><br />
<textarea name="articleText" cols="65" rows="3"></textarea>
<input class="SubmitArticle" id="<?php echo $userPage->id; ?>" name="SubmitArticle" type="button" value="Submit article" />
</form>
<?php
}
?>

的Javascript

$(".SubmitArticle").click( function(e){
    var targetPage = $(this).attr('id');
    var thisForm = $(this).parent();
    var postData = thisForm.serialize() + "&targetPage=" + targetPage;

    $.post(document.location, postData, function(data) {
        $('#mainDiv').html(data);
    });
});

PHP

if( isset($_POST["SubmitArticle"]) )
{
    $pageID = $_POST["targetPage"];
    $text = $_POST["articleText"];

    PublishArticle( $pageID , $text );
}

恶意代码:

在JS文件中插入代码以在其他用户页面上写文章(这是不允许的),攻击者使用视图页面源从html元素读取页面id(比如说page_id = 12):

postData = "SubmitArticle=1&targetPage=12&articleText='Muwhahahah'";
$.post(document.location, postData, function(data) {
});

如果可能,解决方案是什么?

8 个答案:

答案 0 :(得分:3)

我认为你对网络服务器的运作方式存在一些误解。

从客户端的角度来看,服务器发送给客户端的所有内容都是只读的。

想象一下,您已从互联网上下载了一个zip文件。然后,您修改它并保存它。保存过程将在您的硬盘驱动器上进行,而不是在服务器上进行。当您编辑本地文件时(在您的示例中为javascript文件),它将不会在服务器上进行编辑,只需在您的本地PC上进行编辑。

因此,您可以随心所欲地编辑/编辑本地文件。除非您以某种方式将其上传到服务器(例如FTP),否则它只会在您的本地PC上。

考虑到这一点,您应该始终在服务器端验证数据,因为熟练的用户可以编辑您的javascript以删除数据验证并将其发送到服务器。

答案 1 :(得分:3)

你担心是对的,不要相信客户。如初。

在您的示例中,您应该在发布文章之前验证用户,例如:

if( isset($_POST["SubmitArticle"]) ){
    $pageID = $_POST["targetPage"];
    $text = $_POST["articleText"];

    if( $user->id == $page->userID ){
      PublishArticle( $pageID , $text );
    }
}

不要就此止步

此外,您不应相信客户会向您发送有效的文章文字和页面ID。它可能是SQL注入,恶意javascript,破坏页面的HTML等。您还需要清理您的输入。

答案 2 :(得分:2)

智能用户可以轻松破解客户端验证 客户端正在这样做,所以我们不必担心,直到他向服务器发送错误的数据 所以应用服务器端验证。

->like the length of data comming from user  
->he is a geniune person to send data or not etc.  
->he is on session or not 
->check the data type, as expecting(type castings)  
->check userId equals to sessionId in server side also not only in client side  

它也称为跨站点脚本

跨站点脚本是Web应用程序中最常见的漏洞之一。它包括使用应用程序提供的表单将恶意JavaScript注入网页。

假设您正在撰写博客,任何人都可以添加评论。如果您盲目地将评论者写入您的HTML页面,那么您就是在打开网站进行攻击。它可以是:

Show a popup to your visitors
Redirect your visitors to a site controlled by the attacker
Steal information supposed to be visible only to the current user, and send it back to the attacker’s site

因此,保护​​自己免受这些攻击是非常重要的。

check this for example for server side validation example

答案 3 :(得分:1)

每当处理用户输入时,请确保在整个处理链(接收,存储,读取,发送,输出)期间输入永远不会作为代码执行。因此,永远不要像在jQuery中那样将用户输入呈现为像Javascript或.html()中的.innerHTML这样的HTML

//jQuery
$('#mainDiv').html(data);

//JavaScript
mainDiv.innerHTML = data;

总是使用文字:

//jQuery
$('#mainDiv').text(data);

//JavaScript
mainDiv.appendChild(document.createTextNode(data));

如果您需要在数据中添加标记,那么事情会变得复杂得多,您应该提供自己的(简化的)标记语言,如SO或维基百科正在这样做。

答案 4 :(得分:1)

您总是需要在表单处理PHP代码中进行一些服务器验证,例如:

if( isset($_POST["SubmitArticle"]) )
{
  $pageID = $_POST["targetPage"];
  $text = $_POST["articleText"];

  // here write some code to create a page from pageID

  if ($user->id == $page->userID)
  {
     PublishArticle( $pageID , $text );
  }
}

答案 5 :(得分:0)

每当用户将任何内容(应该是其他用户可见的内容)上传到服务器端时,您必须保护它。一种方法是转义所有特殊字符(可以解释为JavaScript),例如将所有.转换为其等效的&#46;。您可能只想将所有<转换为&#60;来转义HTML。我想要的角色至少是这些:<>.=()[]

您可以查看特殊代码here。虽然应该有一些PHP库。我不确定,我不是PHP开发人员。

答案 6 :(得分:0)

好吧,它不是“更改缓存的JS文件的内容” - 因为任何在客户端计算机上运行的代码都可以被更改以供恶意使用。那,现在大多数浏览器都有一个方便的控制台,允许您动态创建和运行JavaScript函数,这非常容易!

解决方案是保护您的代码在服务器端,即在您接收POST数据并将其作为新文章发布的方法中提及的示例中。

您可以通过多种方式克服此问题,通过将标记与文章数据一起传递来验证用户会话。在服务器端,您为唯一用户会话创建并配对唯一令牌并将其存储在那里。因此,令牌不是会话标识符,而是应该被解释为“允许用户x在条件y下提交文章的通过”的标识符。因此,例如,HTML页面可以创建包含此唯一字符串的隐藏表单字段,该字符串仅对单个请求和特定用户会话有效。因此,当用户提交表单时,服务器不仅验证表单的内容(因为它也可能在客户端被篡改),而且还读取令牌值并尝试为用户查找存储的匹配项session AND验证它是否对用户尝试执行的操作有效。传递这些验证后,可以删除存储的令牌,因为它现在无效。您可以添加其他检查以查看是否在给定时间段内使用令牌,IP是否仍然匹配,或者优选用户是否在此期间未注销该会话等(如果您使用在您的应用程序中注册用户,这样做的好处是您只能允许注册用户提交数据,但这样做的缺点是它要求所有访问者在与站点交互之前进行注册。)。

因此,如果一个有趣的家伙试图重新提交相同的表单,但是使用无意义(或恶意!)数据,服务器端代码将拒绝该请求,因为使用了令牌/或用户会话与存储的不匹配令牌因此无效(此外,您还可以使用服务器端验证来查找正文中的顽皮单词,无效的电子邮件地址等,但这更多地与清理您网站的内容有关,而非比严格的安全。)

答案 7 :(得分:0)

实际上,在浏览器中运行代码比编辑下载的js文件更简单。用户可以在浏览器的控制台中运行js代码或编写将运行用户javascript的浏览器扩展。我相信这是一个功能,而不是一个错误。

您需要做的是确保服务器端用户不做任何他/她无权做的事情,您不能信任来自客户端的任何内容。

此外,如果您遵循此规则,在浏览器中运行的用户代码通常只有在他/她可以在其他用户的浏览器上运行该代码时才会出现问题(您无法限制用户在其中运行任何js代码) /她想要的浏览器。