实战用Python解析出抽象语法树

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 抽象语法树分析可以动态的做网络安全的解析,例如,对SQL语句的解析,可以有效检测SQL是否存在问题

原文合集地址如下,有需要的朋友可以关注

本文地址

合集地址

生成抽象语法树的例子

SQL

利用python的sqlparse库

sqlparse 是一个用于解析和分析 SQL 语句的 Python 库。它提供了一系列功能,可用于解析和操作 SQL 语句的不同组成部分,如关键字、标识符、表达式、函数、注释等。

以下是 sqlparse 库的一些主要功能:

解析 SQL 语句

sqlparse 可以解析和分析 SQL 语句,并将其拆分为不同的标记(token)。这使得您可以访问和操作 SQL 语句的各个部分,如 SELECT 语句中的列、表名、WHERE 子句等。

以sql代码SELECT * FROM users WHERE id = '1' OR '1'='1' or (1=2) or (x = '(123)')为例,编写了如下示例:

import sqlparse

# 递归打印 SQL 解析树
def print_tokens(tokens, indent=0):
    for token in tokens:
        if hasattr(token, "tokens"):
            print_tokens(token.tokens, indent + 4)
        else:
            print(" " * indent,token.ttype, token.value)

# 解析 SQL 查询语句
def demo1():
    user_input = "1' OR '1'='1"
    sql_query = "SELECT * FROM users WHERE id = '" + user_input + "' or (1=2) or (x = '(123)')"
    print(sql_query)
    parsed = sqlparse.parse(sql_query)[0]
    # 打印 AST 对象
    print_tokens(parsed.tokens)

if __name__ == '__main__':
    demo1()

运行的结果为:

Token.Keyword.DML SELECT
 Token.Text.Whitespace  
 Token.Wildcard *
 Token.Text.Whitespace  
 Token.Keyword FROM
 Token.Text.Whitespace  
     Token.Name users
 Token.Text.Whitespace  
     Token.Keyword WHERE
     Token.Text.Whitespace  
             Token.Name id
         Token.Text.Whitespace  
         Token.Operator.Comparison =
         Token.Text.Whitespace  
         Token.Literal.String.Single '1'
     Token.Text.Whitespace  
     Token.Keyword OR
     Token.Text.Whitespace  
         Token.Literal.String.Single '1'
         Token.Operator.Comparison =
         Token.Literal.String.Single '1'
     Token.Text.Whitespace  
     Token.Keyword or
     Token.Text.Whitespace  
         Token.Punctuation (
             Token.Literal.Number.Integer 1
             Token.Operator.Comparison =
             Token.Literal.Number.Integer 2
         Token.Punctuation )
     Token.Text.Whitespace  
     Token.Keyword or
     Token.Text.Whitespace  
         Token.Punctuation (
                 Token.Name x
             Token.Text.Whitespace  
             Token.Operator.Comparison =
             Token.Text.Whitespace  
             Token.Literal.String.Single '(123)'
         Token.Punctuation )

可以发现,sqlparse将SQL拆分成了一个一个token,在语法和词法解析领域,Token(记号)是指源代码中的最小语义单元,它代表了编程语言中的一个词法元素。Token 是语法分析器(Parser)在解析源代码时所使用的基本单位。

在编程语言中,Token 可以表示关键字、标识符、操作符、常量、字符串、注释等各种语法成分。语法分析器通过词法分析(Lexical Analysis)将源代码分解为一系列的 Token,以便进行进一步的语法分析和语义处理。

词法分析器(也称为词法解析器或扫描器)负责将源代码字符串转换为一系列 Token。它通过扫描源代码字符流,识别出连续的字符组成的词法单元,并为每个词法单元分配一个相应的 Token 类型。每个 Token 类型通常具有一个唯一的标识符和相关的属性值。

例如,在下面的代码片段中:

x = 10 + y

词法分析器将识别出以下 Token:

  • 标识符 Token:x
  • 操作符 Token:=
  • 数字常量 Token:10
  • 操作符 Token:+
  • 标识符 Token:y

词法分析器将将这些 Token 传递给语法分析器,后者负责根据语法规则进行进一步的解析和分析。

通过使用 Token,语法分析器可以更容易地理解和处理源代码的结构。每个 Token 都包含了与之相关的类型信息和属性值,使得语法分析器能够根据 Token 类型进行相应的语法规则匹配和语义处理。

在拿到这棵词法解析树之后,不管sql注入如何变幻,我们都可以定位到最小token单元,从而动态监测sql注入的行为。

格式化 SQL 语句

sqlparse 可以根据预定义的样式规则对 SQL 语句进行格式化。这使得 SQL 语句的结构更加清晰可读,便于理解和调试。

当使用 sqlparse 库来格式化 SQL 语句时,它会执行以下操作:

  1. 重新缩进:sqlparse 会根据语句的嵌套结构重新缩进语句,使其更具可读性和结构清晰。它会根据语句中的关键字、括号、逗号等进行缩进操作,以反映语句的层次结构。
  2. 关键字大小写转换:sqlparse 可以根据指定的选项将关键字转换为特定的大小写形式。您可以选择将关键字转换为大写、小写或首字母大写。这可以使 SQL 语句中的关键字在格式化后保持一致性。
  3. 空格和换行符处理:sqlparse 会添加适当的空格和换行符,以提高语句的可读性。它会在逗号、括号、运算符等符号周围添加空格,使语句更易于理解。此外,它会根据语句的结构添加适当的换行符,以使语句在屏幕上更好地展示。
  4. 注释处理:sqlparse 会解析 SQL 语句中的注释,并根据注释的位置将其正确地应用于格式化的结果。这有助于确保注释在格式化后保持正确的位置和格式。
  5. 字符串处理:sqlparse 会解析和处理 SQL 语句中的字符串,以确保在格式化后字符串的内容保持不变。它会保留字符串中的引号和转义字符,以保持字符串的完整性。

下面是一个例子:

def demo2():
    sql_statement = 'select * from users where deleted_mark = false '
    formatted_sql = sqlparse.format(sql_statement, reindent=True, keyword_case='upper')
    print(formatted_sql)

上述代码中,我们的sql语句为select * from users where deleted_mark = false,最终的结果为:

SELECT *
FROM users
WHERE deleted_mark = FALSE

分析 SQL 语句结构

sqlparse 可以分析 SQL 语句的结构,并提供了一组 API 用于查找和操作特定类型的 SQL 元素。例如,您可以使用 sqlparse 查找和访问所有的表名、列名、函数调用等。

过滤 SQL 片段

sqlparse 可以根据指定的条件过滤和选择 SQL 语句中的特定部分。例如,您可以使用 sqlparse 仅提取 SELECT 语句中的列名,或者仅提取 WHERE 子句中的条件表达式。

解析 SQL 片段

sqlparse 不仅可以解析完整的 SQL 语句,还可以解析和分析 SQL 片段。这使得您可以处理和操作 SQL 片段而不仅仅是完整的语句。

python

ast库解析python代码

def demo3():
    import ast

    code = """
def greet(name=123):
    print(f"Hello, {name}!")
    return 1
    """

    tree = ast.parse(code)

    class MyVisitor(ast.NodeVisitor):
        def visit_FunctionDef(self, node):
            print("Function definition:", node.name)

            # 获取参数名和默认值
            for arg in node.args.args:
                print("Parameter name:", arg.arg)

            # 获取返回值
            for statement in node.body:
                if isinstance(statement, ast.Return):
                    print("Return value:", ast.literal_eval(statement.value))

            self.generic_visit(node)

    visitor = MyVisitor()
    visitor.visit(tree)

运行的结果为

Function definition: greet
Parameter name: name
Return value: 1
目录
相关文章
|
4天前
|
Python
Python的编辑工具-Jupyter notebook实战案例
这篇博客介绍了Jupyter Notebook的安装和使用方法,包括如何在本地安装Jupyter、启动和使用Jupyter Notebook进行编程、文档编写和数据分析,以及如何执行和管理代码单元(Cell)的快捷键操作。
15 4
Python的编辑工具-Jupyter notebook实战案例
|
4天前
|
Python
Python软件包及环境管理器conda实战篇
详细介绍了如何使用conda进行Python软件包管理及环境管理,包括查看、安装、卸载软件包,切换源,管理不同版本的Python环境,以及解决使用过程中可能遇到的错误。
24 2
Python软件包及环境管理器conda实战篇
|
3天前
|
数据采集 机器学习/深度学习 数据挖掘
探索Python编程之美:从基础到实战
【9月更文挑战第3天】本文旨在通过深入浅出的方式,带领读者领略Python编程语言的魅力。我们将从基本语法入手,逐步深入至高级特性,最终通过实战案例将理论知识与实践操作相结合。无论你是编程新手还是有一定经验的开发者,这篇文章都将为你提供有价值的见解和技巧。
|
2天前
|
数据采集 Python
探索Python中的异步编程:从基础到实战
【9月更文挑战第4天】在Python的海洋中,异步编程犹如一艘快艇,让你的代码在执行效率和响应速度上破浪前行。本文将带你从理解“异步”这一概念出发,深入到Python的asyncio库的使用,再到构建一个实际的异步Web爬虫项目,体验异步编程的魅力。我们将避开枯燥的理论,通过生动的比喻和直观的代码示例,让异步编程的知识活灵活现。
|
2天前
|
测试技术 Apache 数据库
从慢如蜗牛到飞一般的感觉!Python性能测试实战,JMeter&Locust助你加速🏃‍♂️
【9月更文挑战第6天】你的Python应用是否曾因响应缓慢而让用户望而却步?借助JMeter与Locust,这一切将迎刃而解。JMeter作为Apache基金会的明星项目,以其强大的跨平台和多协议支持能力,成为性能测试领域的魔法师;而Locust则以Python的简洁与高效,让性能测试更加灵活。通过实战演练,你可以利用这两款工具轻松识别并解决性能瓶颈,优化数据库查询、网络配置等,最终使应用变得敏捷高效,轻松应对高并发挑战。
7 1
|
4天前
|
安全 数据挖掘 Python
Python的打包工具(setup.py)实战篇
关于如何使用Python的setup.py工具打包Python项目的实战教程。
8 0
Python的打包工具(setup.py)实战篇
|
4天前
|
Python
Python软件包管理工具pip实战篇
详细介绍了Python软件包管理工具pip的使用方法,包括安装、搜索、卸载软件包,修改软件源,导出和安装依赖列表,以及查看pip版本和配置信息等操作,并提供了相关命令示例。
14 0
Python软件包管理工具pip实战篇
|
7天前
|
开发者 图形学 Java
揭秘Unity物理引擎核心技术:从刚体动力学到关节连接,全方位教你如何在虚拟世界中重现真实物理现象——含实战代码示例与详细解析
【8月更文挑战第31天】Unity物理引擎对于游戏开发至关重要,它能够模拟真实的物理效果,如刚体运动、碰撞检测及关节连接等。通过Rigidbody和Collider组件,开发者可以轻松实现物体间的互动与碰撞。本文通过具体代码示例介绍了如何使用Unity物理引擎实现物体运动、施加力、使用关节连接以及模拟弹簧效果等功能,帮助开发者提升游戏的真实感与沉浸感。
19 1
|
7天前
|
数据采集 存储 JavaScript
Python 爬虫实战:从入门到精通
【8月更文挑战第31天】 本文将带你走进 Python 爬虫的世界,从基础的请求和解析开始,逐步深入到反爬策略的应对和数据存储。我们将通过实际案例,一步步构建一个功能完整的爬虫项目。无论你是编程新手还是有一定经验的开发者,都能在这篇文章中找到适合自己的学习路径。让我们一起探索数据的海洋,揭开网络信息的神秘面纱。
|
7天前
|
开发者 图形学 API
从零起步,深度揭秘:运用Unity引擎及网络编程技术,一步步搭建属于你的实时多人在线对战游戏平台——详尽指南与实战代码解析,带你轻松掌握网络化游戏开发的核心要领与最佳实践路径
【8月更文挑战第31天】构建实时多人对战平台是技术与创意的结合。本文使用成熟的Unity游戏开发引擎,从零开始指导读者搭建简单的实时对战平台。内容涵盖网络架构设计、Unity网络API应用及客户端与服务器通信。首先,创建新项目并选择适合多人游戏的模板,使用推荐的网络传输层。接着,定义基本玩法,如2D多人射击游戏,创建角色预制件并添加Rigidbody2D组件。然后,引入网络身份组件以同步对象状态。通过示例代码展示玩家控制逻辑,包括移动和发射子弹功能。最后,设置服务器端逻辑,处理客户端连接和断开。本文帮助读者掌握构建Unity多人对战平台的核心知识,为进一步开发打下基础。
25 0

推荐镜像

更多
下一篇
DDNS