当前位置: 首页 > 编程日记 > 正文

web安全浅析

就之前本人主持开发的金融产品所遇到的安全问题,设计部分请参见:http://www.cnblogs.com/shenliang123/p/3835072.html

这里就部分web安全防护就简单的交流:

1.1系统安全

1.1.1  客户端脚本安全

(1)跨站脚本攻击(XSS):

XSS攻击,通常指黑客通过“html注入” 篡改了网页,插入了恶意的脚本,从而在用户浏览网页的时候,控制用户浏览器的一种攻击。

最常见的XSS攻击就是通过读取浏览器的Cookie对象,从而发起“cookie劫持”,当前用户的登录凭证存储于服务器的session中,而在浏览器中是以cookie的形式进行存储的,cookie被劫持后,意味着攻击者可以不通过密码而直接登录系统。我们也可以直接在浏览器中输入脚本javascript:alert(document.cookie)来获取当前cookie值。

目前防止“cookie劫持”的方法大致有:a. 输入检查,使用filter来过滤敏感的关键字;b. 将cookie与用户ip地址进行绑定;c. 为cookie植入HttpOnly标识。

本系统采用的是第3种方式:为cookie植入HttpOnly标识。一旦这个HttpOnly被设置,你在浏览器的 document对象中就看不到Cookie了,而浏览器在浏览的时候不受任何影响,因为Cookie会被放在浏览器头中发送出去(包括ajax的时 候),应用程序也一般不会在js里操作这些敏感Cookie的,对于一些敏感的Cookie我们采用HttpOnly,对于一些需要在应用程序中用js操作的cookie我们就不予设置,这样就保障了Cookie信息的安全也保证了应用。

具体代码实现:在web服务器tomcat的配置文件server.xml中添加:

<Context docBase="E:\tomcat\apache-tomcat-6.0.24/webapps/netcredit" path="/netcredit" reloadable="false" useHttpOnly="true"/>

或者在项目的web.xml 配置如下:

复制代码
 <session-config><cookie-config> <http-only>true</http-only> </cookie-config></session-config>
复制代码

图1-1 浏览器cookie截图

(2)跨站点请求伪造(CSRF):

本系统采用了对抗CSRF最有效的防御方法:验证码。

1.1.2 服务器端应用安全

服务器端的安全相对于客户端来说显的更加的重要,因为服务器端的某个安全漏洞可能带来的是致命的危险。因此我们对服务器端的安全更为的慎重和重视。

(1)SQL注入攻击:

Sql注入的的两个关键条件:第一个是用户能够控制输入;第二个是原本程序要执行的代码,拼接了用户输入的数据。

根据上面两个关键条件,系统为防止sql注入使用了以下方法:

第一:使用预编译语句,这也是防御sql注入最有效的方法,完全摒弃代码的直接拼接所带来的危险。

复制代码
public List<T> findByPage(final String hql, final Object[] values, final int offset,final int pageSize) {List<T> list = getHibernateTemplate().executeFind(new HibernateCallback(){public Object doInHibernate(Session session)throws HibernateException, SQLException{Query query=session.createQuery(hql);for (int i = 0 ; i < values.length ; i++){query.setParameter( i, values[i]);}if(!(offset==0 && pageSize==0)){query.setFirstResult(offset).setMaxResults(pageSize);}List<T> result = query.list();return result;}});return list;}      
复制代码

第二:关闭web服务器的错误回显功能,这样可以防止攻击者对系统进行攻击后,通过回显的详细错误信息对攻击内容进行调整,对攻击者提供极大的便利。我们在项目的web.xml文件中添加以下示例代码:

复制代码
  <error-page><error-code>400</error-code><location>/error400.jsp</location></error-page>
复制代码

第三:数据库自身使用最小权限原则,系统程序不使用最高权限的root对数据库进行连接,而是使用能满足系统需求的最小权限账户进行数据库连接,而且多个数据库之间使用不同的账户,保证每个数据库都有独立对应的账户。

(2)文件上传漏洞:

文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过脚本文件获得了执行服务器端命令的能力,这样将会导致严重的后果。而本系统内涉及到大量的图片格式文件上传,因此对于上传问题的处理非常谨慎,并尽可能的达到安全标准。

本系统主要通过对上传文件详细的格式验证:

第一步:通过后缀名来简单判断文件的格式。

复制代码
public static boolean isPicture(String pInput) throws Exception{// 获得文件后缀名String tmpName = pInput.substring(pInput.lastIndexOf(".") + 1,pInput.length());// 声明图片后缀名数组String imgeArray [] = { "jpg", "png", "jpeg" };// 遍历名称数组for(int i = 0; i<imgeArray.length;i++){ // 判断符合全部类型的场合if(imgeArray [i].equals(tmpName.toLowerCase())){return true;}}return false;}
复制代码

第二步:通过读取文件的前两个字符进行对比,例如png格式图片的前两个字符为8950,而jpg格式的图片前两个字符为ffd8。

复制代码
public static String bytesToHexString(byte[] src) {StringBuilder stringBuilder = new StringBuilder();if (src == null || src.length <= 0) {return null;}for (int i = 0; i < src.length; i++) {int v = src[i] & 0xFF;//byte to intString hv = Integer.toHexString(v);if (hv.length() < 2) {stringBuilder.append(0);}stringBuilder.append(hv);}return stringBuilder.toString();}  
复制代码

第三步:如果上传的为图片,则获取相应的高度和宽度,如果存在相应的宽度和高度则可认为上传的是图片。

复制代码
public static boolean isImage(File imageFile) {if (!imageFile.exists()) {return false;}Image img = null;try {img = ImageIO.read(imageFile);if (img == null || img.getWidth(null) <= 0 || img.getHeight(null) <= 0) {return false;}return true;} catch (Exception e) {return false;} finally {img = null;}}
复制代码

如果以上验证都成功通过,本系统在对文件进行存储时会将文件名进行重命名处理,并且设置相应的web服务器,默认不显示目录。因为文件上传如果需要执行代码,则需要用户能够访问到这个文件,因此使用随机数改写了文件名,将极大的增加攻击的成本,甚至根本无法成功实施攻击。

//对文件的名称进行重命名StringBuilder sb = new StringBuilder().append(new Date().getTime()).append(".").append(fileMsg[1]);

(3)认证与会话管理:

认证实际上就是一个验证凭证的过程,因此我们对登录密码有着严格的规定:密码要求长度在8位以上并且包含字母,数字,符号两种以上的组合。并将密码加密后再进行数据库的存储。为防止一些暴力破解手段,又出于用户体验的考虑,本系统采用用户登录时默认不进行验证码的输入,但密码三次输入失败后需要进行验证码的输入,连续五次输入错误后,该用户的ip地址将被封,可以在一段时间后自动解封或者后台管理员手动解封。涉及到系统资金有关的操作,例如投标,我们还需要用户设置并提供支付密码,而提现等操作我们还配备短信验证码功能。以此来增强验证的可靠性。

当用户登录完成后,在服务器端会创建一个新的会话(Session),会话中保存着用户的状态和相关信息,服务器端维护所有在线用户的Session,而浏览器则是将SessionId加密后保存在cookie中,这里就出现了前面提到了“cookie劫持“问题,本系统通过将cookie中植入HttpOnly成功解决该问题。本系统还给Session设置了一个有效时间,来保证在有效时间后Session将自动销毁,以防止Session长连接所带来的安全隐患。在web.xml文件中添加以下代码:

<session-config><session-timeout>30</session-timeout></session-config>

(4)访问控制:

访问控制实际上就是建立用户和权限之间的对应关系,本系统采用的是“基于角色的访问控制”,根据相应功能模块的划分相应的权限,并将相应的权限分配给不同的角色,再将角色分配给用户,用户就拥有了该角色所持有的权限。具体的设计与实现分析请见1.2 Annotation和Struts2拦截器实现基于角色的垂直权限管理。

1.2 Annotation和Struts2拦截器实现基于角色的垂直权限管理

1.2.1 模块的设计

以下是本系统的垂直权限管理模块的物理模型设计:

图1-2 权限管理模块物理模型

管理员与角色之间是多对多的关系,这样可以实现为一个管理员分配多个角色进行管理,而角色与权限之间也是多对多的关系,权限是根据功能模块进行划分的,使得角色可以进行细粒度的权限分配。

4.3.2 模块的代码实现

首先声明一个注解类,该注解类是自定义的,根据我们需要的实现的功能进行相应注解的定义,使得在之后需要注释的方法上使用相应注解,代码如下:

复制代码
@Retention(RetentionPolicy.RUNTIME)           //注解的存活时间,整个运行时都存活 @Target(ElementType.METHOD)               //此注解表示只能在方法上面有效 public @interface Permission { /** 模块名 **/ String model(); /** 权限值 **/ String privilegeValue();/*用于区分当前页面是dialog还是navTab*/String targetType();}然后定义相应的拦截器类,并在struts2的配置文件struts.xml中进行拦截器的配置,为相应需要的类进行拦截验证,定义拦截器部分的核心代码如下:/*** 校验控制在方法上的拦截*/@SuppressWarnings("unchecked")public boolean validate(Admin admin, ActionInvocation invocation, List<Role> roleList,Map session) {String methodName= "execute";                                  //定义默认的访问方法Method currentMethod = null;methodName = invocation.getProxy().getMethod();                //通过actionProxy,得到当前正在执行的方法名try {//利用反射,通过方法名称得到具体的方法currentMethod = invocation.getProxy().getAction().getClass().getMethod(methodName, new Class[] {});} catch (Exception e) {e.printStackTrace();}if (currentMethod != null && currentMethod.isAnnotationPresent(Permission.class)) {//得到方法上的Permission注解Permission permission = currentMethod.getAnnotation(Permission.class);//通过Permission注解构造出系统权限Systemprivilege privilege = new Systemprivilege(new SystemprivilegeId(permission.privilegeValue(), permission.model()));session.put("targetType", permission.targetType());//迭代用户所具有的具体权限,如果包含,返回truefor (Role role : roleList) {                 RolePrivilege rolePrivilege = new RolePrivilege(privilege, role);if (role.getRolePrivileges().contains(rolePrivilege)) {return true;}}return false;}return true;}
复制代码

本系统需要向权限表中添加相应的功能模块,为了有一个比较细的粒度,模块将根据功能进行划分,而权限则根据按钮来进行细分:

图1-3 数据库截图

在定义了相应的权限后,我们需要在相应的执行方法体上面进行注释,使得拦截器进行拦截验证时能根据注释获取该执行方法体的模块和权限类型:

@Permission(model="recharge", privilegeValue="recharge" ,targetType="dialog")

4.3.3 模块的实现效果

首先添加相应的员工:

然后新增相应的角色,填写角色名称并勾取相应的权限:

然后新增相应的用户,勾选该用户相应的角色,可以选择多个角色,并且选择相应用户对应的员工:

相关文件主要来自网络和个人编程。支持转载

转载于:https://www.cnblogs.com/GmrBrian/p/6241945.html

相关文章:

HDU 1556 Color the ball

题解&#xff1a;基础的树状数组区间修改&#xff0c;单点查询。 #include <cstdio> #include <cstring> int c[100005],a,b,n; int modify(int x,int num){while(x<n)c[x]num,xx&-x;} int query(int x){int s0;while(x>0)sc[x],x-x&-x;return s;} …

OC协议实现多继承

协议实现多继承 协议实现多继承的话&#xff0c;只是简答的提供了接口&#xff0c;并灭有提供实现的方式。 A #import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGINprotocol StuAProtocal <NSObject>// 学生A 会游泳 - (void)swimming;endinterface Stude…

扶梯正确使用_乘坐自动扶梯解释CSS浮动

扶梯正确使用by Kevin Kononenko凯文科诺年科(Kevin Kononenko) 乘坐自动扶梯解释CSS浮动 (CSS Floats Explained By Riding An Escalator) 如果您曾经跳过自动扶梯&#xff0c;那么您可以快速了解浮动。 (If you have ever jumped on an escalator, then you can quickly und…

安卓学习-界面-ui-ListView

ListView继承自AbsListView AbsListView属性 XML属性代码说明 android:choiceMode setChoiceMode(int choiceMode) AbsListView.CHOICE_MODE_SINGLEAbsListView.CHOICE_MODE_MULTIPLEAbsListView.CHOICE_MODE_MULTIPLE_MODAL none :无选择模式 singleChoice&#xff1a;允许单…

swift 浮点型字符串的运算

// 1 两个浮点字符串之间的运算 let str1 "1.3"; let str2 "2.4"; let val1 Double(str1); let val2 Double(str2);let val3 CGFloat(Double(str1)!) * CGFloat(Double(str2)!);print(val3);// 2 string 转 double 不失精度 let formattor NumberFo…

为什么要在JavaScript中使用静态类型? (使用Flow进行静态打字的4部分入门)

by Preethi Kasireddy通过Preethi Kasireddy 为什么要在JavaScript中使用静态类型&#xff1f; (使用Flow进行静态打字的4部分入门) (Why use static types in JavaScript? (A 4-part primer on static typing with Flow)) As a JavaScript developer, you can code all day …

客户端如何连接 DataSnap Server 调用服务的方法

一般http访问的地址是 http://localhost:8099/datasnap/rest/TServerMethods1/EchoString/abc 一、用FDConnection1连接Datasnap服务器 FireDAC 连接Datasnap服务端。这个是tcp协议连接通讯&#xff0c;长连接。服务端不是没个方法都建立实例释放实例&#xff0c;而是连接的时…

Solr_全文检索引擎系统

Solr介绍&#xff1a; Solr 是Apache下的一个顶级开源项目&#xff0c;采用Java开发&#xff0c;它是基于Lucene的全文搜索服务。Solr可以独立运行在Jetty、Tomcat等这些Servlet容器中。 Solr的作用&#xff1a; solr是一个现成的全文检索引擎系统&#xff0c; 放入tomcat下可以…

swift 数组 filter reduce sort 等方法

数组的常用方法 swift 数组有很多的操作方法&#xff0c;但是用的时候用常常想不起来&#xff0c;就列出来看看 map 和 flatMap对数组中的元素进行变形操作filter主要对数组进行过滤reduce主要对数组进行计算sort对数组进行排序forEach循环遍历每一个元素min 和 max找出数组中…

im和音视频开发哪个更好_找时间成为更好的开发人员

im和音视频开发哪个更好There’s no time for anything. At least that’s how it feels doesn’t it? No time to learn all the things you think you need to learn to stay ahead of the curve. No time to go back and refactor that ugly piece of code. It works (sort…

4-8 同义词

雅思阅读&#xff1a;剑4~剑8阅读的所有同义词转换 雅思必考词汇 Cambridge 4 TEST 1 1. ignorepay no attentionnot pay any attentiontake no noticenot take any notice忽略&#xff0c;无视v. 2. encounterfaceconfrontmeet遇见&#xff0c;遭遇v. 3. mistaken viewmisconc…

swift可选类型

import UIKitvar array1 ["1","2","3","4","5"];// 1 if let 是一个组合关键字 来进行可选绑定 // 解决Optional对象解包时产生空对象的处理。 for i in array1 {print(i); }if let idx array1.firstIndex(of: "4&q…

java 配置及Eclipse安装

jdk下载 点我~ Java SE Development Kit 8u20 You must accept the Oracle Binary Code License Agreement for Java SE to download this software. Accept License Agreement Decline License Agreement Thank you for accepting the Oracle Binary Code License Agree…

golang 命令行_如何使用Golang编写快速有趣的命令行应用程序

golang 命令行by Peter Benjamin彼得本杰明(Peter Benjamin) 如何使用Golang编写快速有趣的命令行应用程序 (How to write fast, fun command-line applications with Golang) A while back, I wrote an article about “Writing Command-Line Applications in NodeJS”.不久前…

【Pyhon 3】: 170104:优品课堂: GUI -tkinter

from tkinter import * root Tk() root.title("BMS 图书管理系统") lbl Label(root, text书名:)#(1) lbl.pack() #(2) lbl.place(45.50) #(3) web 早期布局&#xff0c;&#xff0c; 常见。 lbl.grid(row0, column0) # web 早期布局&#xff0c;&#xff0c; 常见…

swift Sequence 和 SubSequence

1 序列 Sequence 序列协议是集合类型结构中的基础。 一个序列是代表有一系列具有相同类型的值&#xff0c;并且对这些值进行迭代。 协议中主要有两个参数&#xff0c;一个是元素Element&#xff0c;一个就是迭代器Iterator /// A type representing the sequences elements.…

PDF数据提取------1.介绍

1.关于PDF文件 PDF&#xff08;Portable Document Format的简称&#xff0c;意为“便携式文件格式”&#xff09;是由Adobe Systems在1993年用于文件交换所发展出的文件格式。它的优点在于跨平台、能保留文件原有格式&#xff08;Layout&#xff09;、开放标准&#xff0c;能自…

javascript_治愈JavaScript疲劳的研究计划

javascriptby Sacha Greif由Sacha Greif 治愈JavaScript疲劳的研究计划 (A Study Plan To Cure JavaScript Fatigue) Like everybody else, I recently came across Jose Aguinaga’s post “How it feels to learn JavaScript in 2016”.像其他所有人一样&#xff0c;我最近遇…

SQL Server中SELECT会真的阻塞SELECT吗?

在SQL Server中&#xff0c;我们知道一个SELECT语句执行过程中只会申请一些意向共享锁(IS) 与共享锁(S), 例如我使用SQL Profile跟踪会话86执行SELECT * FROM dbo.TEST WHERE OBJECT_ID 1 这个查询语句&#xff0c;其申请、释放的锁资源的过程如下所示&#xff1a; 而且从最常见…

appium IOS真机测试

看了 http://blog.csdn.net/today520/article/details/36378805 的文章&#xff0c;终于在真机上面测试成功。 由于没有开发者账号&#xff0c;不能发布应用到机器上面。所以就用了网易新闻的客户端来测试 没有开发者账号&#xff0c;貌似不能真正的开始测试。只能启动一下客户…

siwft 写时复制 Copy-On-Write

写时复制 Copy-On-Write 1 定义 在siwft 标准库中&#xff0c;Array&#xff0c;Dictionary&#xff0c;Set这样的集合类型是通过写时复制来实现的。 import Foundationvar a1 [1,2,3]; var a2 a1;// 将a1 复制给 a2&#xff0c;地址打印结果是相同的// 0x1--0x2--0x3 pri…

超越技术分析_超越技术面试

超越技术分析by Jaime J. Rios由Jaime J. Rios 超越技术面试 (Transcending the Technical Interview) “Wow. What a chastening and shameful experience that was.”“哇。 那真是一种令人st目结舌的经历。” This was my immediate mental reaction after I completed my…

轻松获取LAMP,LNMP环境编译参数配置

轻松获取LAMP&#xff0c;LNMP环境编译参数配置 作者:Mr.Xiong /分类:系统管理 字号&#xff1a;L M S大家是否遇到过去了新公司&#xff0c;公司内的LAMP&#xff0c;LNMP等所有的环境都是配置好的&#xff08;已经在提供服务了&#xff09;&#xff0c;公司又没有留下部署文档…

java内存分配--引用

栈内存 对象地址 堆内存 存放属性 public class TestDemo{ public static void main(String args[]){ Person perA new Person(); //出现new百分之百就是要申请堆内存 perA.name"王强"&#xff1b; //perA 地址存放在栈内存中&#xff0c;同一块内存只能存…

iOS NSObject对象内存大小

NSObject内存大小 类的本质是结构体 无须赘述 struct NSObject { Class isa; };一个类对象的实例大小是8个字节 之所以打印出的16个字节&#xff0c;是因为一个NSObject 最小开辟16个字节 NSObject *obj [[NSObject alloc]init];// class_getInstanceSize 这是runtime 获…

客户端渲染 服务端渲染_这就是赢得客户端渲染的原因

客户端渲染 服务端渲染A decade ago, nearly everyone was rendering their web applications on the server using technologies like ASP.NET, Ruby on Rails, Java, and PHP.十年前&#xff0c;几乎每个人都使用ASP.NET&#xff0c;Ruby on Rails&#xff0c;Java和PHP等技术…

java多线程三之线程协作与通信实例

多线程的难点主要就是多线程通信协作这一块了&#xff0c;前面笔记二中提到了常见的同步方法&#xff0c;这里主要是进行实例学习了&#xff0c;今天总结了一下3个实例&#xff1a; 1、银行存款与提款多线程实现&#xff0c;使用Lock锁和条件Condition。 附加 &#xff1a;…

Java8中Lambda表达式的10个例子

Java8中Lambda表达式的10个例子 例1 用Lambda表达式实现Runnable接口 Java代码 //Before Java 8: new Thread(new Runnable() { Override public void run() { System.out.println("Before Java8, too much code for too little to do"); } }).start(); …

OC的对象的分类

OC的对象分类 一 oc的对象分类主要分为3种 1 instance 对象&#xff1a; 实例对象就是通过alloc 出来的对象&#xff0c;一个类每一次的alloc都会产生一个新的实例对象 StudentA *a [[StudentA alloc]init];StudentA *b [[StudentA alloc]init];// 打印结果如下 地址是明显…

如何在国内上medium_在Medium上写作的风格指南

如何在国内上mediumAfter spending more than 1,000 hours writing and editing stories for our Medium publication, I’ve decided to create this living style guide for contributors. Feel free to use it for your publication as well.在花了1000多个小时为我们的《中…