idea代码分支显示异常

img

为什么idea代码分支都变成了两份了呢,、?有很多分支是我没打开过的,所以应该不会存在我本地。

下面是 远端仓库分支, 不影响; 上面才是你本地仓库分支
至于两个不同的远程分支,说明你有两个远端呗,一个是 原项目的,一个是 你 fork到你Git用户下的

  • 这个问题的回答你可以参考下: https://ask.csdn.net/questions/7486044
  • 除此之外, 这篇博客: 从0到1实现一个IDEA代码审计插件中的 在idea中进行静态代码审计 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 首先解决第一个问题,用SDK的哪个接口来进行代码审计

    虽然intellij的文档写的很烂,但是还好他在github上放了一些代码示例,其中inspection_basics模块以及comparing_references_inspection模块(尤其是这个模块)给了我们提示,通过这两个模块我知道了在intellij platform上进行自动化代码检查需要用到的功能被称作inspection,那么在这个基础上我们就可以进一步查询inspection的使用文档了

    既然写到这里了,那为了让屏幕前的大家更好地了解inspection的使用,我干脆来简单的给大家讲解下comparing_references_inspection这个模块里的一些知识点吧,这个简单的demo主要的功能就是检测java代码中有没有错误地进行引用类型的比较,比如对于String类型,错误的使用!=或者==而不是.equals()方法

    如果发现有错误的用法插件会将对应的代码高亮,并且提供一键修复功能,除此之外这个demo里还给我们展示了怎么编写测试用例

    这简直就是我们的SAST插件想要做的事情——发现漏洞对漏洞代码进行高亮,如果可以,提供一键修复功能

    当然,除此之外,我们还希望发现漏洞代码及时上报到soc方便后续人工确认

    首先,我们要对java做inspection,需要在build.gradle中的intellij配置好java的plugin


    这个配好过后,我们就可以实现一个自己的inspection类啦,这个类需要继承AbstractBaseJavaLocalInspectionTool,然后我们自己实现的inspection类大体架构如下:

    public class ComparingReferencesInspection extends AbstractBaseJavaLocalInspectionTool{
    	public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly){
    			return new JavaElementVisitor() {
    				public void visitBinaryExpression(PsiBinaryExpression expression) {
    					doSomething...
    					if(condition){
    						holder.registerProblem(expression, "问题描述字符串")
    					}
    				}
    				public void visitXXXXX(){
    					xxxxx
    				}
    			}
    	}	
    }
    

    其中最重要的方法就是visitXXX方法,上面代码中举了visitBinaryExpression这么个方法,这个方法有什么用呢?

    当插件跑起来过后,这个方法就会检查代码中的BinaryExpression,你可能会问BinaryExpression是啥?

    intellij platform中的BinaryExpression其实代表的就是代码中的二项式,例如:

    "select * from table where id=" + id
    1+2
    1-2
    

    idea中用BinaryExpression封装了上面这种表达式,代码中的每一个二项式都会作为参数传入visitBinaryExpression方法,然后你可以在这个方法里处理这些二项式,比如判断这个二项式是不是潜在的sql注入语句(例如上面第一条二项式那样)

    除了visitBinaryExpression方法,intellij还提供了很多种visit方法,这些方法都是为了方便我们进行代码inspection的,例如visitMethodCallExpression是可以访问到所有的方法调用语句,visitNewExpression可以访问到所有的类似new Xxx()语句

    有了上面的基础知识,我们尝试着想一想怎么实现一个简单的检测sql注入的插件,我们不考虑特别复杂的sql注入,我们就考虑怎么检测sql语句拼接就行,例如下面这些句子

    public test(String id){
    	String id2 = '2';
    	String sql1 = "select * from table where id="+id;
    	String sql2 = "select * from table where id=" + id2;
    }
    

    上面两个sql语句都是二项表达式,所以我们可以用visitBinaryExpression拿到他们,拿到他们过后,我们怎么确定他是一个sql语句呢?毕竟这两个二项表达式是被封装到binaryExpression这个对象里的,怎么通过这个对象判断他是一个sql语句这是一个需要我们解决的问题

    这里我们借用一个插件「PsiViewer」,这个插件可以查看当前源码文件的AST树,看图

    上图左侧是我们的源代码,右侧是psiviewer插件窗口,当我们在把光标停留在源码某处时,psiviewer窗口会对应展示我们正处在AST树的哪个位置,反过来,当我们在psiviewer窗口中选中ast树某处时,对应的源码也会高亮出来

    这个插件可以让我们对intellij platform解析出来的AST树有更加清晰的认知

    现在,让我们回到最初的问题,在拿到了BinaryExpression后,我们要怎么判断它到底是不是一个sql语句呢?

    其实

    如果你观察仔细,你可以从上图中发现psiviewer窗口的下半部分展示了当前PsiBinaryExpression对象所有的属性以及其值

    可以看到前两个属性分别是LOperand(左操作数)以及ROperand(右操作数),除此之外还有个属性是operationTokenType,上面截图没有截到,这个属性指明了当前二项式的操作符是啥

    常见的操作符有+-

    所以,到目前为止怎么判断一个二项式是不是一个sql语句应该很明显了吧:

    先判断当前二项式的操作符是不是加号,如果是加号,拿到左操作数以及右操作数,解析出他们的值,然后把他们的值拼接起来,最后用正则判断是不是一个sql语句

    当然,这只是很理想的一个状况,如果你要检测sql注入,还需要考虑很多种情况,举一部分🌰:

    public test(String id){
    	String id2 = '2';
    	String sql1 = "select * from table where id="
    	String sql2 = sql1 + id;
    	String sql1 += id;
    	String sql3 = "select * from table where id=" + id2;
    	String sql4 = "select * from" + "table" + id2;
    	String sql5 = "select * from table where id=" + getId();
    	String sql6 = "select * from table where id=%s";
    	sql6.format(id);
    }
    

    ok,写到这里好像就已经差不多了,要是再细节一点,就是把代码直接贴出来,然后一句句注释了

    然后下面是我写的demo插件运行的效果:

    代码已上传github:https://github.com/Maskhe/AxinSAST

    代码很烂,希望大家别喷我,ball ball 大家

    公众号:一个安全研究员,来找我玩!