========================================第1页========================================
如何查看
sqlserver
日志的方法
定期分析sqlserver日志是DBA很重要的任务,那如何才能查看sqlserver日志
呢?
在SQL Server 7.0和SQL Server2000中,可以用下面的命令查看:
DBCC log ( {dbid|dbname}, [, type={0|1|2|3|4}] )
参数:
Dbid or dbname - 任一数据库的ID或名字
type - 输出结果的类型:
0 - 最少信息(operation, context, transaction id)
1 - 更多信息(plus flags, tags, row length)
2 - 非常详细的信息(plus object name, index name,page id, slot id)
3 - 每种操作的全部信息
4 - 每种操作的全部信息加上该事务的16进制信息
默认 type = 0
要查看MSATER数据库的事务日志可以用以下命令:
DBCC log (master)
释放日志空间
释放日志空间
释放日志空间
释放日志空间
1.清空日志
DUMP TRANSACTION 库名 WITH NO_LOG
2.截断事务日志:
BACKUP LOG 数据库名 WITH NO_LOG
3.收缩数据库文件(如果不压缩,数据库的文件不会减小
企业管理器--右键你要压缩的数据库--所有任务--收缩数据库--收缩文件
--选择日志文件--在收缩方式里选择收缩至XXM,这里会给出一个允许收
缩到的最小M数,直接输入这个数,确定就可以了
--选择数据文件--在收缩方式里选择收缩至XXM,这里会给出一个允许收
缩到的最小M数,直接输入这个数,确定就可以了
也可以用SQL语句来完成
--收缩数据库
========================================第2页========================================
DBCC SHRINKDATABASE(客户资料)
--收缩指定数据文件,1是文件号,可以通过这个语句查询到:select * from
sysfiles
DBCC SHRINKFILE(1)
4.为了最大化的缩小日志文件(如果是sql 7.0,这步只能在查询分析器中进行)
a.分离数据库:
企业管理器--服务器--数据库--右键--分离数据库
b.在我的电脑中删除LOG文件
c.附加数据库:
企业管理器--服务器--数据库--右键--附加数据库
此法将生成新的LOG,大小只有500多K
或用代码:
下面的示例分离 pubs,然后将 pubs 中的一个文件附加到当前服务器。
a.分离
E X E C sp_detach_db @dbname = 'pubs'
b.删除日志文件
c.再附加
E X E C sp_attach_single_file_db @dbname = 'pubs',
@physname = 'c:\Program Files\Microsoft SQL
Server\MSSQL\Data\pubs.mdf'
5.为了以后能自动收缩,做如下设置:
企业管理器--服务器--右键数据库--属性--选项--选择"自动收缩"
--SQL语句设置方式:
E X E C sp_dboption '数据库名', 'autoshrink', 'TRUE'
6.如果想以后不让它日志增长得太大
企业管理器--服务器--右键数据库--属性--事务日志
--将文件增长限制为xM(x是你允许的最大数据文件大小)
--SQL语句的设置方式:
alter database 数据库名 modify file(name=逻辑文件名,maxsize=20)
特别注意:
请按步骤进行,未进行前面的步骤,请不要做后面的步骤
否则可能损坏你的数据库.
一般不建议做第4,6两步
第4步不安全,有可能损坏数据库或丢失数据
第6步如果日志达到上限,则以后的数据库处理会失败,在清理日志后才能恢
复.
另外提供一种更简单的方法,建议大家使用。
更简单的方法:
1。右建数据库属性窗口--故障还原模型--设为简单
2。右建数据库所有任务--收缩数据库
3。右建数据库属性窗口--故障还原模型--设为大容量日志记录
========================================第3页========================================
ASP
制作显
IP
签名图片
<!--#include file="conn.asp"-->
<!--#include file="inc/config.asp"-->
<%Response.ContentType = "image/gif"
ConnDatabase
Dim tempip,myipnumeber,sql,rs1
Dim country,city
tempip=ReqIP
tempip = Split(tempip,".")
if Ubound(tempip)=3 then
For i=0 To Ubound(tempip)
tempip(i)=left(tempip(i),3)
if isnumeric(tempip(i)) then
tempip(i)=cint(tempip(i))
else
tempip(i)=0
end if
next
myipnumeber=tempip(0)*256*256*256+tempip(1)*256*256+tempip(2)*25
6+tempip(3)
End If
sql="select country,city from DV_Address where IP1<="&myipnumeber&" and
IP2>="&myipnumeber
set rs1=conn.execute(sql)
if not rs1.eof Then
country = rs1(0)
city = rs1(1)
Else
country = "51Tiao.Com"
city = ""
End If
rs1.close : Set rs1 = Nothing
CloseDatabase
Dim LocalFile,TargetFile
LocalFile = Server.MapPath("Ip.gif")
Dim Jpeg
Set Jpeg = Server.CreateObject("Persits.Jpeg")
If -2147221005=Err then
Response.write "没有这个组件,请安装!" '检查是否安装AspJpeg组件
Response.End()
========================================第4页========================================
End If
Jpeg.Open (LocalFile) '打开图片
If err.number then
Response.write"打开图片失败,请检查路径!"
Response.End()
End if
Dim aa
aa=Jpeg.Binary '将原始数据赋给aa
'=========加文字水印====http://www.devdao.com/=============
Jpeg.Canvas.Font.Color = &H000000 '水印文字颜色
Jpeg.Canvas.Font.Family = "宋体" '字体
Jpeg.Canvas.Font.Bold = False '是否加粗
Jpeg.Canvas.Font.Size = 12 '字体大小
Jpeg.Canvas.Font.ShadowColor = &Hffffff '阴影色彩
Jpeg.Canvas.Font.ShadowYOffset = 1
Jpeg.Canvas.Font.ShadowXOffset = 1
Jpeg.Canvas.Brush.Solid = False
Jpeg.Canvas.Font.Quality = 4 ' '输出质量
Jpeg.Canvas.PrintText 30,30,"-------------------------------------" '
水印位置及文字
Jpeg.Canvas.PrintText 30,50," 你的IP: "& ReqIP
Jpeg.Canvas.PrintText 30,70," 你的位置: "&country&" "&city
Jpeg.Canvas.PrintText 30,90," 操作系统: "&ClientInfo(0)
Jpeg.Canvas.PrintText 30,110," 浏 览 器:
"&RegExpFilter("Microsoft<sup>®</sup> ", ClientInfo(1), 0, "")
Jpeg.Canvas.PrintText 30,130,"-------------------------------------"
Jpeg.Canvas.PrintText 30,145,"个性签名来自风易在线
www.knowsky.com
"
bb=Jpeg.Binary '将文字水印处理后的值赋给bb,这时,文字水印没有不透明
度
'============调整文字透明度================
Set MyJpeg = Server.CreateObject("Persits.Jpeg")
MyJpeg.OpenBinary aa
Set Logo = Server.CreateObject("Persits.Jpeg")
Logo.OpenBinary bb
MyJpeg.DrawImage 0,0, Logo, 0.9 '0.3是透明度
cc=MyJpeg.Binary '将最终结果赋值给cc,这时也可以生成目标图片了
Response.BinaryWrite cc '将二进输出给浏览器
set aa=nothing
set bb=nothing
set cc=nothing
Jpeg.close : Set Jpeg = Nothing
========================================第5页========================================
MyJpeg.Close : Set MyJpeg = Nothing
Logo.Close : Set Logo = Nothing
%>
'--------------------------------------------------
'File: conn.asp
<%dim conn,dbpath,UserIP
sub ConnDatabase
On Error Resume next
set conn=server.createobject("adodb.connection")
DBPath = Server.MapPath("IP.MDB")
conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & DBPath
If Err Then
err.Clear
Set Conn = Nothing
Response.Write "数据库正在更新中,请稍后再试!"
Response.End
End If
End Sub
Sub CloseDatabase
Conn.close
Set Conn = Nothing
End Sub%>
'-------------------------------------------------
'File: config.asp
<%
Dim User_Agent
User_Agent = Request.ServerVariables("HTTP_USER_AGENT")
' ============================================
' 获取客户端配置
' ============================================
Public Function ClientInfo(sType)
If sType = 0 Then
If InStr(User_Agent, "Windows 98") Then
ClientInfo = "Windows 98"
ElseIf InStr(User_Agent, "Win 9x 4.90") Then
ClientInfo = "Windows ME"
ElseIf InStr(User_Agent, "Windows NT 5.0") Then
ClientInfo = "Windows 2000"
ElseIf InStr(User_Agent, "Windows NT 5.1") Then
========================================第6页========================================
ClientInfo = "Windows XP"
ElseIf InStr(User_Agent, "Windows NT 5.2") Then
ClientInfo = "Windows 2003"
ElseIf InStr(User_Agent, "Windows NT") Then
ClientInfo = "Windows NT"
ElseIf InStr(User_Agent, "unix") or InStr(User_Agent,
"Linux") or InStr(User_Agent, "SunOS") or InStr(User_Agent, "BSD")
Then
ClientInfo = "Unix & Linux"
Else
ClientInfo = "Other"
End If
ElseIf sType = 1 Then
If InStr(User_Agent, "MSIE 7") Then
ClientInfo = "Microsoft<sup>®</sup> Internet Explorer 7.0"
ElseIf InStr(User_Agent, "MSIE 6") Then
ClientInfo = "Microsoft<sup>®</sup> Internet Explorer 6.0"
ElseIf InStr(User_Agent, "MSIE 5") Then
ClientInfo = "Microsoft<sup>®</sup> Internet Explorer 5.0"
ElseIf InStr(User_Agent, "MSIE 4") Then
ClientInfo = "Microsoft<sup>®</sup> Internet Explorer 4.0"
ElseIf InStr(User_Agent, "Netscape") Then
ClientInfo = "Netscape<sup>®</sup>"
ElseIf InStr(User_Agent, "Opera") Then
ClientInfo = "Opera<sup>®</sup>"
Else
ClientInfo = "Other"
End If
End If
End Function
' ============================================
' 按照指定的正则表达式替换字符
' ============================================
Public Function RegExpFilter(Patrn, Str, sType, ReplaceWith)
Dim RegEx
Set RegEx = New RegExp
If sType = 1 Then
RegEx.Global = True
Else
RegEx.Global = False
End If
RegEx.Pattern = Patrn
========================================第7页========================================
RegEx.IgnoreCase = True
RegExpFilter = RegEx.Replace(Str, ReplaceWith)
End Function
Public Function ReqIP()
ReqIP = Request.ServerVariables("HTTP_X_FORWARDED_FOR")
If ReqIP = "" or IsNull(ReqIP) Then ReqIP =
Request.ServerVariables("REMOTE_ADDR")
End Function
%>
网站被上传木马
(
网站被黑
)
如何处理
有时会收到一些客户反映网站被黑,或被上传木马,当用户访问网站时就会下载
病毒或者木马,杀毒软件弹出病毒的提示. 这种情况是以下2种情况导致的.
第一种情况
第一种情况
第一种情况
第一种情况:
:
:
: 客户网站存在文件上传漏洞
客户网站存在文件上传漏洞
客户网站存在文件上传漏洞
客户网站存在文件上传漏洞.
..
.导致黑客可以使用这漏洞
导致黑客可以使用这漏洞
导致黑客可以使用这漏洞
导致黑客可以使用这漏洞,
,,
,上传黑客
上传黑客
上传黑客
上传黑客
文件
文件
文件
文件.
..
. 然后黑客可以对该用户网站所有文件进行任意修改,这种情况比较普遍.
针对这种情况, 用户需要找技术人员. 检查出网站漏洞并彻底修复,并检查看网
站是否还有黑客隐藏的恶意文件.
原因: 很多网站都需要使用到文件上传功能,例如很多网站需要发布产品图片等.
文件上传功能本来应该具有严格的限定. 例如:只允许用户只能上传JPG,GIF等
图片. 但由于程序开发人员考虑不严谨,或者直接是调用一些通用的文件上传组
件, 导致没对文件上传进行严格的检查.
处理: 处理关键是要用户自己知道自己网站哪些地方使用到了文件上传功能.
重点针对这个文件上传功能进行检查, 同时针对网站所有文件进行检查,排查可
疑信息. 同时也利用网站日志,对文件被修改时间进行检查,
1) 查到哪个文件被加入代码: 用户要查看自己网页代码.根据被加入代码的位
置,确定到底是哪个页面被黑, 一般黑客会去修改数据库连接文件或网站顶部/
底部 文件, 因为这样修改后用户网站所有页面都会被附加代码.
2) 查到被篡改文件后,使用Ftp查看文件最后被修改时间, 例如 Ftp里面查看
到conn.asp文件被黑,最后修改时间是 2008-2-22 10:34 分, 那么可以确定在
2008-2-22日10:34 分这个时间 有黑客使用他留下的黑客后门,篡改了你的
conn.asp这个文件. 到底是哪个文件? 可以使用网站日志查出来. 在
www.72dns.com 的虚拟主机管理里面. 使用获取网站日志功能. 获得到
2008-2-20 日的网站日志. 由于日志记录和真实时间有8小时时间差, 所以您
要检查的时间是 2:34分 左右. 以下是一个日志记录案例.
========================================第8页========================================
2008-02-22 02:34:16 W3SVC23 211.155.230.227 GET /favicon.ico
2008-02-22 02:34:29 W3SVC23 211.155.230.227 GET /favicon.ico
2008-02-22 02:34:29 W3SVC23 211.155.230.227 POST /news/uppic/569853.asp
2008-02-22 02:36:03 W3SVC23 211.155.230.227 GET /prod_Detail.asp id=59
2008-02-22 02:38:56 W3SVC23 211.155.230.227 GET /prod_detail.asp id=63
用户可以根据日志判定 /news/uppic/569853.asp 这个文件 应该是黑客上传的
文件.
3) 再重复2) 步. 查看569853.asp文件修改时间,再查出到底是哪个文件 导致
上传了569853.asp 这个文件. 查看到569853.asp 文件修改时间是2008-02-20
18:58分, 找到有问题的文件. 结果追查到有问题的文件是
uploadPic.inc.asp.
2008-02-20 10:57:37 W3SVC23 211.155.230.227 GET /prod_ListCategory.asp
cid=18
2008-02-20 10:58:03 W3SVC23 211.155.230.227 POST
/news/admin/uploadPic.inc.asp
2008-02-20 11:08:43 W3SVC23 211.155.230.227 GET /uploadpic/nike.jpg
4) 就这样循环.最后可以查出是哪个文件有文件上传漏洞, 要修复这些文件上
传漏洞,并彻底检查网站代码,彻底删除黑客其他隐藏的黑客文件.
注意
注意
注意
注意:
::
:
1)
1)
1)
1) 很多用户网站被黑后
很多用户网站被黑后
很多用户网站被黑后
很多用户网站被黑后,
,,
,只是将被串改的文件修正过来
只是将被串改的文件修正过来
只是将被串改的文件修正过来
只是将被串改的文件修正过来.
..
.或重新上传
或重新上传
或重新上传
或重新上传,
,
,
, 这样是
这样是
这样是
这样是
没多大作用
没多大作用
没多大作用
没多大作用.
.
.
. 如果网站不修复漏洞
如果网站不修复漏洞
如果网站不修复漏洞
如果网站不修复漏洞.
..
.黑客可以很快再次利用这漏洞
黑客可以很快再次利用这漏洞
黑客可以很快再次利用这漏洞
黑客可以很快再次利用这漏洞,
,,
,对用户网站
对用户网站
对用户网站
对用户网站
再次入侵
再次入侵
再次入侵
再次入侵.
..
.
2)
2)
2)
2) 网站漏洞的检查和修复需要一定的技术人员才能处理
网站漏洞的检查和修复需要一定的技术人员才能处理
网站漏洞的检查和修复需要一定的技术人员才能处理
网站漏洞的检查和修复需要一定的技术人员才能处理.
..
.用户需要先做好文件
用户需要先做好文件
用户需要先做好文件
用户需要先做好文件
的备份
的备份
的备份
的备份.
..
.
第二种情况: 用户本地机器中毒了. 修改了用户自己本地的网页文件.然后用户
自己将这些网页文件上传到服务器空间上了. 这种情况比较少. 如是这种情况
用户要先彻底检查自己网站.
1. 这种病毒一般是搜索本地磁盘的文件,在网页文件的源代码中插入一段带有
病毒的代码,而一般最常见的方式是插入一个 iframe ,然后将这个 iframe 的
src 属性指向到一个带有病毒的网址。
2. 如何检测这种情况呢?
(1).浏览网站,右键查看源代码,在源代码里搜索 iframe ,看看有没有被插
入了一些不是自己网站的页面,如果有,一般就是恶意代码。
(2). 也是右键查看源代码,搜索 "script" 这个关键字,看看有没有被插入
一些不是自己域名下的的脚本,如果有,并且不是自己放上去的,那很可能也有
问题。
========================================第9页========================================
3.这种病毒怎么杀呢?
(1).有些人会说用查毒程序查过本地没有发现病毒,这就要看看本地的网站文
件是否带有这些恶意代码,如果有,那基本上可以肯定你的机器是曾经中过毒的,
这些病毒可能不是常驻内存的,并且有可能执行一次之后就将自己删除,所以用
查毒程序查不出来是很正常的。
(2).就算这些病毒是常驻内存,杀毒程序也可能查不出来,因为这种病毒的原
理很简单,其实就是执行一下文件磁盘扫描,找到那些网页文件(如 asp php
html)等格式的文件,然后打开它插入一段代码,然后再保存一下。因为它修改
的不是什么系统文件,病毒防火墙一般不会发出警告,如果它不是挂在一些系统
进程里,而是在某个特定的时刻运行一下就退出,这样被查出的可能性更少。
(3).手工删除这些病毒的一般方法:
a. 调出任务管理器,看看有没有一些不知名的程序在运行,如果有,用
windows的文件查找功能找到这个文件,右键查看属性,如果这个可执行文件的
摘要属性没有任何信息,而自己又不知道是什么东西,那很可能有问题,然后上
google搜索一个这个文件的信息,看看网上的资料显示是不是就是病毒,如果
是就先将其改名。。
b. 打开注册表编辑器,查看一下
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run有没
有一可疑的启动项,有的话就删除.
c. 查看本地机器的 windows 控制面板,看看“任务计划”那里有没有一些
不是自己定义的任务,如果有查看属性,找到这个任务所执行的可执行文件是哪
个,重复前面步骤 a 的方法进行查杀。
可能还有其它一些方法,暂时没想到。。。
4. 中毒的常见原因:
一般是因为上了一些烂网站,这些网站有木马,然后机器就中毒了,我们的服务
器一般不会中毒的,因为我们的工作人员不会在服务器上上一些乱七八糟的网
站,中毒的可能性很少。至于说其它客户上传了一些有问题的程序然后令服务器
中毒也是不成立的,因为普通的客户的IIS进程是没有权限去修改其它客户的网
站的。
ASP
网站漏洞解析及黑客入侵防范方法
如何更好的达到防范黑客攻击,本人提一下个人意见!第一,免费程序不要真的
就免费用,既然你可以共享原码,那么攻击者一样可以分析代码。如果在细节上
注意防范,那样你站点的安全性就大大的提高了。即使出现了SQL Injection
这样的漏洞,攻击者也不可能马上拿下你的站点。
由于ASP的方便易用,越来越多的网站后台程序都使用ASP脚本语言。但是,
由于ASP本身存在一些安全漏洞,稍不小心就会给黑客提供可乘之机。事实上,
安全不仅是网管的事,编程人员也必须在某些安全细节上注意,养成良好的安全
习惯,否则会给自己的网站带来巨大的安全隐患。目前,大多数网站上的ASP
程序有这样那样的安全漏洞,但如果编写程序的时候注意一点的话,还是可以避
========================================第10页========================================
免的。
1、用户名与口令被破解
攻击原理:用户名与口令,往往是黑客们最感兴趣的东西,如果被通过某种
方式看到源代码,后果是严重的。
防范技巧:涉及用户名与口令的程序最好封装在服务器端,尽量少在ASP
文件里出现,涉及与数据库连接的用户名与口令应给予最小的权限。出现次数多
的用户名与口令可以写在一个位置比较隐蔽的包含文件中。如果涉及与数据库连
接,在理想状态下只给它以执行存储过程的权限,千万不要直接给予该用户修改、
插入、删除记录的权限。
2、验证被绕过
攻击原理:现在需要经过验证的ASP程序大多是在页面头部加一个判断语
句,但这还不够,有可能被黑客绕过验证直接进入。
防范技巧:需要经过验证的ASP页面,可跟踪上一个页面的文件名,只有从
上一页面转进来的会话才能读取这个页面。
3、inc文件泄露问题
攻击原理:当存在ASP的主页正在制作且没有进行最后调试完成以前,可以
被某些搜索引擎机动追加为搜索对象。如果这时候有人利用搜索引擎对这些网页
进行查找,会得到有关文件的定位,并能在浏览器中查看到数据库地点和结构的
细节,并以此揭示完整的源代码。
防范技巧:程序员应该在网页发布前对它进行彻底的调试;安全专家则需要
加固ASP文件以便外部的用户不能看到它们。首先对.inc文件内容进行加密,
其次也可以使用.asp文件代替.inc文件使用户无法从浏览器直接观看文件的源
代码。inc文件的文件名不要使用系统默认的或者有特殊含义容易被用户猜测到
的名称,尽量使用无规则的英文字母。
4、自动备份被下载
攻击原理:在有些编辑ASP程序的工具中,当创建或者修改一个ASP文件时,
编辑器自动创建一个备份文件,比如:UltraEdit就会备份一个.bak文件,如你
创建或者修改了some.asp,编辑器会自动生成一个叫some.asp.bak文件,如果
你没有删除这个bak文件,攻击者可以直接下载some.asp.bak文件,这样
some.asp的源程序就会被下载。
防范技巧:上传程序之前要仔细检查,删除不必要的文档。对以BAK为后缀
的文件要特别小心。
========================================第11页========================================
5、特殊字符
攻击原理:输入框是黑客利用的一个目标,他们可以通过输入脚本语言等对
用户客户端造成损坏;如果该输入框涉及数据查询,他们会利用特殊查询语句,
得到更多的数据库数据,甚至表的全部。因此必须对输入框进行过滤。但如果为
了提高效率仅在客户端进行输入合法性检查,仍有可能被绕过。
防范技巧:在处理类似留言板、BBS等输入框的ASP程序中,最好屏蔽掉HTML、
JavaScript、VBScript语句,如无特殊要求,可以限定只允许输入字母与数字,
屏蔽掉特殊字符。同时对输入字符的长度进行限制。而且不但要在客户端进行输
入合法性检查,同时要在服务器端程序中进行类似检查。
6、数据库下载漏洞
攻击原理:在用Access做后台数据库时,如果有人通过各种方法知道或者
猜到了服务器的Access数据库的路径和数据库名称,那么他也能够下载这个
Access数据库文件,这是非常危险的。
防范技巧:
(1)为你的数据库文件名称起个复杂的非常规的名字,并把它放在几层目
录下。所谓 “非常规”, 打个比方说,比如有个数据库要保存的是有关书籍的
信息, 可不要给它起个“book.mdb”的名字,而要起个怪怪的名称,比如
d34ksfslf.mdb, 并把它放在如./kdslf/i44/studi/的几层目录下,这样黑客要
想通过猜的方式得到你的Access数据库文件就难上加难了。
(2)不要把数据库名写在程序中。有些人喜欢把DSN写在程序中,比如:
DBPath = Server.MapPath(“cmddb.mdb”)
conn.Open “driver={Microsoft Access Driver (*.mdb)};
dbq=”
& DBPath
假如万一给人拿到了源程序,你的Access数据库的名字就一览无余了。因
此建议你在ODBC里设置数据源,再在程序中这样写:
conn.open“shujiyuan”
(3)使用Access来为数据库文件编码及加密。首先在“工具→安全→加密
/解密数据库”中选取数据库(如:employer.mdb),然后按确定,接着会出现
“数据库加密后另存为”的窗口,可存为:“employer1.mdb”。
要注意的是,以上的动作并不是对数据库设置密码,而只是对数据库文件加
以编码,目的是为了防止他人使用别的工具来查看数据库文件的内容。
========================================第12页========================================
接下来我们为数据库加密,首先打开经过编码了的 employer1.mdb,在打开
时,选择“独占”方式。然后选取功能表的“工具→安全→设置数据库密码”,
接着输入密码即可。这样即使他人得到了employer1.mdb文件,没有密码他也是
无法看到 employer1.mdb中的内容。
7、防范远程注入攻击
这类攻击在以前应该是比较常见的攻击方式,比如POST攻击,攻击者可以随
便的改变要提交的数据值已达到攻击目的.又如:COOKIES 的伪造,这一点更值得
引起程序编写者或站长的注意,不要使用COOKIES来做为用户验证的方式,否则
你和把钥匙留给贼是同一个道理.
比如:
If trim(Request. cookies ("uname"))="fqy" and
Request.cookies("upwd") =”fqy#e3i5.com” then
……..more………
End if
我想各位站长或者是喜好写程序的朋友千万别出这类错误,真的是不可饶恕.
伪造COOKIES 都多少年了,你还用这样的就不能怪别人跑你的密码.涉及到用户
密码或者是用户登陆时,你最好使用session 它才是最安全的.如果要使用
COOKIES就在你的COOKIES上多加一个信息,SessionID,它的随机值是64位的,
要猜解它,不可能.例:
if not (rs.BOF or rs.eof) then
login="true"
Session("username"&sessionID) = Username
Session("password"& sessionID) = Password
‘Response.cookies(“username”)= Username
‘Response.cookies(“Password”)= Password
下面我们来谈谈如何防范远程注入攻击,一般的攻击都是将单表提交文件拖
到本地,将Form ACTION=”chk.asp” 指向你服务器中处理数据的文件即可.如
果你全部的数据过滤都在单表页上,那么恭喜你,你将已经被脚本攻击了.
怎么才能制止这样的远程攻击?好办,请看代码如下: 程序体(9)
<%
server_v1=Cstr(Request.ServerVariables("HTTP_REFERER"))
server_v2=Cstr(Request.ServerVariables("SERVER_NAME"))
if mid(server_v1,8,len(server_v2))<>server_v2 then
========================================第13页========================================
response.write "<br><br><center>"
response.write " "
response.write "你提交的路径有误,禁止从站点外部提交数据请
不要乱改参数!"
response.write "
"
response.end
end if
%>
‘个人感觉上面的代码过滤不是很好,有一些外部提交竟然还能堂堂正
正的进来,于是再写一个.
‘这个是过滤效果很好,建议使用.
if
instr(request.servervariables("http_referer"),"http://"&request.serve
rvariables("host") )<1 then response.write "处理 URL 时服务器上出错。
如果您是在用任何手段攻击服务器,那你应该庆幸,你的所有操作已经被服
务器记录,我们会第一时间通知公安局与国家安全部门来调查你的IP. "
response.end
end if
程序体(9)
本以为这样就万事大吉了,在表格页上加一些限制,比如maxlength啦,等
等..但天公就是那么不作美,你越怕什么他越来什么.你别忘了,攻击者可以突破
sql注入攻击时输入框长度的限制.写一个SOCKET程序改变HTTP_REFERER?我不
会。网上发表了这样一篇文章:
------------len.reg-----------------
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Microsoft\Internet
Explorer\MenuExt\扩展(&E)]
@="C:\Documents and Settings\Administrator\桌面\len.htm"
"contexts"=dword:00000004
-----------end----------------------
-----------len.htm------------------
----------end-----------------------
========================================第14页========================================
用法:先把len.reg导入注册表(注意文件路径)
然后把len.htm拷到注册表中指定的地方.
打开网页,光标放在要改变长度的输入框上点右键,看多了一个叫扩展的选
项了吧
单击搞定! 后记:同样的也就可以对付那些限制输入内容的脚本了.
怎么办?我们的限制被饶过了,所有的努力都白费了?不,举起你de键盘,
说不。让我们继续回到脚本字符的过滤吧,他们所进行的注入无非就是进行脚本
攻击。我们把所有的精力全都用到ACTION以后的页面吧,在chk.asp页中,我
们将非法的字符全部过滤掉,结果如何?我们只在前面虚晃一枪,叫他们去改注
册表吧,当他们改完才会发现,他们所做的都是那么的徒劳。
8、ASP木马
已经讲到这里了,再提醒各位论坛站长一句,小心你们的文件上传:为什么
论坛程序被攻破后主机也随之被攻击者占据。原因就在……对!ASP木马!一个
绝对可恶的东西。病毒么?非也.把个文件随便放到你论坛的程序中,您老找去
吧。不吐血才怪哦。如何才能防止ASP木马被上传到服务器呢?方法很简单,如
果你的论坛支持文件上传,请设定好你要上传的文件格式,我不赞成使用可更改
的文件格式,直接从程序上锁定,只有图象文件格式,和压缩文件就完全可以,
多给自己留点方便也就多给攻击者留点方便。怎么判断格式,我这里收集了一个,
也改出了一个,大家可以看一下:
程序体(10)
’判断文件类型是否合格
Private Function CheckFileExt (fileEXT)
dim Forumupload
Forumupload="gif,jpg,bmp,jpeg"
Forumupload=split(Forumupload,",")
for i=0 to ubound(Forumupload)
if lcase(fileEXT)=lcase(trim(Forumupload(i))) then
CheckFileExt=true
exit Function
else
CheckFileExt=false
end if
next
End Function
‘验证文件内容的合法性
========================================第15页========================================
set MyFile = server.CreateObject ("Scripting.FileSystemObject")
set MyText = MyFile.OpenTextFile (sFile, 1) ’ 读取文本文件
sTextAll = lcase(MyText.ReadAll): MyText.close
’判断用户文件中的危险操作
sStr
="8 .getfolder .createfolder .deletefolder .createdirectory
.deletedirectory"
sStr = sStr & " .saveas wscript.shell script.encode"
sNoString = split(sStr," ")
for i = 1 to sNoString(0)
if instr(sTextAll, sNoString(i)) <> 0 then
sFile = Upl.Path & sFileSave: fs.DeleteFile sFile
Response.write "<center><br><big>"& sFileSave &"文件中
含有与操作目录等有关的命令"&_
"<br><font color=red>"& mid(sNoString(i),2) &"</font>,
为了安全原因,<b>不能上传。<b>"&_"</big></center></html
>"
Response.end
end if
next
把他们加到你的上传程序里做一次验证,那么你的上传程序安全性将会大大
提高.
还不放心?拿出杀手锏,请你的虚拟主机服务商来帮忙吧。登陆到服务器,
将PROG ID 中的"shell.application"项和"shell.application.1"项改名或删
除。再将”WSCRIPT.SHELL”项和”WSCRIPT.SHELL.1”这两项都要改名或删除。
ASP
中获取地址栏字符函数
Function GetLocationURL()
Dim Url
Dim ServerPort,ServerName,ScriptName,QueryString
ServerName = Request.ServerVariables("SERVER_NAME")
ServerPort = Request.ServerVariables("SERVER_PORT")
ScriptName = Request.ServerVariables("SCRIPT_NAME")
========================================第16页========================================
QueryString = Request.ServerVariables("QUERY_STRING")
Url="
http://
"&ServerName
If ServerPort <> "80" Then Url = Url & ":" & ServerPort
Url=Url&ScriptName
If QueryString <>"" Then Url=Url&"?"& QueryString
GetLocationURL=Url
End Function
Response.Write GetLocationURL()
禁止让别人对自己用
p2pover
如果是
Vista
系统,开始,输入:
“cmd”
步骤①,查找所属网络连接。方法如下:
在命令提示符下面直接输入:
netsh i i show in
会出来以下内容:
C:\Users\GaoYx>netsh i i show in
Idx Met MTU
状态
名称
--- --- ----- ----------- -------------------
1 50 4294967295 connected Loopback Pseudo-Interface 1
8 25 1500 disconnected
无线网络连接
9 20 1500 connected
本地连接
如果你用的是有线网络,就是
9
(无线网络就是
8
,这里以有线网络为例)。
步骤②,查找网关的
IP
地址和
MAC
地址。方法如下:
========================================第17页========================================
在命令提示符下面直接输入:
arp -a
会出来以下内容:
C:\Users\GaoYx>arp -a
接口
: 192.168.0.111 --- 0x9
Internet
地址
物理地址
类型
192.168.0.1 00-0f-3d-1d-e5-99
动态
其中,
192.168.0.1
是机器的网关(当然该网关有可能是
192.168.1.1
或者其他,这里以
192.168.0.1
为例)
其中,
00-0f-3d-1d-e5-99
是网关的
MAC
地址。
步骤③,绑定网关的
IP
地址和
MAC
地址。方法如下:
新建记事本文件,内容为:
netsh -c "i i" add neighbors 9 "192.168.0.1" "00-0f-3d-1d-e5-99"
保存为
.bat
文件。文件名可以任意取,如:
Vista.bat
然后右键,以管理员身份运行。
说明:这里
9
,是指步骤①中的本地连接;
192.168.0.1
是指网关的
IP
地址;
00-0f-3d-1d-e5-99
是指网关的
MAC
地址。
步骤④,验证是否已经绑定成功。
在命令提示符下面直接输入:
arp -a
会出来以下内容:
C:\Users\GaoYx>arp -a
接口
: 192.168.0.111 --- 0x9
Internet
地址
物理地址
类型
192.168.0.1 00-0f-3d-1d-e5-99
静态
========================================第18页========================================
从刚才的动态,到现在的静态,表明已经绑定成功。这样,别人用
p2pover
就不能对你产生
作用。
如果你的机子是
XP
,方法如下:
步骤①,查找网关的
IP
地址和
MAC
地址。方法如下:
在命令提示符下面直接输入:
arp -a
会出来以下内容:
C:\Users\GaoYx>arp -a
接口
: 192.168.0.111 --- 0x9
Internet
地址
物理地址
类型
192.168.0.1 00-0f-3d-1d-e5-99
动态
其中,
192.168.0.1
是机器的网关(当然该网关有可能是
192.168.1.1
或者其他,这里以
192.168.0.1
为例)
其中,
00-0f-3d-1d-e5-99
是网关的
MAC
地址。
步骤②,绑定网关的
IP
地址和
MAC
地址。方法如下:
新建记事本文件,内容为:
arp -s 192.168.0.1 00-0f-3d-1d-e5-99
保存为
.bat
文件。文件名可以任意取,如:
XP.bat
然后双击运行。
说明:这里
192.168.0.1
是指网关的
IP
地址;
00-0f-3d-1d-e5-99
是指网关的
MAC
地址。
========================================第19页========================================
P2Pover
类软件的分析与解决
p2pover是一个在局域网中用来限制其他用户上网流量以及自动限制p2p下载软
件的工具,这款软件本来是用于商业公司内部的,但是被一些人破解以后在网上
流传,便变成了恶意限制他人的工具了.
p2pover的原理无非是ARP嗅探和ARP欺骗
ARP(Address Resolution Protocol)是地址解析协议,是一种将IP地址转化成
物理地址的协议.从IP地址到物理地址的映射有两种方式:表格方式和非表格方
式.ARP具体说来就是将网络层(IP层,也就是相当于OSI的第三层)地址解析为
数据连接层(MAC层,也就是相当于OSI的第二层)的MAC地址.
在网络中当A向B通信时,首先会查询本地的ARP缓存表,找到B的IP地址对应
的MAC地址后,就会进行数据传输.如果没有找到,A会向B发送一个则ARP请求
报文,此报文中会有A的IP地址,MAC地址以及B的IP地址等,请求B回应它本
机的IP地址和MAC地址,网络上的所有主机都会收到此报文,但是只有B能够识
别自己的IP,因此只有B才会向回应A,同理回应中也会包括B的IP地址,MAC地
址,以及A的IP地址和MAC地址等.A接收到B的应答后,就会更新本地的ARP缓
存,接着使用这个MAC地址发送数据.所谓的ARP地址解析协议实际上是,当计算
机接受到APR应答的数据包之后,其会将此数据包中的IP和MAC存储在本地的
ARP缓存中.
那么局域网中是怎么实现限制别人上网的呢,或者干脆使别人断网.
假设A是网络中的路由,当B回应A的ARP应答时,如果B回应的数据包中的IP
是C的,MAC地址是一个伪造的,由于网络中流通是按照MAC地址来进行传输的,
所以A就会更新它本地的ARP缓存表,而这个缓存表中C的MAC地址是伪造的,
也就是使C的网络不通了.
建议解决方法:
第一,就是修改自己本机的MAC地址了,不过这个方法自己觉的不是很好,在"开
始"--"运行"--输入
regedit,HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Class\
{4D36E972-E325-11CE-BFC1-08002BE103 18}子键,在子键下的0000,0001,0002
等分支中查找DriverDesc(如果你有一块以上的网卡,就有0001,0002......在
这里保存了有关你的网卡的信息),假设你的网卡在0000子键,在0000子键下添
加一个字符串,命名为"NetworkAddress",键值为修改后的MAC地址,要求为连续
的12个16进制数,然后在"0000"子键下的NDI\params中新建一项名为
NetworkAddress的子键,在该子键下添加名为"default"的字符串,键值为修改
后的MAC地址,在NetworkAddress的子键下继续建立名为"ParamDesc"的字符串,
其作用为指定Network Address的描述,其值可为"MAC Address",这样以后打开
网络邻居的"属性",双击相应的网卡就会发现有一个"高级"设置,其下存在MAC
========================================第20页========================================
Address的选项,它就是你在注册表中加入的新项"NetworkAddress",以后只要
在此修改MAC地址就可以了.关闭注册表,重新启动,你的网卡地址已经改变.打
开网络邻居的属性,双击相应网卡项会发现有一个MAC Address的高级设置项,
用于直接修改MAC地址.
第二,p2pover这种软件都是发给你一个伪造的网关的MAC地址,使你无法上网的,
所以我们可以绑定本机IP和MAC地址,以及网关的IP和MAC
"开始"--"运行"--cmd
先ping一下你的网关,然后用arp -a命令,会出现你局域网的网关的MAC,然后
用"arp -s 网关ip 网关mac",来绑定,如果ip后面的状态是"static",说明绑定
成功,这样在你被封的时候就可以用这两条命令解封了,你也可以做成一个批处
理文件,新建记事本,把 arp -s 网关ip 网关mac 写入,保存为.bat结尾的文件.
另外绑定之前可用arp -d 删除一下以前的绑定,如果想取消绑定也可以用这个
命令.
第三,我们可以利用一些网络上的反p2p软件,典型的有网络剪刀手,和arp防火
墙,这里就不提供下载了,如果需要的话就在google上搜吧,多的很.
第四,我们要找到对方是谁在搞鬼,可以利用Arpkiller的"Sniffer杀手",扫描
整个局域网IP段,然后查找处在"混杂"模式下的计算机,就可以发现对方了.运
行Arpkiller,点击"Sniffer监测工具",出现的"Sniffer杀手"窗口中输入检测
的起始和终止IP,单击"开始检测".如果相应的IP是绿帽子图标,说明这个IP处
于正常模式,如果是红帽子则说明该网卡处于混杂模式.那么它就是搞鬼的人,用
网络剪刀手把它KA了.然后再用你的p2pover来控制它,当然这种做法不推荐了
(p2pover是那个在先,哪个就有控制权)或者可以装一个Anti ARP Sniffer防火
墙.
第五,linux环境下:
需要用
#ifconfig eth0 down
先把网卡禁用
再用ifconfig eth0 hw ether 1234567890ab
这样就可以改成功了
要想永久改就这样
在/etc/rc.d/rc.local里加上这三句(也可以在/etc/init.d/network里加下面
三行)
ifconfig eth0 down
ifconfig eth0 hw ether 1234567890ab
ifconfig eth0 up
第六,还有一种防止限制流量的方法,把默认设置子网掩码255.255.255.0改成
255.240.0.0,还可以上网,P2POVER就没法限制了.
========================================第21页========================================
CSS
图片的垂直居中
CSS代码
1.
ul{
list
list
list
list-
--
-style
style
style
style-
--
-type
type
type
type
:
none
;
padding
padding
padding
padding
:0;
margin
margin
margin
margin
:0
auto
;
width
width
width
width
:
602px
;
background
background
background
background-
--
-color
color
color
color
:
#CDCDCD
;
border
border
border
border
:
#000000
1px
solid
;
overf
overf
overf
overflow
low
low
low
:
hidden
;
position
position
position
position
:
relative
}
2.
li{
list
list
list
list-
--
-style
style
style
style-
--
-type
type
type
type
:
none
;
width
width
width
width
:
200px
;
float
float
float
float
:
left
;
padding
padding
padding
padding
:0 0
30px
0;
margin
margin
margin
margin
:0;
vertical
vertical
vertical
vertical-
--
-align
align
align
align
:
middle
;
position
position
position
position
:
relative
;
display
display
display
display
:
inline
;
font
font
font
font
:
150px
/
normal
"Times new roman"
; *
padding
padding
padding
padding
:0;*
font
font
font
font-
--
-size
size
size
size
:
180px
;
text
text
text
text-
--
-align
align
align
align
:
center
}
3.
li img
{
vertical
vertical
vertical
vertical-
--
-align
align
align
align
:
middle
;
background
background
background
background
:
#fff
;
font
font
font
font-
--
-size
size
size
size
:
12px
;
padding
padding
padding
padding
:
2px
;
border
border
border
border
:
solid
1px
#555
;}
4.
li a:hover{
text
text
text
text-
--
-indent
indent
indent
indent
:0;
/*IE6 使用的 :hover*/
}
5.
li a:hover img{
padding
padding
padding
padding
:
1px
;
border
border
border
border
:
solid
2px
#336699
;}
6.
li strong{
display
display
display
display
:
block
;
font
font
font
font
:
12px
/150%
Arial
;
position
position
position
position
:
absolute
;
bottom
bottom
bottom
bottom
bottom
:0;
left
:0;
width
width
width
width
:100%; }
7.
li strong a{
display
display
display
display
:
block
;
padding
padding
padding
padding
:
8px
4px
;
color
color
color
color
:
#336699
;
text
text
text
text-
--
-decorati
decorati
decorati
decoration
on
on
on
:
none
;}
XML/HTML代码
1.
<
<<
<
ul
ul
ul
ul
>
>>
>
2.
<
<<
<
li
li
li
li
>
>>
>
3.
<
<<
<
a
aa
a
href
=
""><
><
><
><
img
img
img
img
src
=
"http://farm1.static.flickr.com/182/424905397_d0ab1d8eea_m.
jpg"
height
=
"20"
alt
=
""
/></
/></
/></
/></
a
aa
a
>
>>
>
4.
<
<<
<
strong
strong
strong
strong
><
><
><
><
a
aa
a
href
=
"">
>>
>
图文垂直居中,图文垂直居中,图文垂直
居中,图文垂直居中,
</
</
</
</
a
aa
a
></
></
></
></
strong
strong
strong
strong
>
>>
>
5.
</
</
</
</
li
li
li
li
>
>>
>
6.
<
<<
<
l
ll
li
ii
i
>
>>
>
7.
<
<<
<
a
aa
a
href
=
""><
><
><
><
img
img
img
img
src
=
"http://farm1.static.flickr.com/182/424905397_d0ab1d8eea_m.
jpg"
height
=
"40"
alt
=
""
/></
/></
/></
/></
a
aa
a
>
>>
>
8.
<
<<
<
strong
strong
strong
strong
><
><
><
><
a
aa
a
href
=
"">
>>
>
开发的上课了
</
</
</
</
a
aa
a
></
></
></
></
strong
strong
strong
strong
>
>>
>
9.
</
</
</
</
li
li
li
li
>
>>
>
10.
<
<<
<
li
li
li
li
>
>>
>
11.
<
<<
<
a
aa
a
href
=
""><
><
><
><
img
img
img
img
src
=
"http://farm1.static.flickr.com/182/424905397_d0ab1d8eea_m.
jpg"
height
=
"60"
alt
=
""
/></
/></
/></
/></
a
aa
a
>
>>
>
12.
<
<<
<
strong
strong
strong
strong
><
><
><
><
a
aa
a
href
=
"">
>>
>
开发的上课了
</
</
</
</
a
aa
a
></
></
></
></
strong
strong
strong
strong
>
>>
>
13.
</
</
</
</
li
li
li
li
>
>>
>
========================================第22页========================================
14.
<
<<
<
li
li
li
li
>
>>
>
15.
<
<<
<
a
aa
a
href
=
""><
><
><
><
img
img
img
img
src
=
"http://farm1.static.flickr.com/182/424905397_d0ab1d8eea_m.
jpg"
height
=
"80"
alt
=
""
/><
/><
/><
/></
//
/
a
aa
a
>
>>
>
16.
<
<<
<
strong
strong
strong
strong
><
><
><
><
a
aa
a
href
=
"">
>>
>
开发的上课了
</
</
</
</
a
aa
a
></
></
></
></
strong
strong
strong
strong
>
>>
>
17.
</
</
</
</
li
li
li
li
>
>>
>
18.
<
<<
<
li
li
li
li
>
>>
>
19.
<
<<
<
a
aa
a
href
=
""><
><
><
><
img
img
img
img
src
=
"http://farm1.static.flickr.com/182/424905397_d0ab1d8eea_m.
jpg"
height
=
"20"
alt
=
""
/></
/></
/></
/></
a
aa
a
>
>>
>
20.
<
<<
<
strong
strong
strong
strong
><
><
><
><
a
aa
a
href
=
"">
>>
>
开发的上课了
</
</
</
</
a
aa
a
></
></
></
></
strong
strong
strong
strong
>
>>
>
21.
</
</
</
</
li
li
li
li
>
>>
>
22.
<
<<
<
li
li
li
li
>
>>
>
23.
<
<<
<
a
aa
a
href
=
""><
><
><
><
img
img
img
img
src
=
"http://farm1.static.flickr.com/182/424905397_d0ab1d8eea_m.
jpg"
height
=
"40"
alt
=
""
/></
/></
/></
/></
a
aa
a
>
>>
>
24.
<
<<
<
strong
strong
strong
strong
><
><
><
><
a
aa
a
href
=
"">
>>
>
开发的上课了
</
</
</
</
a
aa
a
></
></
></
></
strong
strong
strong
strong
>
>>
>
25.
</
</
</
</
li
li
li
li
>
>>
>
26.
</
</
</
</
ul
ul
ul
ul
>
>>
>
什么是
DOCTYPE
DOCTYPE
是
是是
是
document type(
文档类型
文档类型
文档类型
文档类型
)
的简写
的简写
的简写
的简写,
,,
,用来说明你
用来说明你
用来说明你
用来说明你
用的
用的
用的
用的
XHTML
或者
或者
或者
或者
HTML
是什么版本
是什么版本
是什么版本
是什么版本。
。。
。
其中的
DTD(
例如上例中的
xhtml1-transitional.dtd)
叫文档类型定义,里面包含了文档的规则,
浏览器就根据你定义的
DTD
来解释你页面的标识,并展现出来。
要建立符合标准的网页,
DOCTYPE
声明是必不可少的关键组成部分;除非你的
XHTML
确
定了一个正确的
DOCTYPE
,否则你的标识和
CSS
都不会生效。
XHTML 1.0
提供了三种
DTD
声明可供选择:
过渡的
(Transitional):
要求非常宽松的
DTD
,它允许你继续使用
HTML4.01
的标识
(
但是要符
合
xhtml
的写法
)
。完整代码如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd
">
严格的
(Strict):
要求严格的
DTD
,你不能使用任何表现层的标识和属性,例如
<br>
。完整代
码如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
========================================第23页========================================
"
http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd
">
框架的
(Frameset):
专门针对框架页面设计使用的
DTD
,如果你的页面中包含有框架,需要采
用这种
DTD
。完整代码如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
"
http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd
">
我们选择什么样的
DOCTYPE
理想情况当然是严格的
DTD
,但对于我们大多数刚接触
web
标准的设计师来说,过渡的
DTD(XHTML 1.0 Transitional)
是目前理想选择
(
包括本站,使用的也是过渡型
DTD)
。因为这
种
DTD
还允许我们使用表现层的标识、元素和属性,也比较容易通过
W3C
的代码校验。
注:上面说的
"
表现层的标识、属性
"
是指那些纯粹用来控制表现的
tag
,例如用于排版的表
格、背景颜色标识等。在
XHTML
中标识是用来表示结构的,而不是用来实现表现形式,
我们过渡的目的是最终实现数据和表现相分离。
打个比方:人体模特换衣服。模特就好比数据,衣服则是表现形式,模特和衣服是分离的,
这样你就可以随意换衣服。而原来
HTML4
中,数据和表现是混杂在一起的,要一次性换个
表现形式非常困难。呵呵,有点抽象了,这个概念需要我们在应用过程中逐步领会。
补充
DOCTYPE
声明必须放在每一个
XHTML
文档最顶部,在所有代码和标识之上。
C#
中
StringBuilder
类的使用
String
对象是不可改变的。每次使用
System.String
类中的方法之一时,都要在内存中创建
一个新的字符串对象,这就需要为该新对象分配新的空间。在需要对字符串执行重复修改的
情况下,与创建新的
String
对象相关的系统开销可能会非常昂贵。如果要修改字符串而不
创建新的对象,则可以使用
System.Text.StringBuilder
类。例如,当在一个循环中将许多字
符串连接在一起时,使用
StringBuilder
类可以提升性能。
通过用一个重载的构造函数方法初始化变量,可以创建
StringBuilder
类的新实例,正
如以下示例中所阐释的那样。
StringBuilder MyStringBuilder = new StringBuilder("Hello World!");
(
一
)
设置容量和长度
虽然
StringBuilder
对象是动态对象,允许扩充它所封装的字符串中字符的数量,但是
您可以为它可容纳的最大字符数指定一个值。此值称为该对象的容量,不应将它与当前
StringBuilder
对象容纳的字符串长度混淆在一起。例如,可以创建
StringBuilder
类的带有
字符串
“Hello”
(长度为
5
)的一个新实例,同时可以指定该对象的最大容量为
25
。当修改
StringBuilder
时,在达到容量之前,它不会为其自己重新分配空间。当达到容量时,将自动
分配新的空间且容量翻倍。可以使用重载的构造函数之一来指定
StringBuilder
类的容量。
========================================第24页========================================
以下代码示例指定可以将
MyStringBuilder
对象扩充到最大
25
个空白。
StringBuilder MyStringBuilder = new StringBuilder("Hello World!", 25);
另外,可以使用读
/
写
Capacity
属性来设置对象的最大长度。以下代码示例使用
Capacity
属
性来定义对象的最大长度。
MyStringBuilder.Capacity = 25;
(
二
)
下面列出了此类的几个常用方法:
(1)Append
方法可用来将文本或对象的字符串表示形式添加到由当前
StringBuilder
对象表
示的字符串的结尾处。以下示例将一个
StringBuilder
对象初始化为
“Hello World”
,然后将
一些文本追加到该对象的结尾处。将根据需要自动分配空间。
StringBuilder MyStringBuilder = new StringBuilder("Hello World!");
MyStringBuilder.Append(" What a beautiful day.");
Console.WriteLine(MyStringBuilder);
此示例将
Hello World! What a beautiful day.
显示到控制台。
(2)AppendFormat
方法将文本添加到
StringBuilder
的结尾处,而且实现了
IFormattable
接
口,因此可接受格式化部分中描述的标准格式字符串。可以使用此方法来自定义变量的格式
并将这些值追加到
StringBuilder
的后面。以下示例使用
AppendFormat
方法将一个设置为
货币值格式的整数值放置到
StringBuilder
的结尾。
int MyInt = 25;
StringBuilder MyStringBuilder = new StringBuilder("Your total is ");
MyStringBuilder.AppendFormat("{0:C} ", MyInt);
Console.WriteLine(MyStringBuilder);
此示例将
Your total is $25.00
显示到控制台。
(3)Insert
方法将字符串或对象添加到当前
StringBuilder
中的指定位置。以下示例使用此方
法将一个单词插入到
StringBuilder
的第六个位置。
StringBuilder MyStringBuilder = new StringBuilder("Hello World!");
MyStringBuilder.Insert(6,"Beautiful ");
Console.WriteLine(MyStringBuilder);
此示例将
Hello Beautiful World!
显示到控制台。
(4)
可以使用
Remove
方法从当前
StringBuilder
中移除指定数量的字符,移除过程从指定的
从零开始的索引处开始。以下示例使用
Remove
方法缩短
StringBuilder
。
StringBuilder MyStringBuilder = new StringBuilder("Hello World!");
MyStringBuilder.Remove(5,7);
Console.WriteLine(MyStringBuilder);
此示例将
Hello
显示到控制台。
(5)
使用
Replace
方法,可以用另一个指定的字符来替换
StringBuilder
对象内的字符。以下
示例使用
Replace
方法来搜索
StringBuilder
对象,查找所有的感叹号字符
(!)
,并用问号
字符
(?)
来替换它们。
StringBuilder MyStringBuilder = new StringBuilder("Hello World!");
MyStringBuilder.Replace('!', '?');
========================================第25页========================================
Console.WriteLine(MyStringBuilder);
此示例将
Hello World?
显示到控制台
利用模板生成
ASP.NET
静态网页
OS:Windows Server 2003 中文版
ASP.Net生成静态HTML页
在Asp中实现的生成静态页用到的FileSystemObject对象!
在.Net中涉及此类操作的是System.IO
以下是程序代码 注:此代码非原创!参考别人代码
Code:
//生成HTML页
public
static
bool
WriteFile(
string
strText,
string
strContent,
string
strAuthor)
{
string
path = HttpContext.Current.Server.MapPath("/news/");
Encoding code = Encoding.GetEncoding("gb2312");
// 读取模板文件
string
temp = HttpContext.Current.Server.MapPath("/news/text.html");
StreamReader sr=
null
;
StreamWriter sw=
null
;
string
str="";
try
{
sr =
new
StreamReader(temp, code);
str = sr.ReadToEnd();
// 读取文件
}
catch
(Exception exp)
{
HttpContext.Current.Response.Write(exp.Message);
HttpContext.Current.Response.End();
sr.Close();
}
此函数放在Conn.CS基类中了
在添加新闻的代码中引用 注:工程名为Hover
========================================第26页========================================
if
(Hover.Conn.WriteFilethis.Title.Text.ToString),
this
.Content.Text.To
String),
this
.Author.Text.ToString)))
{
Response.Write("添加成功");
}
else
{
Response.Write("生成HTML出错!");
}
模板页Text.html代码
Code:
<!
DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
>
<
HTML
>
<
HEAD
>
<
title
>
ShowArticle
</
title
>
<
body
>
biaoti
<
br
>
content
<
br
>
author
</
body
>
</
HTML
>
biaoti
<
br
>
content
<
br
>
author
</
body
>
</
HTML
>
<script type="text/javascript"><!--
google_ad_client = "pub-7908659590633539";
google_ad_width = 728;
google_ad_height = 90;
google_ad_format = "728x90_as";
google_ad_type = "text_image";
google_ad_channel ="";
google_color_border = "4C4C4C";
google_color_link = "E1771E";
google_color_bg = "E6E6E6";
google_color_text = "3D81EE";
google_color_url = "CC0000";
//--></script>
========================================第27页========================================
<script type="text/javascript"
src="
http://pagead2.googlesyndication.com/pagead/show_ads.js
">
</script>
牢记!
SQL Server
数据库开发的二十一条军规
如果你正在负责一个基于
SQL Server
的项目,或者你刚刚接触
SQL Server
,你都有可能要
面临一些数据库性能的问题,这篇文章会为你提供一些有用的指导(其中大多数也可以用于
其它的
DBMS
)。
在这里,我不打算介绍使用
SQL Server
的窍门,也不能提供一个包治百病的方案,我所做
的是总结一些经验
----
关于如何形成一个好的设计。这些经验来自我过去几年中经受的教训,
一直来,我看到许多同样的设计错误被一次又一次的重复。
一、了解你用的工具
不要轻视这一点,这是我在这篇文章中讲述的最关键的一条。也许你也看到有很多的
SQL
Server
程序员没有掌握全部的
T-SQL
命令和
SQL Server
提供的那些有用的工具。
“
什么?我要浪费一个月的时间来学习那些我永远也不会用到的
SQL
命令???
”
,你也许
会这样说。对的,你不需要这样做。但是你应该用一个周末浏览所有的
T-SQL
命令。在这
里,你的任务是了解,将来,当你设计一个查询时,你会记起来:
“
对了,这里有一个命令
可以完全实现我需要的功能
”
,于是,到
MSDN
查看这个命令的确切语法。
二、不要使用游标
让我再重复一遍:不要使用游标。如果你想破坏整个系统的性能的话,它们倒是你最有效的
首选办法。大多数的初学者都使用游标,而没有意识到它们对性能造成的影响。它们占用内
存,还用它们那些不可思议的方式锁定表,另外,它们简直就像蜗牛。而最糟糕的是,它们
可以使你的
DBA
所能做的一切性能优化等于没做。不知你是否知道每执行一次
FETCH
就
等于执行一次
SELECT
命令?这意味着如果你的游标有
10000
条记录,它将执行
10000
次
SELECT
!如果你使用一组
SELECT
、
UPDATE
或者
DELETE
来完成相应的工作,那将有效
率的多。
初学者一般认为使用游标是一种比较熟悉和舒适的编程方式,可很不幸,这会导致糟糕的性
能。显然,
SQL
的总体目的是你要实现什么,而不是怎样实现。
我曾经用
T-SQL
重写了一个基于游标的存储过程,那个表只有
100,000
条记录,原来的存储
过程用了
40
分钟才执行完毕,而新的存储过程只用了
10
秒钟。在这里,我想你应该可以看
到一个不称职的程序员究竟在干了什么!!!
我们可以写一个小程序来取得和处理数据并且更新数据库,这样做有时会更有效。记住:对
于循环,
T-SQL
无能为力。
我再重新提醒一下:使用游标没有好处。除了
DBA
的工作外,我从来没有看到过使用游标
可以有效的完成任何工作。
三、规范化你的数据表
为什么不规范化数据库?大概有两个借口:出于性能的考虑和纯粹因为懒惰。至于第二点,
你迟早得为此付出代价。而关于性能的问题,你不需要优化根本就不慢的东西。我经常看到
一些程序员
“
反规范化
”
数据库,他们的理由是
“
原来的设计太慢了
”
,可结果却常常是他们让
系统更慢了。
DBMS
被设计用来处理规范数据库的,因此,记住:按照规范化的要求设计
数据库。
========================================第28页========================================
四、不要使用
SELECT *
这点不太容易做到,我太了解了,因为我自己就经常这样干。可是,如果在
SELECT
中指
定你所需要的列,那将会带来以下的好处:
1
减少内存耗费和网络的带宽
2
你可以得到更安全的设计
3
给查询优化器机会从索引读取所有需要的列
五、了解你将要对数据进行的操作
为你的数据库创建一个健壮的索引,那可是功德一件。可要做到这一点简直就是一门艺术。
每当你为一个表添加一个索引,
SELECT
会更快了,可
INSERT
和
DELETE
却大大的变慢
了,因为创建了维护索引需要许多额外的工作。显然,这里问题的关键是:你要对这张表进
行什么样的操作。这个问题不太好把握,特别是涉及
DELETE
和
UPDATE
时,因为这些语
句经常在
WHERE
部分包含
SELECT
命令。
六、不要给
“
性别
”
列创建索引
首先,我们必须了解索引是如何加速对表的访问的。你可以将索引理解为基于一定的标准上
对表进行划分的一种方式。如果你给类似于
“
性别
”
这样的列创建了一个索引,你仅仅是将表
划分为两部分:男和女。你在处理一个有
1,000,000
条记录的表,这样的划分有什么意义?
记住:维护索引是比较费时的。当你设计索引时,请遵循这样的规则:根据列可能包含不同
内容的数目从多到少排列,比如:姓名
+
省份
+
性别。
七、使用事务
请使用事务,特别是当查询比较耗时。如果系统出现问题,这样做会救你一命的。一般有些
经验的程序员都有体会
-----
你经常会碰到一些不可预料的情况会导致存储过程崩溃。
八、小心死锁
按照一定的次序来访问你的表。如果你先锁住表
A
,再锁住表
B
,那么在所有的存储过程中
都要按照这个顺序来锁定它们。如果你(不经意的)某个存储过程中先锁定表
B
,再锁定表
A
,这可能就会导致一个死锁。如果锁定顺序没有被预先详细的设计好,死锁是不太容易被
发现的。
九、不要打开大的数据集
一个经常被提出的问题是:我怎样才能迅速的将
100000
条记录添加到
ComboBox
中?这是
不对的,你不能也不需要这样做。很简单,你的用户要浏览
100000
条记录才能找到需要的
记录,他一定会诅咒你的。在这里,你需要的是一个更好的
UI
,你需要为你的用户显示不
超过
100
或
200
条记录。
十、不要使用服务器端游标
与服务器端游标比起来,客户端游标可以减少服务器和网络的系统开销,并且还减少锁定时
间。
十一、使用参数查询
有时,我在
CSDN
技术论坛看到类似这样的问题:
“SELECT * FROM a WHERE a.id='A'B
,
因为单引号查询发生异常,我该怎么办?
”
,而普遍的回答是:用两个单引号代替单引号。
这是错误的。这样治标不治本,因为你还会在其他一些字符上遇到这样的问题,更何况这样
会导致严重的
bug
,除此以外,这样做还会使
SQL Server
的缓冲系统无法发挥应有的作用。
使用参数查询,
釜底抽薪,这些问题统统不存在了。
十二、在程序编码时使用大数据量的数据库
程序员在开发中使用的测试数据库一般数据量都不大,可经常的是最终用户的数据量都很
大。我们通常的做法是不对的,原因很简单:现在硬盘不是很贵,可为什么性能问题却要等
到已经无可挽回的时候才被注意呢?
========================================第29页========================================
十三、不要使用
INSERT
导入大批的数据
请不要这样做,除非那是必须的。使用
UTS
或者
BCP
,这样你可以一举而兼得灵活性和速
度。
十四、注意超时问题
查询数据库时,一般数据库的缺省都比较小,比如
15
秒或者
30
秒。而有些查询运行时间要
比这长,特别是当数据库的数据量不断变大时。
十五、不要忽略同时修改同一记录的问题
有时候,两个用户会同时修改同一记录,这样,后一个修改者修改了前一个修改者的操作,
某些更新就会丢失。处理这种情况不是很难:创建一个
timestamp
字段,在写入前检查它,
如果允许,就合并修改,如果存在冲突,提示用户。
十六、在细节表中插入纪录时,不要在主表执行
SELECT MAX(ID)
这是一个普遍的错误,当两个用户在同一时间插入数据时,这会导致错误。你可以使用
SCOPE_IDENTITY
,
IDENT_CURRENT
和
IDENTITY
。如果可能,不要使用
IDENTITY
,
因为在有触发器的情况下,它会引起一些问题(详见这里的讨论)。
十七、避免将列设为
NULLable
如果可能的话,你应该避免将列设为
NULLable
。系统会为
NULLable
列的每一行分配一个
额外的字节,查询时会带来更多的系统开销。另外,将列设为
NULLable
使编码变得复杂,
因为每一次访问这些列时都必须先进行检查。
我并不是说
NULLS
是麻烦的根源,尽管有些人这样认为。我认为如果你的业务规则中允许
“
空数据
”
,那么,将列设为
NULLable
有时会发挥很好的作用,但是,如果在类似下面的情
况中使用
NULLable
,那简直就是自讨苦吃。
CustomerName1
CustomerAddress1
CustomerEmail1
CustomerName2
CustomerAddress2
CustomerEmail3
CustomerName1
CustomerAddress2
CustomerEmail3
如果出现这种情况,你需要规范化你的表了。
十八、尽量不要使用
TEXT
数据类型
除非你使用
TEXT
处理一个很大的数据,否则不要使用它。因为它不易于查询,速度慢,
用的不好还会浪费大量的空间。一般的,
VARCHAR
可以更好的处理你的数据。
十九、尽量不要使用临时表
尽量不要使用临时表,除非你必须这样做。一般使用子查询可以代替临时表。使用临时表会
带来系统开销,如果你是用
COM+
进行编程,它还会给你带来很大的麻烦,因为
COM+
使
用数据库连接池而临时表却自始至终都存在。
SQL Server
提供了一些替代方案,比如
Table
数据类型。
二十、学会分析查询
SQL Server
查询分析器是你的好伙伴,通过它你可以了解查询和索引是如何影响性能的。
二十一、使用参照完整性
定义主健、唯一性约束和外键,这样做可以节约大量的时间。
========================================第30页========================================
SQL
优化
34
条
我们要做到不但会写
SQL,
还要做到写出性能优良的
SQL,
以下为笔者学习、摘录、并汇总部
分资料与大家分享!
(
1
)
选择最有效率的表名顺序
(
只在基于规则的优化器中有效
)
:
ORACLE
的解析器按照从右到左的顺序处理
FROM
子句中的表名,
FROM
子句中写在最后
的表
(
基础表
driving table)
将被最先处理,在
FROM
子句中包含多个表的情况下
,
你必须选择
记录条数最少的表作为基础表。如果有
3
个以上的表连接查询
,
那就需要选择交叉表
(intersection table)
作为基础表
,
交叉表是指那个被其他表所引用的表
.
(
2
)
WHERE
子句中的连接顺序.:
ORACLE
采用自下而上的顺序解析
WHERE
子句
,
根据这个原理
,
表之间的连接必须写在其他
WHERE
条件之前
,
那些可以过滤掉最大数量记录的条件必须写在
WHERE
子句的末尾
.
(
3
)
SELECT
子句中避免使用
‘ * ‘
:
ORACLE
在解析的过程中
,
会将
'*'
依次转换成所有的列名
,
这个工作是通过查询数据字典
完成的
,
这意味着将耗费更多的时间
(
4
)
减少访问数据库的次数:
ORACLE
在内部执行了许多工作
:
解析
SQL
语句
,
估算索引的利用率
,
绑定变量
,
读数据
块等;
(
5
)
在
SQL*Plus , SQL*Forms
和
Pro*C
中重新设置
ARRAYSIZE
参数
,
可以增加每次数
据库访问的检索数据量
,
建议值为
200
(
6
)
使用
DECODE
函数来减少处理时间:
使用
DECODE
函数可以避免重复扫描相同记录或重复连接相同的表
.
(
7
)
整合简单
,
无关联的数据库访问:
如果你有几个简单的数据库查询语句
,
你可以把它们整合到一个查询中
(
即使它们之间没有
关系
)
(
8
)
删除重复记录:
最高效的删除重复记录方法
(
因为使用了
ROWID)
例子:
DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID)
FROM EMP X WHERE X.EMP_NO = E.EMP_NO);
(
9
)
用
TRUNCATE
替代
DELETE
:
当删除表中的记录时
,
在通常情况下
,
回滚段
(rollback segments )
用来存放可以被恢复的信
息
.
如果你没有
COMMIT
事务
,ORACLE
会将数据恢复到删除之前的状态
(
准确地说是恢复
到执行删除命令之前的状况
)
而当运用
TRUNCATE
时
,
回滚段不再存放任何可被恢复的信
息
.
当命令运行后
,
数据不能被恢复
.
因此很少的资源被调用
,
执行时间也会很短
. (
译者按
:
TRUNCATE
只在删除全表适用
,TRUNCATE
是
DDL
不是
DML)
(
10
)
尽量多使用
COMMIT
:
只要有可能
,
在程序中尽量多使用
COMMIT,
这样程序的性能得到提高
,
需求也会因为
COMMIT
所释放的资源而减少
:
COMMIT
所释放的资源
:
a.
回滚段上用于恢复数据的信息
.
b.
被程序语句获得的锁
c. redo log buffer
中的空间
d. ORACLE
为管理上述
3
种资源中的内部花费
========================================第31页========================================
(
11
)
用
Where
子句替换
HAVING
子句:
避免使用
HAVING
子句
, HAVING
只会在检索出所有记录之后才对结果集进行过滤
.
这个
处理需要排序
,
总计等操作
.
如果能通过
WHERE
子句限制记录的数目
,
那就能减少这方面的
开销
. (
非
oracle
中
)on
、
where
、
having
这三个都可以加条件的子句中,
on
是最先执行,
where
次之,
having
最后,因为
on
是先把不符合条件的记录过滤后才进行统计,它就可以减少中
间运算要处理的数据,按理说应该速度是最快的,
where
也应该比
having
快点的,因为它过
滤数据后才进行
sum
,在两个表联接时才用
on
的,所以在一个表的时候,就剩下
where
跟
having
比较了。在这单表查询统计的情况下,如果要过滤的条件没有涉及到要计算字段,那
它们的结果是一样的,只是
where
可以使用
rushmore
技术,而
having
就不能,在速度上后
者要慢如果要涉及到计算的字段,就表示在没计算之前,这个字段的值是不确定的,根据上
篇写的工作流程,
where
的作用时间是在计算之前就完成的,而
having
就是在计算后才起作
用的,所以在这种情况下,两者的结果会不同。在多表联接查询时,
on
比
where
更早起作
用。系统首先根据各个表之间的联接条件,把多个表合成一个临时表后,再由
where
进行过
滤,然后再计算,计算完后再由
having
进行过滤。由此可见,要想过滤条件起到正确的作
用,首先要明白这个条件应该在什么时候起作用,然后再决定放在那里
(
12
)
减少对表的查询:
在含有子查询的
SQL
语句中
,
要特别注意减少对表的查询
.
例子:
SELECT TAB_NAME FROM TABLES WHERE (TAB_NAME,DB_VER) = ( SELECT
TAB_NAME,DB_VER FROM TAB_COLUMNS WHERE VERSION = 604)
(
13
)
通过内部函数提高
SQL
效率
.
:
复杂的
SQL
往往牺牲了执行效率
.
能够掌握上面的运用函数解决问题的方法在实际工作中
是非常有意义的
(
14
)
使用表的别名
(Alias)
:
当在
SQL
语句中连接多个表时
,
请使用表的别名并把别名前缀于每个
Column
上
.
这样一来
,
就可以减少解析的时间并减少那些由
Column
歧义引起的语法错误
.
(
15
)
用
EXISTS
替代
IN
、用
NOT EXISTS
替代
NOT IN
:
在许多基于基础表的查询中
,
为了满足一个条件
,
往往需要对另一个表进行联接
.
在这种情况
下
,
使用
EXISTS(
或
NOT EXISTS)
通常将提高查询的效率
.
在子查询中
,NOT IN
子句将执行
一个内部的排序和合并
.
无论在哪种情况下
,NOT IN
都是最低效的
(
因为它对子查询中的表
执行了一个全表遍历
).
为了避免使用
NOT IN ,
我们可以把它改写成外连接
(Outer Joins)
或
NOT EXISTS.
例子:
(高效)
SELECT * FROM EMP (
基础表
) WHERE EMPNO > 0 AND EXISTS (SELECT ‘X'
FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = ‘MELB')
(
低效
)SELECT * FROM EMP (
基础表
) WHERE EMPNO > 0 AND DEPTNO IN(SELECT
DEPTNO FROM DEPT WHERE LOC = ‘MELB')
(
16
)
识别
'
低效执行
'
的
SQL
语句:
虽然目前各种关于
SQL
优化的图形化工具层出不穷
,
但是写出自己的
SQL
工具来解决问题始
终是一个最好的方法:
SELECT EXECUTIONS , DISK_READS, BUFFER_GETS,
ROUND((BUFFER_GETS-DISK_READS)/BUFFER_GETS,2) Hit_radio,
ROUND(DISK_READS/EXECUTIONS,2) Reads_per_run,
SQL_TEXT
FROM V$SQLAREA
========================================第32页========================================
WHERE EXECUTIONS>0
AND BUFFER_GETS > 0
AND (BUFFER_GETS-DISK_READS)/BUFFER_GETS < 0.8
ORDER BY 4 DESC;
常用正则表达式
1。^\d+$
//匹配非负整数(正整数 + 0)
2。^[0-9]*[1-9][0-9]*$
//匹配正整数
3。^((-\d+)|(0+))$
//匹配非正整数(负整数 + 0)
4。^-[0-9]*[1-9][0-9]*$
//匹配负整数
5。^-?\d+$
//匹配整数
6。^\d+(\.\d+)?$
//匹配非负浮点数(正浮点数 + 0)
7。
^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9
][0-9]*))$
//匹配正浮点数
8。^((-\d+(\.\d+)?)|(0+(\.0+)?))$
//匹配非正浮点数(负浮点数 + 0)
9。
^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1
-9][0-9]*)))$
//匹配负浮点数
10。^(-?\d+)(\.\d+)?$
//匹配浮点数
11。^[A-Za-z]+$
//匹配由26个英文字母组成的字符串
12。^[A-Z]+$
//匹配由26个英文字母的大写组成的字符串
13。^[a-z]+$
//匹配由26个英文字母的小写组成的字符串
14。^[A-Za-z0-9]+$
//匹配由数字和26个英文字母组成的字符串
15。^\w+$
//匹配由数字、26个英文字母或者下划线组成的字符串
16。^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$
//匹配email地址
17。^[a-zA-z]+:
//匹配(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$ //匹配
url
18。匹配中文字符的正则表达式: [\u4e00-\u9fa5]
19。匹配双字节字符(包括汉字在内):[^\x00-\xff]
20。应用:计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)
String.prototype.len=function(){
return
this
.replace([^\x00-\xff]/g,"aa").length;}
21。匹配空行的正则表达式:\n[\s| ]*\r
22。匹配HTML标记的正则表达式:/<(.*)>.*<\/\1>|<(.*) \/>/
23。匹配首尾空格的正则表达式:(^\s*)|(\s*$)
* 正则表达式用例
* 1、^\S+[a-z A-Z]$ 不能为空 不能有空格 只能是英文字母
* 2、\S{6,} 不能为空 六位以上
* 3、^\d+$ 不能有空格 不能非数字
========================================第33页========================================
* 4、(.*)(\.jpg|\.bmp)$ 只能是jpg和bmp格式
* 5、^\d{4}\-\d{1,2}-\d{1,2}$ 只能是2004-10-22格式
* 6、^0$ 至少选一项
* 7、^0{2,}$ 至少选两项
* 8、^[\s|\S]{20,}$ 不能为空 二十字以上
* 9、
^\+?[a-z0-9](([-+.]|[_]+)?[a-z0-9]+)*@([a-z0-9]+(\.|\-))+[a-z]{2,6}$
邮件
* 10、
\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*([,;]\s*\w+([-+.]\w+)*@\w+
([-.]\w+)*\.\w+([-.]\w+)*)* 输入多个地址用逗号或空格分隔邮件
* 11、^(\([0-9]+\))?[0-9]{7,8}$电话号码7位或8位或前面有区号例如(022)
87341628
* 12、^[a-z A-Z 0-9 _]+@[a-z A-Z 0-9 _]+(\.[a-z A-Z 0-9 _]+)+(\,[a-z A-Z
0-9 _]+@[a-z A-Z 0-9 _]+(\.[a-z A-Z 0-9
_]+)+)*$ "^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-
z0-9]+)*\.[A-Za-z0-9]+$"
* 只能是字母、数字、下划线;必须有@和.同时格式要规范 邮件
* 13 ^\w+@\w+(\.\w+)+(\,\w+@\w+(\.\w+)+)*$上面表达式也可以写成这样子,
更精练。
14 ^\w+((-\w+)|(\.\w+))*\@\w+((\.|-)\w+)*\.\w+$
固定电话的正则表达式 0\d{2,3}-\d{5,9}|0\d{2,3}-\d{5,9} 不区分区号的
(\(\d{3}\)|\d{3}-)?\d{8}
邮政编码或区号 /^\d{6}$/
最新手机号码正则表达式 ^1[3,5]{1}[0-9]{1}[0-9]{8}$
关于从客户端中检测到有潜在危险的
Request.Form
值的最优解决方
案
(
转
ASP.Net 1.1后引入了对提交表单自动检查是否存在XSS(跨站脚本攻击)的能力。
当用户试图用之类的输入影响页面返回结果的时候,ASP.Net的引擎会引发一个
HttpRequestValidationExceptioin。默认情况下会返回如下文字的页面:
以下是引用片段:
Server Error in '/YourApplicationPath' Application
A potentially dangerous Request.Form value was detected from the client
(txtName="<b>").
========================================第34页========================================
Description: Request Validation has detected a potentially dangerous
client input value, and processing of the request has been aborted. This
value may indicate an attempt to compromise the security of your
application, such as a cross-site scripting attack. You can disable
request validation by setting validateRequest=false in the Page directive
or in the configuration section. However, it is strongly recommended that
your application explicitly check all inputs in this case.
Exception Details: System.Web.HttpRequestValidationException: A
potentially dangerous Request.Form value was detected from the client
(txtName="<b>").
....
这是ASP.Net提供的一个很重要的安全特性。因为很多程序员对安全没有概
念,甚至都不知道XSS这种攻击的存在,知道主动去防护的就更少了。ASP.Net
在这一点上做到默认安全。这样让对安全不是很了解的程序员依旧可以写出有一
定安全防护能力的网站。
但是,当我Google搜索 HttpRequestValidationException 或者 "A
potentially dangerous Request.Form value was detected from the client"
的时候,惊奇的发现大部分人给出的解决方案竟然是在ASP.Net页面描述中通过
设置 validateRequest=false 来禁用这个特性,而不去关心那个程序员的网站
是否真的不需要这个特性。看得我这叫一个胆战心惊。安全意识应该时时刻刻在
每一个程序员的心里,不管你对安全的概念了解多少,一个主动的意识在脑子里,
你的站点就会安全很多。
为什么很多程序员想要禁止 validateRequest 呢?有一部分是真的需要用
户输入"<>"之类的字符。这就不必说了。还有一部分其实并不是用户允许输入那
些容易引起XSS的字符,而是讨厌这种报错的形式,毕竟一大段英文加上一个
ASP.Net典型异常错误信息,显得这个站点出错了,而不是用户输入了非法的字
符,可是自己又不知道怎么不让它报错,自己来处理报错。
对于希望很好的处理这个错误信息,而不使用默认ASP.Net异常报错信息的
程序员们,你们不要禁用validateRequest=false。
正确的做法是在你当前页面添加Page_Error()函数,来捕获所有页面处理
过程中发生的而没有处理的异常。然后给用户一个合法的报错信息。如果当前页
面没有Page_Error(),这个异常将会送到Global.asax的Application_Error()
来处理,你也可以在那里写通用的异常报错处理函数。如果两个地方都没有写异
常处理函数,才会显示这个默认的报错页面呢。
举例而言,处理这个异常其实只需要很简短的一小段代码就够了。在页面的
Code-behind页面中加入这么一段代码:
========================================第35页========================================
以下是引用片段:
protected void Page_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
if (ex is HttpRequestValidationException)
{
Response.Write("请您输入合法字符串。");
Server.ClearError(); // 如果不ClearError()这个异常会继续传到
Application_Error()。
}
}
这样这个程序就可以截获 HttpRequestValidationException 异常,而且可
以按照程序员的意愿返回一个合理的报错信息。
这段代码很简单,所以我希望所有不是真的要允许用户输入之类字符的朋
友,千万不要随意的禁止这个安全特性,如果只是需要异常处理,那么请用类似
于上面的代码来处理即可。
而对于那些通过 明确禁止了这个特性的程序员,自己一定要明白自己在做
什么,而且一定要自己手动的检查必须过滤的字符串,否则你的站点很容易引发
跨站脚本攻击。
关于存在Rich Text Editor的页面应该如何处理?
如果页面有富文本编辑器的控件的,那么必然会导致有类的HTML标签提交
回来。在这种情况下,我们不得不将validateRequest="false"。那么安全性怎
么处理?如何在这种情况下最大限度的预防跨站脚本攻击呢?
根据微软的建议,我们应该采取安全上称为“默认禁止,显式允许”的策略。
首先,我们将输入字符串用 HttpUtility.HtmlEncode()来编码,将其中的
HTML标签彻底禁止。
然后,我们再对我们所感兴趣的、并且是安全标签,通过Replace()进行替
换。比如,我们希望有""标签,那么我们就将""显式的替换回""。
示例代码如下:
以下是引用片段:
void submitBtn_Click(object sender, EventArgs e)
...{
// 将输入字符串编码,这样所有的HTML标签都失效了。
StringBuilder sb = new StringBuilder(
HttpUtility.HtmlEncode(htmlInputTxt.Text)
========================================第36页========================================
);
// 然后我们选择性的允许<b> 和 <i>
sb.Replace("<b>", "<b>");
sb.Replace("</b>", "");
sb.Replace("<i>", "<i>");
sb.Replace("</i>", "");
Response.Write(sb.ToString());
}
这样我们即允许了部分HTML标签,又禁止了危险的标签。
根据微软提供的建议,我们要慎重允许下列HTML标签,因为这些HTML标签
都是有可能导致跨站脚本攻击的。
以下是引用片段:
# <applet>
# <body>
# <embed>
# <frame>
# <script>
# <frameset>
# <html>
# <iframe>
# <img>
# <style>
# <layer>
# <link>
# <ilayer>
# <meta>
# <object>
可能这里最让人不能理解的是<img>。但是,看过下列代码后,就应该明白
其危险性了。
以下是引用片段:
<img src="javascript:alert('hello');">
<img src="java
script:alert('hello');">
<img src="java
script:alert('hello');">
通过<img>标签是有可能导致javascript执行的,这样攻击者就可以做他想
伪装的任何事情。
关于<style>也是一样:
========================================第37页========================================
以下是引用片段:
<style TYPE="text/javascript">...
alert('hello');
</style>
从客户端中检测到有潜在危险的 Request.Form 值
由于在.net中,Request时出现有HTML或Javascript等字符串时,系统会认为是危险性值。立
马报错上面的错误。
解决办法:
解决方案一:
在.aspx文件头中加入这句:
<%@ Page validateRequest="false" %>
解决方案二:
修改web.config文件:
<configuration>
<system.web>
<pages validateRequest="false" />
</system.web>
</configuration>
因为validateRequest默认值为true。只要设为false即可。
当然,这样只能是让界面好看一些,要想抵制注入,还得从过滤上做足功夫
然后,还是有不禁用validateRequest的方法的,如下
不禁用validateRequest=false。
正确的做法是在你当前页面添加Page_Error()函数,来捕获所有页面处理过程中发生的而
没有处理的异常。然后给用户一个合法的报错信息。如果当前页面没有Page_Error(),这个异
常将会送到Global.asax的Application_Error()来处理,你也可以在那里写通用的异常报错处
理函数。如果两个地方都没有写异常处理函数,才会显示这个默认的报错页面呢。
举例而言,处理这个异常其实只需要很简短的一小段代码就够了。在页面的Code-behind
页面中加入这么一段代码:
以下是引用片段:
protected void Page_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
if (ex is HttpRequestValidationException)
{
Response.Write("请您输入合法字符串。");
Server.ClearError(); // 如果不ClearError()这个异常会继续传到Application_Error()。