语言Java学习笔记–脚本语言支持API

SQL注入常见攻击技巧

SQL注入攻击是Web安全史上之一个首要里程碑,它从1999年篇坏登人们的视线,至今已经起十几年的历史了,虽然咱本曾闹矣十分到的防范对策,但是它们的威力还拒绝小觑,SQL注入攻击至今还是Web安全世界被之一个根本片段。

以PHP+MySQL为例,让咱以一个Web网站中极度核心的用户系统来做实例演示,看看SQL注入究竟是怎发的。

1、创建一个名为吧demo的数据库:
<pre>
CREATE DATABASE demo DEFAULT CHARACTER SET utf8 COLLATE
utf8_general_ci;
</pre>

2、创建一个叫做吧user的数据表,并插入1条演示数据:
<pre>
CREATE TABLE demo.user (
uid INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT
‘用户uid’,
username VARCHAR( 20 ) NOT NULL COMMENT ‘用户名’,
password VARCHAR( 32 ) NOT NULL COMMENT ‘用户密码’
) ENGINE = INNODB;
INSERT INTO demo.user (uid, username, password) VALUES (‘1’,
‘plhwin’, MD5(‘123456’));
</pre>

实行结果

语言 1

说明
    通过setWriter方法把剧本的出口重定向到一个文书被。通过ScriptContext的setReader和setErrorWriter方法可以分级设置脚本执行时之数目输入来源及生错误时错信息之出口目的。

2、过滤特殊符号

对无法确定固定格式的变量,一定要是开展特殊符号过滤或转义处理。以PHP为例,通常是利用addslashes函数,它会于指定的预约义字符前补给加反斜杠转义,这些预定义的字符是:单引号 (') 双引号 (") 反斜杠 (\) NULL

来看2条SQL语句:
<pre>
$uid = isset($_GET[‘uid’]) ? $_GET[‘uid’] : 0;
$uid = addslashes(uid);
$sql = “SELECT uid,username FROM user WHERE uid='{$uid}'”;
</pre>
以及
<pre>
$uid = isset($_GET[‘uid’]) ? $_GET[‘uid’] : 0;
$uid = addslashes(uid);
$sql = “SELECT uid,username FROM user WHERE uid={$uid}”;
</pre>

地方两只查询语词都经了php的addslashes函数过滤转义,但以安全性及倒是大不相同,在MySQL中,对于int类型字段的尺码查询,上面只报告句子之查询功能完全一样,由于第一句SQL的变量被单引号包含起来,SQL注入的下,黑客面临的重大问题是必使优先关前面的单引号,这样才能够使后面的说话作为SQL执行,并且还要注释掉原SQL语句被之后面的单引号,这样才可成功注入,由于代码里下了addslashes函数,黑客的攻击会无从下手,但第二句没有因此引号包含变量,那黑客也休想考虑去关掉、注释,所以便相同采用addslashes转义,也或存在SQL攻击漏洞。

对PHP程序+MySQL构架的程序,在动态的SQL语句被,使用单引号把变量包含起来相当addslashes函数是许针对SQL注入攻击的有用手段,但这做的尚不够,像上面的2长SQL语句,根据「检查数据类型」的准绳,uid都该通过intval函数格式为int型,这样不仅会行避免第二久告词的SQL注入漏洞,还能够使程序看起更当,尤其是在NoSQL(如MongoDB)中,变量类型一定要同字段类型相匹配才可以。

打上面可以看,第二单SQL语句是起尾巴的,不过由采用了addslashes函数,你会发觉黑客的攻击语句也存无克采取特殊符号的标准限制,类似where username='plhwin'这般的攻击语句是无奈执行之,但是黑客可以以字符串转为16进制编码数据或采用char函数进行转向,同样能上平等的目的,如果对这一部分内容感兴趣,可以点击这里翻。而且由于SQL保留重要字,如「HAVING」、「ORDER
BY」的存,即使是基于黑白名单之过滤方法仍然会发出或多要有失问题,那么是否还有其他方来防御SQL注入呢?

本子引擎默认的语言绑定对象的言传身教执行结果

语言 2

    在大部情下,使用ScriptEngine的put和get方法就是足够了。如果仅以put和get方法,语言绑定对象自我对于开发人员来说是透明的。在某些情况下,需要采取程序自己的语言绑定对象,比如语言绑定对象吃含有了次自己独有的数目。如果指望下自己之言语绑定对象,可以调用脚本引擎的createBindings方法或者创办,并传递给脚本引擎的eval方法。

小结

1、不要擅自敞开生产条件中Webserver的错误显示。
2、永远不要相信来用户端的变量输入,有固定格式的变量一定要严加检查对应的格式,没有固定格式的变量需要对引号等特殊字符进行必要的过滤转义。
3、使用预编译绑定变量的SQL语句。
4、做好数据库帐号权限管理。
5、严格加密处理用户的机密信息。

言语绑定对象的先期级依次的示范

    /**
     * 语言绑定对象的优先级顺序的示例
     */
    public static void scriptContextBindings(){
        try {
            ScriptEngine engine = getJavaScriptEngine();
            ScriptContext context = engine.getContext();
            Bindings binding1 = engine.createBindings();
            binding1.put("name","Arthur Ming");
            context.setBindings(binding1,ScriptContext.GLOBAL_SCOPE);
            Bindings binding2 = engine.createBindings();
            binding2.put("name","明国宾");
            context.setBindings(binding2,ScriptContext.ENGINE_SCOPE);
            engine.eval("print(name)");
        } catch (Exception e){
            e.printStackTrace();
        }
    }

实例二

如若系统非允而履行多久SQL语句,那么SQL注入攻击是匪是就是不再这样可怕吗?答案是否认的,我们仍以点的user数据表,用Web网站中常用的会员登录体系来开另外一个现象实例,编写程序login.php,代码如下:

<?php
if($_POST){
$link = mysql_connect(“localhost”, “root”, “root”);
mysql_select_db(‘demo’, $link);
$username = empty($_POST[‘username’]) ? ” :
$_POST[‘username’];
$password = empty($_POST[‘password’]) ? ” :
$_POST[‘password’];
$md5password = md5($password);
$sql = “SELECT uid,username FROM user WHERE username='{$username}’ AND
password='{$md5password}'”;
$query = mysql_query($sql, $link);
$userinfo = mysql_fetch_array($query, MYSQL_ASSOC);
if(!empty($userinfo)){
//登录成功,打印出会员信息
echo ‘<pre>’,print_r($userinfo, 1),'</pre>’;
} else {
echo “用户称无存在或者密码错误!”;
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset=”utf-8″>
<title>Web登录系统SQL注入实例</title>
</head>
<body>
<form name=”LOGIN_FORM” method=”post” action=””>
签到帐号: <input type=”text” name=”username” value=”” size=30
/><br /><br />
签到密码: <input type=”text” name=”password” value=”” size=30
/><br /><br />
<input type=”submit” value=”登录” />
</form>
</body>
</html>

此刻若是输入是的用户名 plhwin 和密码 123456,执行的SQL语句为:

<pre>
SELECT uid,username FROM user WHERE username=’plhwin’ AND
password=’e10adc3949ba59abbe56e057f20f883e’
</pre>

地方语句没有任何问题,可以看来页面打印出了登录成功后底会员信息,但若发捣蛋鬼输入的用户称也
plhwin' AND 1=1-- hack,密码轻易输入,比如aaaaaa,那么拼接之后的SQL查询语句就改成了如下内容:
<pre>
SELECT uid,username FROM user WHERE username=’plhwin’ AND 1=1– hack’
AND password=’0b4e7a0e5fe84ad35fb5f95b9ceeac79′
</pre>

实施方的SQL语句,因为1=1是永久成立之口径,这代表黑客只需要明白别人的会员名,无需掌握密码便会胜利登录到系统。

经过脚本执行上下文获取语言绑定对象的示范

   /**
     * 通过脚本执行上下文获取语言绑定对象的示例
     */
    public static void useScriptContextValues(){
        try{
            ScriptEngine engine = getJavaScriptEngine();
            ScriptContext context = engine.getContext();
            Bindings bindings = context.getBindings(ScriptContext.ENGINE_SCOPE);
            bindings.put("name","Arthur Ming");
            engine.eval("print(name)");
        } catch (Exception e){
            e.printStackTrace();
        }
    }

安确定SQL注入漏洞

通过上述之实例,我们仍然还见面生出问号:黑客并不知道我们程序代码的逻辑与SQL语句的写法,他是怎么样确定一个网站是否留存SQL注入漏洞呢?一般说来有以下2种途径:

本子引擎默认的语言绑定对象的言传身教

    /**
    * 脚本引擎默认的语言绑定对象的示例
     */
    public static void useDefaultBinding(){
        try{
            ScriptEngine  engine = getJavaScriptEngine();
            engine.put("name","Arthur");
            engine.eval("var message = 'Hello,' + name;");
            engine.eval("print(message);");
            Object obj = engine.get("message");
            System.out.println(obj);
        }catch (Exception e){
            System.out.println("异常信息:"+e.getMessage());
        }
    }

3、绑定变量,使用预编译语句

MySQL的mysqli使得提供了预编译语句的支持,不同之程序语言,都各自发出以预编译语句的点子,我们这里还因PHP为例,编写userinfo2.php代码:

<pre>
<?php
header(‘Content-type:text/html; charset=UTF-8’);
$username = isset($_GET[‘username’]) ? $_GET[‘username’] : ”;
$userinfo = array();
if($username){
//使用mysqli驱动连接demo数据库
$mysqli = new mysqli(“localhost”, “root”, “root”, ‘demo’);
//使用问号替代变量位置
$sql = “SELECT uid,username FROM user WHERE username=?”;
$stmt = $mysqli->prepare($sql);
//绑定变量
$stmt->bind_param(“s”, $username);
$stmt->execute();
$stmt->bind_result($uid, $username);
while ($stmt->fetch()) {
$row = array();
$row[‘uid’] = $uid;
$row[‘username’] = $username;
$userinfo[] = $row;
}
}
echo ‘<pre>’,print_r($userinfo, 1),'</pre>’;
</pre>

从今地方的代码可以观看,我们先后里连从未以addslashes函数,但是浏览器里运行
http://localhost/test/userinfo2.php?username=plhwin' AND 1=1-- hack里得无至另外结果,说明SQL漏洞以斯次里连无存。

其实,绑定变量使用预编译语句是防备SQL注入的特级艺术,使用预编译的SQL语句语义不会见出转移,在SQL语句被,变量用问号?表示,黑客就是本事再不行,也无能为力更改SQL语句的结构,像上面例子中,username变量传递的plhwin' AND 1=1-- hack参数,也才见面当作username字符串来诠释查询,从根本上杜绝了SQL注入攻击的发生。

自定义属性保存于言语绑定对象中示范

    /**
     * 自定义属性保存在语言绑定对象中示例
     */
    public static void attributeInBindings(){
        try{
            ScriptEngine engine = getJavaScriptEngine();
            ScriptContext context = engine.getContext();
            context.setAttribute("name1","Arthur Ming",ScriptContext.GLOBAL_SCOPE);
            context.setAttribute("name2","明国宾",ScriptContext.ENGINE_SCOPE);
            engine.eval("print(name1);");
            engine.eval("print(name2);");
        }catch (Exception e){
            e.printStackTrace();
        }
    }

广大攻击方式

常备,在Web安全领域,常见的攻击方式大概发生以下几栽:
1、SQL注入攻击
2、跨站脚论攻击 – XSS
3、跨站伪造请求攻击 – CSRF
4、文件上污染漏洞攻击
5、分布式拒绝服务攻击 – DDOS

说只写外话,本来就篇稿子一开始的题目叫做
「Web安全的时表现攻击方式与预防」,我本来想管方的当下5种方式都举描绘于相同首文章里,可是刚写了第一只SQL注入攻击的当儿,就发现文章篇幅就不缺了,又生为难再次进行大的简单,所以索性将Web安全分成一个层层,分多首文章来展现给大家,下面你看底虽是首先首「Web安全的SQL注入攻击的技能及预防」。

打定义语言绑定对象的言传身教

    /**
     * 自定义语言绑定对象的示例
     */
    public static void userCustomBinding(){
        try{
            ScriptEngine engine = getJavaScriptEngine();
            Bindings bindings = new SimpleBindings();
            bindings.put("hobby","playe games");
            engine.eval("print('I like ' + hobby);",bindings);
        }catch(Exception e){
            System.out.println("异常信息:"+e.getMessage());
        }
    }

数据库信息加密安全

深信大家都还针对2011年暴露的CSDN拖库事件记忆犹新,这档子业务导致CSDN处在风口浪尖被世家痛骂的故即在于他们还是公开存储用户的密码,这引发了科技界对用户信息安全更是密码安全之阳关注,我们当防止SQL注入的来的同时,也应有未雨绸缪,说不定下一个深受拖库的即是你,谁知道啊。

以Web开发被,传统的加解密大致可分为三种植:

1、对如加密:即加密方和解密方都采用相同之加密算法和密钥,这种方案的密钥的保留好主要,因为算法是当面的,而密钥是保密的,一旦密匙泄露,黑客还是可肆意解密。常见的对称加密算法有:AESDES等。

2、非对如加密:即利用不同的密钥来开展加解密,密钥被分为公钥和私钥,用私钥加密的数目必须用公钥来解密,同样用公钥加密的数码要用相应的私钥来解密,常见的非对如加密算法有:RSA等。

3、不可逆加密:利用哈希算法使数据加密之后无法解密回原数据,这样的哈希算法常用之来:md5SHA-1等。

当我们地方登录系统的演示代码中,$md5password = md5($password);自当下词代码可以看出运了md5的不可逆加密算法来囤积密码,这吗是大抵年来业界常用的密码加密算法,但是这还是未安全。为什么吧?

当即是坐md5加密有一个风味:同样的字符串经过md5哈希计算后转的加密字符串也是一致的,由于业界采用这种加密的方长期,黑客们也准备了投机强大的md5彩虹表来接向匹配加密前的字符串,这种用于逆向反推MD5加密的彩虹表在互联网及随处可见,在Google里使用md5 解密作首要词搜索,一下纵可知找到md5于线破解网站,把咱插入用户数据上的MD5加以密字符串e10adc3949ba59abbe56e057f20f883e填入进,瞬间即可知获得加密前的密码:123456。当然也并无是各个一个且能够得逞,但好毫无疑问之是,这个彩虹表会越来越健全。

为此,我们发出迫切的需求下双重好的措施对密码数据开展不可逆加密,通常的做法是啊每个用户确定不同的密码加盐(salt)后,再混合用户之诚实密码进行md5加密,如以下代码:

<pre>
//用户注册上装的password
$password = $_POST[‘password’];
//md5加密,传统做法直接以加密后的字符串存入数据库,但眼看不够,我们继续改善
$passwordmd5 = md5($password);
//为用户生成不同之密码盐,算法可以因自己事情的内需而不同
$salt = substr(uniqid(rand()), -6);
//新的加密字符串包含了密码盐
$passwordmd5 = md5($passwordmd5.$salt);
</pre>

实行结果

语言 3

    自定义属性实际上为保留在语言绑定对象被。

Web安全简史

当Web1.0时日,人们又多是关心服务器端动态脚本语言的安康问题,比如将一个不过尽脚本(俗称Webshell)通过脚本语言的纰漏上传到服务器上,从而获得服务器权限。在Web发展最初,随着动态脚本语言的上进及推广,以及早期工程师对安全题材认知不足造成众多”安全血案”的发,至今依然遗留下许多历史题材,比如PHP语言至今仍鞭长莫及从言语本身杜绝「文件包含漏洞」(参见这里),只能依靠工程师可以的代码规范以及安康意识。

陪伴着Web2.0、社交网络、微博等同样多级新型互联网产品之起来,基于Web环境之互联网采用更加大,Web攻击的一手也愈发多样,Web安全史上之一个要里程碑是横1999年察觉的SQL注入攻击,之后的XSS,CSRF等攻击手段进一步强大,Web攻击的思绪也自服务端转向了客户端,转向了浏览器和用户。

当安康世界,一般用帽子的颜料来比喻黑客的易与恶,白帽子是赖那些工作以反黑客领域的技能专家,这个群体是”善”的之意味;而黑帽子则是凭借那些以黑客技术造成损坏还谋取私利造成违法的群落,他们是”恶”的代表。

“白帽子”和”黑帽子”是零星个意对立的群体。对于黑帽子而言,他们要找到网的一个切入点就足以达到入侵破坏的目的,而白帽子必须将自己系统具备可能为突破之地方还设防,以保证系统的安全运行。

即看起好像是不公平的,但是安全世界里之平整就是是如此,可能我们的网站1000地处都布防的慌好,考虑的慌完善,但是一旦有一个地方疏忽了,攻击者就会用是点开展突破,让我们另外的1000处于努力白费。

1.脚本发动机

     
 一段子脚本的施行要由该脚本语言对应的台本引擎来完成。一个Java程序可以选择而富含多脚本语言的履引擎,这统统由程序的需来决定。程序中所用到之脚本语言,都亟待发相应的脚本引擎。JSR
233着定义了本子引擎的挂号及搜索体制。这对于脚本引擎的实现者来说,是得了解之。而貌似的开发人员只需要了解哪些通过脚本引擎管理器来博取相应语言的剧本引擎,并不需要了解脚本引擎的注册机制。Java
SE6中由带了JavaScript语言的脚本引擎,是冲Mozilla的Rhino来实现之。对于其他的脚本语言,则需要下载对应之台本引擎的库并放在程序的切近路径中。一般如果在类路径中遭遇,脚本引擎就可叫应用程序发现并下。
       
首先介绍脚本引擎的一般用法。首先创建一个剧本引擎管理器javax.script.ScriptEngineManager对象,再经过管理器来询问所要的JavaScript脚论引擎,最后经脚本引擎来推行JavaScript代码。

1、检查变量数据类型和格式

万一您的SQL语句是相仿where id={$id}这种样式,数据库里有的id都是数字,那么尽管应有当SQL被实践前,检查确保变量id是int类型;如果是接受邮箱,那即便应当检查并严厉保证变量一定是邮箱的格式,其他的档次比如日期、时间相当也是一个道理。总结起来:如果是发生固定格式的变量,在SQL语句执行前,应该严格遵照固定格式去检查,确保变量是我们预料的格式,这样十分十分程度及得以免SQL注入攻击。

准,我们前接受username参数例子中,我们的产品设计应该是以用户注册之一模一样方始,就生一个用户名的平整,比如5-20个字符,只能由大小写字母、数字以及一些安全的符号组成,不包含特殊字符。此时咱们应当发一个check_username的函数来进行统一之检查。不过,仍然发生无数例外情况并无克采用至这无异于轨道,比如文章披露系统,评论系统等必须要允许用户提交任意字符串的面貌,这即需采用过滤等另外方案了。

履结果

语言 4

     
 上面的代码中凡是通过脚本引擎的名进行搜寻的。实际上,脚本引擎管理同步支持三种植检索脚本引擎的点子,分别通过名称、文件扩展名及MIME类型来完成。

2、盲注

只有运维人员疏忽,否则大部分底Web运营网站应都关闭了不当提示信息,此时攻击者一般会使用盲注的技术来进展反复的品味判断。
仍然因地方的数目表user为条例,我们事先的翻会员详情页面的url地址为userinfo.php?username=plhwin,此时黑客分别访问userinfo.php?username=plhwin' AND 1=1-- hackuserinfo.php?username=plhwin' AND 1=2-- hack,如果前者访问能够回到正常的音信而后人不能够,就核心得以断定这网站在SQL注入漏洞,因为后者的1=2这表达式永远不建,所以即使username传入了是的参数为无力回天通过,由这个可以推测是页面是SQL注入漏洞,并且可以经过username参数进行注入。

履结果

语言 5

1、错误提示

如若目标Web网站开启了错误显示,攻击者就足以经过反复调整发送的参数、查看页面打印的错误信息,推测出Web网站使用的数据库及开发语言等重点消息。

       对于这些运行于Java虚拟机平台及之脚本语言来说,并不需要为他们准备额外的运转条件,直接复用已有些Java虚拟机环境即可。这即省了当运作环境达标所用的本金投入。在行使开发被动用脚本语言,实际上是“多语言开发”的同一种植非常好的尽,即基于使用之需以及言语本身的性状来挑选最为宜的变成语言,以高速高效地化解使用被的某部平等有的问题。多种不同语言实现之零部件组合起来,用Java编写核心工作逻辑,用Ruby来进行多少处理。不同语言编写的代码可以又运转的跟一个Java虚拟机之上。这些脚本语言和Java语言中的相互,是出于脚本语言支持API来形成的。

何以防御SQL注入

对于服务器配置范围的警备,应该保证生产条件之Webserver是关门错误信息的,比如PHP在产环境之部署文件php.ini中之display_errors应该设置也Off,这样就算关门了左提示,下面我们更多之打编码的角度来探哪防止SQL注入。

地方用单薄独实例分析了SQL注入攻击的技艺,可以看看,但凡发生SQL注入漏洞的次序,都是因程序要经受来自客户端用户输入的变量或URL传递的参数,并且这变量或参数是整合SQL语句之一模一样有些,对于用户输入的情或传递的参数,我们该要时刻保持警惕,这是安全领域里之「外部数据不可相信」的口径,纵观Web安全领域的各种攻击方式,大多数且是盖开发者违反了这个条件要导致的,所以当会体悟的,就是由变量的检测、过滤、验证下手,确保变量是开发者所预期的。

自定义语言绑定对象的以身作则的实施结果

语言 6

    通过eval方法传递的语绑定对象,仅以手上eval调用中生效,并无会见转引擎默认的语言绑定对象。

实例一

通过传播username参数,在页面打印出此会员的详细信息,编写
userinfo.php 程序代码:

<pre>
<?php
header(‘Content-type:text/html; charset=UTF-8’);
$username = isset($_GET[‘username’]) ? $_GET[‘username’] : ”;
$userinfo = array();
if($username){
//使用mysqli驱动连接demo数据库
$mysqli = new mysqli(“localhost”, “root”, “root”, ‘demo’);
$sql = “SELECT uid,username FROM user WHERE username='{$username}'”;
//mysqli multi_query 支持实施多修MySQL语句
$query = $mysqli->multi_query($sql);
if($query){
do {
$result = $mysqli->store_result();
while($row = $result->fetch_assoc()){
$userinfo[] = $row;
}
if(!$mysqli->more_results()){
break;
}
} while ($mysqli->next_result());
}
}
echo ‘<pre>’,print_r($userinfo, 1),'</pre>’;
</pre>

方是顺序要落实的功用是因浏览器传入的用户称参数,在页面上打印出这个用户之详细信息,程序写的这样复杂是以我以了mysqli的教,以便能采用及
multi_query
方法来支撑以推行多条SQL语句,这样会更好之辨证SQL注入攻击的危害性。

比方我们好透过 http://localhost/test/userinfo.php?username=plhwin
这个URL来访问到实际有会员的详情,正常状态下,如果浏览器里流传的username是法定的,那么SQL语句会履:

<pre>
SELECT uid,username FROM user WHERE username=’plhwin’
</pre>

不过,如果用户以浏览器里拿传播的username参数变为
plhwin';SHOW TABLES-- hack,也便是当URL变为
http://localhost/test/userinfo.php?username=plhwin';SHOW TABLES-- hack
的下,此时咱们先后实际履行之SQL语句变成了:

<pre>
SELECT uid,username FROM user WHERE username=’plhwin’;SHOW TABLES–
hack’
</pre>

瞩目:在MySQL中,最后连的点滴只减号表示忽略这个SQL减号后面的口舌,我本机的MySQL版本号为5.6.12,目前几乎有SQL注入实例都是一直利用简单只减号结尾,但是实际上测试,这个本号的MySQL要求简单个减号后面总得使起空格才能够正常注入,而浏览器是碰头自行删除掉URL尾部空格的,所以我们的流入会以点滴个减号后面统一上加任意一个字符或单词,本篇文章的SQL注入实例统一为
-- hack 结尾。

由此地方的SQL注入后,原本想如果实施查询会员详情的SQL语句,此时尚附加执行了
SHOW TABLES;
语句,这明摆着不是开发者的本意,此时足于浏览器里看页面的输出:

<pre>
Array
(
[0] => Array
(
[uid] => 1
[username] => plhwin
)

[1] => Array
    (
        [Tables_in_demo] => user
    )

)
</pre>

您可知清楚的相,除了会员的消息,数据库表的讳user也为打印在了页面上,如果滋事的黑客此时将参数换成
plhwin';DROP TABLE user-- hack,那以生出灾难性的惨重结果,当你当浏览器被尽
http://localhost/test/userinfo.php?username=plhwin';DROP TABLE user-- hack
这个URL后,你见面发觉整整 user 数据表都消失不见了。

透过上面的例子,大家早就认及SQL注入攻击的危害性,但是依旧会有人心里存问题,MySQL默认驱动的mysql_query措施现在早就不支持多长语句以推行了,大部分开发者怎么可能像上面的言传身教程序那样以累又无安全。

不错,在PHP程序中,MySQL是无容许以一个mysql_query受应用分号执行多SQL语句的,这令许多开发者都觉得MySQL本身即非容许多告词执行了,但骨子里MySQL早以4.1版就允许多告诉句执行,通过PHP的源代码,我们发现实际上只是是PHP语言自身限制了这种用法,具体情况大家好看就首文章「PHP+MySQL多报句执行」。

管脚论运行时之出口写副到文件被的示范

    /**
     * 把脚本运行时的输出写入到文件中。
     */
    public static void scriptToFile(){
        try {
            ScriptEngine engine = getJavaScriptEngine();
            ScriptContext context = engine.getContext();
            context.setWriter(new FileWriter("output.txt"));
            engine.eval("print('Hello World!');");
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

ScriptEngineManagerDemo

语言 7

2.语言绑定

     
 脚本语言支持API的一个那个酷优势在于它规范了Java语言和脚本语言之间的交互方式,使Java语言编写的顺序可以跟剧本之间展开双向的方式调用和数量传递。方法调用的法子会于稍后介绍。数据传递是经语言绑定对象来就的。所谓的绑定对象就是一个简便的哈希表,用来存放在和得需要共享的多少。所有数据还对许者哈希表中之一个章,是略的名值对。接口javax.script.Bindings定义了语言绑定对象的接口,继承自java.util.Map接口。一个本子引擎在履行过程中恐怕会见使用多个语言绑定对象。不同语言绑定对象的作用域不同。在默认情况下,脚本引擎会提供多只语言绑定对象,用来存放于尽进程被有全局对象等。ScriptEngine类提供了put和get方法对台本引擎中一定作用域的默认语言绑定对象进行操作。程序可以直接利用是默认的言语绑定对象,也足以以好的语言绑定对象。在脚本语言的推行进程被,可以拿语言绑定对象看成是一个附加的变量映射表。在解析变量值的当儿,语言绑定对象吃的称也会叫考虑在内。脚本执行过程遭到出的全局变量等情节,会起于言语绑定对象吃。通过这种艺术尽管形成了Java以及脚本语言之间的双向数据传递。

3.2从定义属性

    ScriptContext中吗起和ServletConext中接近之得到与设置属性之法,即setAttribute和getAttribute。所不同之是,ScriptContext中之属性是起作用域之分的。不同作用域的界别在寻找属性时之顺序不同。每个作用域都盖一个遥相呼应之平头表示该招来顺序。该整数值越小,说明查找时之一一越优先。优先级赛的作用域中的性能会藏优先级低之作用域中之同名属性。因此,设置属性时用显式地指定所在地作用域。在博属性地时,既可挑选当指定地作用域中摸索,也得选择因作用域优先级电动进行搜。
    不过脚本执行上下文实现着蕴藏地作用域是一定的,开发人员不可知随便定义自己之作用域。通过ScriptContext的getScopes方法好取得有可用的作用域列表。ScriptContext中优先定义了少于单作用域:

  • 常量ScriptContext.ENGINE_SCOPE代表的作用域对应之是时下底脚本引擎。
  • 常量ScriptContext.GLOBAL_SCOPE代表的作用域对应的凡自从同引擎工厂被创造出来的具备脚本引擎对象。

    说明: 前端的先级较高

#### 作用域影响同名属性查找示例

       /**
     * 作用域影响同名属性查找的示例
     */
    public static void scriptContextAttribute(){
        try{
            ScriptEngine engine = getJavaScriptEngine();
            ScriptContext context = engine.getContext();
            context.setAttribute("name","Arthur Ming",ScriptContext.GLOBAL_SCOPE);
            context.setAttribute("name","明国宾",ScriptContext.ENGINE_SCOPE);
            System.out.println(context.getAttribute("name"));
            System.out.println(context.getAttribute("name",ScriptContext.GLOBAL_SCOPE));
        } catch(Exception e){
            System.out.println("异常信息:"+e.getMessage());
        }
    }

#### 执行结果

![](https://images2015.cnblogs.com/blog/1001991/201703/1001991-20170326223034830-213077996.png)

3.脚依照实施上下文

    与剧本引擎执行相关的另外一个重要之接口是javax.script.ScriptContext,其中饱含脚论引擎执行过程的有关上下文信息,可以通过和Java
EE中servlet规范被的javax.servlet.ServletContext接口来进展类比。脚本引擎通过者达成下文对象获得和剧本执行相关的音信,也同意开发人员通过这目标来安排脚本引擎的作为。该上下文对象要包含以下3类信息:

3.1输入语言与输出

    首先介绍与下部论输入和输出的部署信息,其中包脚论在尽着因故来读取数据输入的java.io.Reader对象及出口正确内容以及错信息之java.io.Writer对象。在默认情况下,脚本的输入输出都以产生在正儿八经控制台中。

       随着Java平台的风靡,很多的脚本语言(scripting language)都好运行在Java虚拟机啊上,其中于盛行的有JavaScript、JRuby、Jython和Groovy等。相对Java语言来说,脚本语言由于那个灵活性非常高,非常适合在某些情况下以,比如描述下被复杂多变的事体逻辑,并于应用运行过程中开展动态修改;为使用提供平等栽世界特定语言(Domainspecific Language,DSL),供没有技术背景的普通用户使用;作为以中逐一零部件之间的“胶水”,快速进行零部件之间的组成;快速开有利用的原型系统,从而迅速赢得用户反馈,并开展改良;帮助开发人员快速编写测试用例等。等于这些状况,如果下java来开则行倍功半。

实践结果

语言 8

    通过ScriptContext的setBindings方法设置的言语绑定对象见面影响到ScriptEngine在实行脚本时变量解析。ScriptEngine的put和get方法所操作的实际就是ScriptContext中之作用域为ENGINE_SCOPE的语言绑定对象。

Java语言的动态性之脚本语言支持API

3.1语言绑定对象

    脚论实施上下文中的末梢一近乎消息是语言绑定对象。语言绑定对象也是同意域相对应之,同样的作用域优先级依次对语言绑定对象啊适用。这样的优先级依次会指向剧本执行时之变量解析出影响。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图