<p>我也遇到了这个错误。当<code>.pyre_configuration</code>文件中未配置或错误配置Pyre<code>typeshed</code>目录时,会发生<code>AnalysisClassHierarchy.Untracked</code>错误</p>
<p>例如,如果已将Pyre安装到<code>/home/max/.local/lib/pyre_check/</code>,则<code>typeshed</code>目录为<code>/home/max/.local/lib/pyre_check/typeshed</code></p>
<p>为了立即重现此错误,我已将配置文件中的<code>typeshed</code>目录更改为不正确的目录。因此,我得到了以下错误:</p>
<pre><code>Analysis__ClassHierarchy.Untracked("typing.NamedTuple")
</code></pre>
<p>在更正路径后,Pyre能够发现漏洞。见下文。我还将给出一些实例,说明它是如何发现错误的,如何配置错误,以及需要对源代码进行哪些更改</p>
<p>如果您希望安装自定义存根(包含<code>.pyi</code>文件的目录),请将它们添加到<code>typeshed/third_party/2and3/</code>,或者,在我的情况下,将其添加到<code>/home/max/.local/lib/pyre_check/typeshed/third_party/2and3/</code></p>
<p>因此,您的<code>.pyre_configuration</code>文件将如下所示:</p>
<pre><code>{
"source_directories": ["/home/max/myproject"],
"taint_models_path": "/home/max/myproject/taint",
"typeshed": "/home/max/.local/lib/pyre_check/typeshed"
}
</code></pre>
<p>不要使用默认的Pyre污染目录。您已经指定了自己的污染目录,这是正确的。您已经在<code>.</code>中创建了它,但是最好为它创建一个包含多个子目录的新目录。请创建一个新的<code>taint</code>目录,如<code>/home/max/myproject/taint</code>,并将pyer安装文件夹中的taint.config文件复制到其中。另外,将<code>.pysa</code>文件从Pyre安装复制到此目录,但只复制您需要的文件,而不是所有文件。还将模型<code>.pisa</code>文件放在那里</p>
<p>让我举几个例子</p>
<p>例如,使用<a href="https://github.com/fportantier/vulpy" rel="nofollow noreferrer">https://github.com/fportantier/vulpy</a>Pyre时,发现了以下错误:</p>
<pre><code> {
"line": 20,
"column": 43,
"stop_line": 20,
"stop_column": 51,
"path": "mod_user.py",
"code": 5005,
"name": "SQL injection.",
"description":
"SQL injection. [5005]: Data from [UserControlled] source(s) may reach [SQL] sink(s)",
"inference": null,
"define": "mod_user.do_login"
},
{
"line": 20,
"column": 33,
"stop_line": 20,
"stop_column": 41,
"path": "mod_user.py",
"code": 5005,
"name": "SQL injection.",
"description":
"SQL injection. [5005]: Data from [UserControlled] source(s) may reach [SQL] sink(s)",
"inference": null,
"define": "mod_user.do_login"
},
{
"line": 52,
"column": 33,
"stop_line": 52,
"stop_column": 41,
"path": "mod_user.py",
"code": 5005,
"name": "SQL injection.",
"description":
"SQL injection. [5005]: Data from [UserControlled] source(s) may reach [SQL] sink(s)",
"inference": null,
"define": "mod_user.do_create"
},
{
"line": 52,
"column": 23,
"stop_line": 52,
"stop_column": 31,
"path": "mod_user.py",
"code": 5005,
"name": "SQL injection.",
"description":
"SQL injection. [5005]: Data from [UserControlled] source(s) may reach [SQL] sink(s)",
"inference": null,
"define": "mod_user.do_create"
},
{
"line": 80,
"column": 55,
"stop_line": 80,
"stop_column": 63,
"path": "mod_user.py",
"code": 5005,
"name": "SQL injection.",
"description":
"SQL injection. [5005]: Data from [UserControlled] source(s) may reach [SQL] sink(s)",
"inference": null,
"define": "mod_user.do_chpasswd"
},
{
"line": 39,
"column": 24,
"stop_line": 39,
"stop_column": 40,
"path": "mod_api.py",
"code": 6060,
"name": "User-controlled data flows into filesystem API (other)",
"description":
"User-controlled data flows into filesystem API (other) [6060]: Data from [UserControlled] source(s) may reach [FileSystem_Other] sink(s)",
"inference": null,
"define": "mod_api.do_key_create"
},
{
"line": 39,
"column": 24,
"stop_line": 39,
"stop_column": 40,
"path": "mod_api.py",
"code": 5011,
"name": "User data to filesystem operation (read/write)",
"description":
"User data to filesystem operation (read/write) [5011]: Data from [UserControlled] source(s) may reach [FileSystem_ReadWrite] sink(s)",
"inference": null,
"define": "mod_api.do_key_create"
}
]
</code></pre>
<p>对于<a href="https://github.com/lchsk/django-insecure" rel="nofollow noreferrer">https://github.com/lchsk/django-insecure</a>Pyre,发现了以下错误:</p>
<pre><code> {
"line": 16,
"column": 29,
"stop_line": 16,
"stop_column": 80,
"path": "security/views.py",
"code": 5005,
"name": "SQL injection.",
"description":
"SQL injection. [5005]: Data from [UserControlled] source(s) may reach [StringMayBeSQL] sink(s)",
"inference": null,
"define": "security.views.unsafe_users"
},
{
"line": 32,
"column": 14,
"stop_line": 32,
"stop_column": 22,
"path": "security/views.py",
"code": 5011,
"name": "User data to filesystem operation (read/write)",
"description":
"User data to filesystem operation (read/write) [5011]: Data from [UserControlled] source(s) may reach [FileSystem_ReadWrite] sink(s)",
"inference": null,
"define": "security.views.read_file"
},
{
"line": 41,
"column": 14,
"stop_line": 41,
"stop_column": 17,
"path": "security/views.py",
"code": 5001,
"name": "Possible shell injection",
"description":
"Possible shell injection [5001]: Data from [UserControlled] source(s) may reach [RemoteCodeExecution] sink(s)",
"inference": null,
"define": "security.views.copy_file"
},
{
"line": 72,
"column": 24,
"stop_line": 72,
"stop_column": 29,
"path": "security/views.py",
"code": 6066,
"name": "Unsafe deserialization may result in RCE",
"description":
"Unsafe deserialization may result in RCE [6066]: Data from [UserControlled] source(s) may reach [ExecDeserializationSink] sink(s)",
"inference": null,
"define": "security.views.admin_index"
}
]
</code></pre>
<p>在我的例子中<a href="https://github.com/lchsk/django-insecure" rel="nofollow noreferrer">https://github.com/lchsk/django-insecure</a>项目的存根目录包含以下文件:</p>
<pre><code>collection_propagation.pysa
django_sources_sinks.pysa
filesystem_other_sinks.pysa
filesystem_sinks.pysa
flask_sources_sinks.pysa
format_string_sinks.pysa
general.pysa
github-django-insecure-views.pysa
http_server.pysa
logging_sinks.pysa
protocols.pysa
rce_sinks.pysa
requests_api_sinks.pysa
sanitizers.pysa
skipped_overrides.pysa
sqlite3_sinks.pysa
taint.config
wsgi_ref.pysa
xss_sinks.pysa
</code></pre>
<p>github-django-unsecure-views.pysa文件的内容如下所示。需要定义视图函数的字符串参数也是污染源:</p>
<pre><code>def security.views.unsafe_users(request, user_id: TaintSource[UserControlled]): ...
def security.views.safe_users(request, user_id: TaintSource[UserControlled]): ...
def security.views.read_file(request, filename: TaintSource[UserControlled]): ...
def security.views.copy_file(request, filename: TaintSource[UserControlled]): ...
def security.views.admin_index(request): ...
def security.views.search(request): ...
def security.views.log(request): ...
</code></pre>
<p>我还编辑了views.py文件以指定请求参数的类型,如下所示:</p>
<pre><code>def unsafe_users(request: HttpRequest, user_id):
</code></pre>
<p>您不能仅仅为<code>views.py</code>创建<code>.pyi</code>文件来定义请求参数的类型,因为如果Pyre找到一个<code>.pyi</code>文件,它将跳过对该文件的扫描,因此您必须确保在代码中明确指定了该类型。否则,Pyre将无法跟踪从污染源到污染接收器的执行流</p>