代码质量与安全 | SonarQube 9.9 LTS提升Python开发效率与质量

SonarQube 9.9 LTS推出了强大的Python分析器,提供了近250条规则,确保Python开发人员编写出符合生产标准和开发要求的干净代码。

与SonarQube 8.9 LTS相比,9.9 LTS版本在Python分析方面有了显著的进步。您可以喝一口咖啡,换个舒适的姿势,接下来我们将为您介绍这些改进!

分析引擎的更新

来自Typeshed的预计算符号提高了性能和准确性

SonarQube通过基于Python标准库,以及Python开发人员使用的常见库的类型信息来提供准确分析。这些类型信息由Typeshed(Python存根的集合)提供。

在SonarQube 8.9 LTS中,会在分析时计算这些信息,这将非常昂贵,也无法收集所有可用的信息(例如基于所用Python版本的条件类型信息)。

SonarQube 9.9 LTS从Typeshed中提取数据,并具有更好的性能(仅计算一次符号,作为SonarQube的一部分提供,而不是在每次分析时计算),从而获得了性能更好、结果更好的分析。

可提供Python版本信息,以获得更准确的分析结果

正如前面提到的,SonarQube现在可以考虑到与使用的Python版本相关的类型信息。

与Python 2相比,Python 3有许多重大更改,这对于Sonar的错误检测规则有影响,因为某些代码模式在Python 3中是错误的,但在Python 2中不是!

使用SonarQube 9.9 LTS的开发人员现在可以设置sonar.python.version分析参数,以便检测与Python 2或Python 3相关的特定问题。

请参考这段代码:

				
					
def get_first(items):
    res = filter(lambda x: x > 1, items)
    return res[0]
				
			

如果您使用的是Python 3,这里存在一个问题:APIfilter返回一个没有__getitem__方法的迭代器。这对于Python 2不是一个问题,因为相同的API返回一个列表。如果您正在将代码库迁移到Python 3,这是一个容易犯的错误。

SonarQube 9.9 LTS能够识别正在使用的Python版本,可以正确地提出有关此代码的问题。

支持Python 3.10和3.11

说到Python版本…新的SonarQube LTS意味着对一种语言的新版本提供支持,这要求SonarQube在问题出现时,更新代码的解析和理解方式。

在SonarQube 9.9 LTS中,增加了对Python 3.10和3.11的支持,解析了新的结构,如match语句的多种模式和except*语法。

这也意味着现有规则已经更新,也不会在这些结构上产生误报。

通过符号分析,增强漏洞检测

SonarSource早在2020年5月就收购了RIPS Technologies。

Sonar不仅收获了许多优秀的同事,而且得到了他们检测Python漏洞的先进技术。经过数月的工作,Sonar将Sonar和RIPS引擎的精华结合起来,为Python开发了一个全新的安全引擎。实际上Sonar完全替换了引擎,从所谓的定点分析转为了符号分析。

这意味着Python的安全引擎现在对于字段是敏感的,而且SonarQube 9.9 LTS的商业版本可以精确跟踪对象的哪个字段被恶意用户输入所污染(或未被污染)。对于您来说,这意味着更少的误报,因此您可以专注于修复真正的漏洞,而不是分析虚假的漏洞。

修复误报

在谈到误报问题时,不仅仅是安全规则得到了改进。Sonar投入了大量的精力来确保只提出真正的问题,我们的开发人员一直在审查Python规则提出的问题,以确保它们是准确而相关的。他们也会收到来自社区和商业支持渠道的报告。

除了通过更新分析引擎修复的所有误报之外,在SonarQube 9.9 LTS中,开发人员还解决了31个特定的误报问题!

全新的规则

回归基础

有时候,我们很容易过于关注令人印象深刻的新规则,但如果我们退一步,会发现还有一些不太复杂(但仍然重要)的规则需要实施!

SonarQube9.9 LTS引入了九个这样的规则,这些规则通常由其他代码检查工具提供,例如跟踪TODO标签并确保每个文件都包含版权/许可证标头。

编写干净且无错误的正则表达式

正则表达式(regex)是一系列符号和字符,用于表达在较长的文本中要搜索的字符串或模式。正则表达式是一个非常强大的工具,可以用来表达那些需要很多行代码才能捕捉到相同模式的条件。

虽然在当今的开发人员中,使用正则表达式很常见,但这并不意味着它很容易处理。编写正则表达式的时候,容易出错且耗时,而且很难将它记录下来。一旦编写完成,识别其中的错误也会很困难。

正则表达式不仅难以编写,而且由于其大小和复杂性,通常难以阅读和理解。

举个例子:

				
					
pattern = re.compile(
    r'[a-z\:\//\.]+(youtube|youtu)\.(com|be)/(watch\?v=|embed/|.+\?v=)?([^"&?\s]{11})?'
)
				
			

这个正则表达式的目的是匹配类似于https://www.youtu.be/watch?v=dQw4w9WgXcQ 和 https://www.youtube.com/embed/dQw4w9WgXcQ的URL。

在这个正则表达式中,第三个捕获组(watch\?v=|embed/|.+\?v=)?是为了适应URL格式的变化。您可能没有注意到这个捕获组中的第三个选择项。.+\?v=是多余的,因为它已经在第一个选择项watch\?v=中涵盖了,并且永远不会应用于/embed/URL。

所以,通过删除多余的选择组,这个正则表达式可以简化,使其更易读一些:

				
					
pattern = re.compile(
    r'[a-z\:\//\.]+(youtube|youtu)\.(com|be)/(watch\?v=|embed/)?([^"&?\s]{11})?'
)
				
			

对于开发人员来说,要自行发现这个问题可能会很困难,但对于SonarQube来说却非常简单。

在SonarQube 9.9 LTS中,开发人员引入了21条新规则,帮助Python开发人员编写高效、无误、安全且低复杂度的正则表达式!您可以在rules.sonarsource.com中找到所有与正则表达式相关的Python规则。

编写更好的单元测试

如果您正在使用unittest或pytest框架编写Python单元测试,那么您很幸运,因为SonarQube 9.9 LTS添加了专门用于分析测试代码的规则。

使用针对AWS CDK的规则构建安全的AWS基础架构

越来越多的开发人员使用AWS CDK来描述他们的AWS基础架构,将编程语言的灵活性与云基础设施的复杂性相结合。

CDK提供了预配置和经过测试的默认值,但模式和结构的创建仍然可能导致安全配置错误。

SonarQube 9.9 LTS提供了19条规则,用于在使用Python编写的AWS CDK代码上提醒安全热点,以确保您的IaC与源代码一样安全。

新的bug检测规则,通过符号执行跟踪数据流

SonarQube 9.9 LTS增加了新的功能,可以通过使用符号执行来检测高级的Python bug。

符号执行引擎的目的是访问所有可行的执行路径,甚至跨方法调用,以查找源代码中隐藏的棘手错误。

请参考以下代码段:

				
					
def hello(name):
  print("Hello " + name.upper())

def foo():
  name = None
  hello(name) # Triggers an AttributeError
				
			

在这个例子中,一个变量在一个函数中初始化为None,并且它的值在另一个函数中被使用。访问None属性会出发AttributeError错误。

下面是一个更复杂的例子:

				
					
def get_field(space, w_node, name, optional):
    w_obj = w_node.getdictvalue(space, name)
    if w_obj is None:
        if not optional:
            raise oefmt(space.w_TypeError,
                "required field \"%s\" missing from %T", name, w_node)
        w_obj = space.w_None
    return w_obj

@staticmethod
def from_object(space, w_node):
    w_n = get_field(space, w_node, 'n', False)
    w_lineno = get_field(space, w_node, 'lineno', False)
    w_col_offset = get_field(space, w_node, 'col_offset', False)
    _n = w_n
    if _n is None:
      raise_required_value(space, w_node, 'n') # Noncompliant
				
			

这里有很多事情要注意:

  • _n是w_n的别名;

  • 如果get_field调用的第四个参数为False,并且w_obj为None,则会引发异常,因此get_field将没有返回值;

  • 现在,get_field的唯一可能的返回值必须与None不同;

  • 因此,条件 _n is None总是为假,一些后续的代码将不会被执行。

类似的错误非常常见,而且很难自己发现。SonarQube 9.9 LTS现在会在这些情况下提出问题,共有九个规则可以检测类似的复杂错误。

这些规则在SonarQube商业版中可用。

只需一步:升级即可获得所有好处

SonarQube是由开发人员为开发人员打造的,目标就是帮助所有的开发人员编写干净的代码。

如果您还没有尝试过SonarQube 9.9 LTS,希望现在您有了更多的理由与团队一起准备升级。这是一个免费的版本升级,你只需在SonarQube Downloads点击几下即可获得LTS。

*鸣谢SonarSourcers的Alexandre Gigleux和Andrea Guarino对此篇文章的贡献。

章来源:https://www.sonarsource.com/blog/sonarqube-99-lts-python-developers/
 
 
需要更多的帮助开始升级?请联系SonarQube中国官方授权合作伙伴——创实 ,我们提供SonarQube产品的咨询、销售、实施、培训及技术支持服务。