编码问题

不同的字符编码也会导致出现一些安全问题

sql语法中用单引号”‘“作为转义字符

  1. insert into person(LastName) values(‘O’’R’)
  2. 则输出结果为O’R

php中的转义为\

如果进入数据库之前,web语言中没有考虑到双字节字符问题,双字节字符会被认为是两个字节

  1. 0x 5c和0x bf 5c会被认为是一个字符(双字节字符)

要解决这种问题,需要统一数据库,操作系统,web应用所使用的字符集,避免各层对字符的理解存在差异

  1. 统一设置为utf-8是一个很好的办法

mysql中环境变量sql_mode

  1. 定义了mysql应该支持的sql语法,数据校验等
  2. 默认为null,这种设置下可以允许一些非法操作,比如允许一些非法数据的插入
  3. 在生产环境下必须设置为严格模式

    sql_mode常用来解决的几类问题

  4. 通过设置sql_mode,可以完成不同严格程度的数据校验,有效地保证数据准确性;
  5. 通过设置sql_mode为宽松模式,来保证大多数sql符合标准的sql语法,这样应用在不同数据库之间进行迁移时。则不需要对业务sql进行较大的修改;
  6. 在不同数据库之间进行数据迁移之前,通过设置sql_mode可以使MySQL上的数据更方便地迁移到目标数据库中

    sql_mode包含的模式

  7. ansi模式:宽松模式,对插入数据进行校验,如果不符合定义类型或长度,对数据类型调整或截断保存,爆warning警告
  8. traditional模式:严格模式,当向mysql数据库插入数据时,进行数据的严格校验,保证错误数据不能插入,爆error错误
  9. strict_trans_tables模式:严格模式,进行数据的严格校验,错误数据不能插入,爆error错误

查看sql_mode的语句:

  1. use database_name;

  2. select @@sql_mode;

  3. 或者

  4. use data_basename;

  5. show variables like ‘%sql_mode%’;

  6. LmrvjS.png

  7. 结论:在STRICT_TRANS_TABLES模式下,插入数据时,mysql会严格的进行数据的校验,当发现插入列值未满足要求,直接报告error错误,保证了错误数据无法插入到数据库中

  8. 结论:

  9. 严格模式,当向mysql数据库插入数据时,进行数据的严格校验,保证错误数据不能插入,报error错误,而不仅仅是警告。用于事务时,会进行事务的回滚。

  10. 一旦发现错误立即放弃INSERT/UPDATE。如果你使用非事务存储引擎,这种方式不是你想要的,因为出现错误前进行的数据更改不会“滚动”,结果是更新“只进行了一部分”。