前言
学到一半发现学起来反而轻松了,可能是因为做渗透的原因,有基础上手比较快,今天来综合总结一下自己的相关学习心得。
1.产生该漏洞的原因是什么
SQL注入漏洞的主要原因在于应用程序在构建SQL查询语句时未能正确处理用户输入的数据。具体来说,当应用程序直接将用户输入的数据拼接到SQL查询语句中,而没有进行充分的验证和过滤时,攻击者就可以利用这一漏洞,通过输入恶意的SQL代码来篡改原始的查询语句,从而实现对数据库的非法访问和操作。
可以粗浅的理解为主要原因在于你输入的数据库恶意语句被执行了。
2.审计思路总结
简单概括下自己的思路。
- 查看过滤器:是否有过滤器,过滤器规则写的对不对
- sql语句的规则:是否预编译或参数化查询
- sql语句的写法:如何恶意产生闭合,能否前端利用,是否能通过参数拼接生成恶意的语句
大体思路是这个样子,但是其实里面细节很多的,像是各种技术的不同,各种替代,注释等等,在此不在多提,只是为了总结思路。
3.预编译可以预防所有的注入吗
我之前一直以为是能的,但是后来学习才发现,工具再好,架不住有些不当人啊。把前端的参数变量名直接给你当语句本身执行了,你有什么办法。。。。。。
预编译并不能预防所有的SQL注入。虽然预编译是一种有效的防止SQL注入的方法,但它并不能完全杜绝所有的SQL注入攻击。
预编译的主要原理是通过将SQL语句和参数分开处理,使得攻击者无法直接修改SQL语句的结构,从而减少了SQL注入的风险。但是,如果预编译语句的构造或使用不当,仍然存在被攻击的可能性。例如,如果预编译语句中的参数处理不严谨,或者某些特殊情况下参数被错误地解释为SQL代码的一部分,仍然可能导致SQL注入的发生。
此外,预编译只能防止基于SQL语句拼接的注入攻击,对于其他类型的注入攻击(如通过存储过程、触发器等),预编译可能无法起到有效的防护作用。
因此,虽然预编译是防御SQL注入的重要手段之一,但并不能完全依赖它来解决所有SQL注入问题。在开发过程中,还需要结合其他安全措施,如输入验证、输出编码、使用安全的数据库连接库等,来构建更加安全的应用程序。
总的来说,预防SQL注入需要综合考虑多种因素,并采取多层次的安全防护措施。
4.Mybaits相关
我之前知道开发常用的框架是ssm和ssh,其中的ssm的“m”指的就是Mybaits。之前有说过这是个半ORM模型,移植性差,但是其实不明白其工作原理,为什么 说是半ORM。
4.1运行过程
MyBatis 是一个优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通的 Java 对象)为数据库中的记录。接下来,我将描述 MyBatis 的启动和使用过程。
1. 添加依赖
首先,你需要在你的项目中添加 MyBatis 的依赖。如果你使用的是 Maven,你可以在 pom.xml 文件中添加如下依赖:
xml
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>你的MyBatis版本号</version>
</dependency>
2. 配置 MyBatis
你需要创建一个 MyBatis 的配置文件,通常命名为 mybatis-config.xml。这个文件包含了数据库连接信息、事务管理器、数据源等配置。
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="你的数据库驱动"/>
<property name="url" value="你的数据库URL"/>
<property name="username" value="你的数据库用户名"/>
<property name="password" value="你的数据库密码"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="你的Mapper文件路径"/>
</mappers>
</configuration>
3. 创建 Mapper 接口和映射文件
Mapper 接口定义了与数据库交互的方法,而映射文件则定义了 SQL 语句和结果集的映射规则。
例如,你可以创建一个 UserMapper.java 接口和一个 UserMapper.xml 映射文件。
UserMapper.java
java
public interface UserMapper {
User selectUserById(int id);
}
UserMapper.xml
xml
<mapper namespace="你的包名.UserMapper">
<select id="selectUserById" resultType="你的User类全路径">
SELECT * FROM user WHERE id = #{id}
</select>
</mapper>
4. 启动 MyBatis
你可以通过 MyBatis 的 SqlSessionFactoryBuilder 来构建 SqlSessionFactory,然后通过 SqlSessionFactory 来获取 SqlSession。SqlSession 是 MyBatis 的核心接口,用于执行 SQL 语句。
java
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
5. 使用 MyBatis
通过 SqlSession,你可以获取 Mapper 接口的实现,并调用其方法。
java
try {
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = userMapper.selectUserById(1);
System.out.println(user);
} finally {
session.close();
}
注意事项
确保你的数据库驱动、URL、用户名和密码是正确的。
确保你的 Mapper 接口和映射文件的命名空间和 ID 是匹配的。
在使用完 SqlSession 后,记得关闭它,以释放资源。你也可以使用 try-with-resources 语句来自动关闭 SqlSession。
这就是 MyBatis 的基本启动和使用过程。可以说很清晰了,怎么加载怎么启动,也比较好理解
4.2为什么叫半ORM,跟全ORM区别在哪
MyBatis作为半ORM模型,与全ORM模型在多个方面存在显著差异。以下是MyBatis与全ORM模型的主要区别,并通过具体例子加以说明:
- SQL控制:
MyBatis:需要开发者手动编写SQL语句,通过XML或注解方式配置。例如,开发者可能需要编写一个复杂的查询语句,用于检索满足特定条件的记录。这种方式允许开发者对SQL进行精确控制,但也需要更多的数据库知识和经验。
全ORM(如Hibernate):全自动生成SQL语句,开发者只需定义对象关系模型,ORM框架会自动处理数据库操作。这使得开发更加便捷,但可能会在某些复杂查询或性能优化方面受限。
- 对象映射:
MyBatis:将查询结果映射成Java对象,但不会自动建立对象之间的关系。开发者需要手动控制对象之间的关系,例如通过关联查询或手动构建对象图。
全ORM:自动建立对象之间的关系,可以根据对象关系模型直接获取关联对象或集合。这使得代码更加简洁,但在处理复杂关系时可能不如MyBatis灵活。
- 性能优化:
MyBatis:提供了延迟加载机制,当需要使用某个关联对象时,才通过代理模式实现对该对象的加载。这可以有效提高性能,尤其在处理大量数据时。
全ORM:更多地依赖内存和缓存技术来实现性能优化。虽然这在大多数情况下是有效的,但在某些特定场景下可能不如MyBatis的延迟加载机制高效。
- 数据库独立性:
MyBatis:不完全支持数据库无关性。如果需要支持多种数据库,开发者需要自定义多套SQL映射文件,工作量大。
全ORM:通常具有较好的数据库无关性,可以更容易地切换数据库。
综上所述,MyBatis和全ORM模型在SQL控制、对象映射、性能优化和数据库独立性等方面存在显著区别。我个人觉得就是需不需要进行手写sql语句的区别,全自动生成必然高适配,手写必然更高精准度但适配性低。
Hibernate如何启动和加载的
简单举个例子说明吧。
Hibernate的启动和使用过程通常涉及配置、初始化SessionFactory、创建Session以及执行数据库操作等步骤。下面是一个简单的示例,展示了Hibernate的启动和使用过程:
1. 添加依赖
首先,确保你的项目中包含了Hibernate的依赖。如果你使用Maven,可以在pom.xml文件中添加如下依赖:
xml
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>YOUR_HIBERNATE_VERSION</version>
</dependency>
2. 创建实体类
创建一个简单的实体类,例如User,并为其添加注解以映射到数据库表。
java
import javax.persistence.Entity;
import javax.persistence.Id;@Entity
public class User {
@Id
private Long id;
private String name;
private String email;// 省略构造器、getter和setter方法
}
3. 配置Hibernate
使用hibernate.cfg.xml文件来配置Hibernate。
xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 数据库连接配置 -->
<property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mydatabase</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">password</property><!-- 数据库方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property><!-- 显示SQL语句 -->
<property name="hibernate.show_sql">true</property><!-- 格式化SQL语句 -->
<property name="hibernate.format_sql">true</property><!-- 配置映射文件或实体类 -->
<mapping class="com.example.User"/>
</session-factory>
</hibernate-configuration>
4. 初始化SessionFactory
在应用程序启动时,初始化SessionFactory。
java
import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;public class HibernateUtil {
private static final SessionFactory sessionFactory;static {
try {
// 创建配置对象
Configuration configuration = new Configuration().configure();// 创建服务注册对象
StandardServiceRegistryBuilder serviceRegistryBuilder = new StandardServiceRegistryBuilder();
StandardServiceRegistry serviceRegistry = serviceRegistryBuilder.applySettings(configuration.getProperties()).build();// 创建元数据对象
Metadata metadata = new MetadataSources(serviceRegistry).getMetadataBuilder().build();// 创建SessionFactory
sessionFactory = metadata.getSessionFactoryBuilder().build();
} catch (Throwable ex) {
// 处理异常
throw new ExceptionInInitializerError(ex);
}
}public static SessionFactory getSessionFactory() {
return sessionFactor
上面简单的使用例子,跟mybaits对照看区别还是比较明显的。
写在最后
再会,兄弟,如果能帮助到你是我的荣幸!88~