
, . ? , β . .
? , ? , ? β , .
Java, -, SonarQube Find Security Bugs, .
Heisenbug: β , β .
:
, OWASP ZAP Accunetix.
, :
, .
?
.
, .
( ) . β Lint, 1979 , . Lint β , grep.
, :

, : API, , .
β . , , , .
, , . .
(, β SQL β) , .
?
-, (AST). AST . , .
Java- - :

, AST:
β β, equals(), hashCode()β;
β β password secretβ.
-, (Control Flow Graph, CFG). CFG , .

. CFG . CFG β , , , taint analysis.
, , , , . cross-site scripting (XSS) :
String foo = request.getParameter("foo");
response.getWriter().write(foo);
JavaScript .
? Β«fooΒ», . . , foo , html , HTML-.
Taint analysis , : , cross site scripting, β , .
? , , . tainted, Β«taintΒ» β «», «». foo tainted, getParameter , .

, ? . , , , . , API β β,. , - .
, , . β . XSS; SQL- SQL-. .
tainted: sink, «», «».

tainted sink, .
, html foo, . β , . tainted sink. , tainted sink , , .

, , .
, , . , . web- .
β reflection. Reflection Dependency Injection- , , , taint analysis.

, . C , bar(). , bar() - sink, , .
,
web-, β . JSP, Java- , β HTML- . .

, taint analysis, , .
Java : , . . :
- : , . Java, JavaScript TypeScript, , Android-.
- : taint analysis. , , , .
- , , , Β« Β» , .
- , Β« Β» : , , , . , collaboration .
- , , . , .
, . , OWASP (Open Web Application Security Project) 2016- (https://github.com/OWASP/benchmark). OWASP β Java . :

, , . β , . , β .
( ) ( ) . .
, , , . - , . , .
OWASP Find Security Bugs , , , . .
? , , .
Find Security Bugs. Java, FindBugs, SpotBugs. Find Security Bugs , , Android.
Java, taint analysis.
, , , SonarQube. Find Security Bugs SonarQube, .
. β Spring Thymeleaf.
, Find Security Bugs , . GitHub.
1
β XSS, HTML-.
@ExceptionHandler({IllegalArgumentException.class})
    public void oops(HttpServletRequest request, HttpServletResponse response) {
        String originalURL = request.getRequestURL() + "?" +
                URLDecoder.decode(request.getQueryString());
        
            PrintWriter writer = response.getWriter();
            writer.write("<h1>Error procesing page " + originalURL + "</h1>");
            writer.flush();
        
}
, .
originalURL tainted, request.getQueryString() HttpServletRequest .
writer.write() sink, ββ .
, , , :

2
@GetMapping("/photo")
    public String photo(@RequestParam("id") long id, Model model) {
        Photo photo = photoRepository.findOne(id);
        
        m.addAttribute("photo", photo)
        
        return "/photo";
}
<div th:each="comment : ${photo.comments}">
    <p th:utext="${comment.text}"></p>
</div>
Spring endpoint, . . ?
. photoRepository.findOne(id) , , taint. (th:utext ). HTML-, HTML.
Find Security Bugs .
.
: , - ( Β«ph:utextΒ») β . , , - .
: .
, addAttribute() sink, taint sink .
Find Security Bugs . . Find Security Bugs c :

sink β addAttribute(). , , , , , , , ββ .
, Find Security Bugs , , Java-.
3
@GetMapping("/photo")
public String photo(@RequestParam("id") long id, Model model) {
    Photo photo = photoRepository.findOne(id);
    
    model.addAttribute("photo", photo);
    return "/photo";
}
Spring endpoint, . ?
! , . IDOR β Insecure Direct Object Reference.
:
@GetMapping("/photo")
public String photo(@RequestParam("id") long id, Model model) {
        Photo photo = photoRepository.findOne(id);
        
        User currentUser = getCurrentUser = getCurrentUser();
        if (!canAccess(currentUser, author)) {
            return "/error/302";
        }
        model.addAttribute("user", author);
        model.addAttribute("photo", photo);
        return "/photo";
}
: ? , , - , . , .
, , .
, Β«, , , Spring endpoint- , canAccess(). , Β».
. Find Security Bugs β Java.
import edu.umd.cs.findbugs.Detector;
public class IdorDetector implements Detector {
    @Override
    public void vistClassContext(ClassContext classContext) {
    }
    @Override
    public void report() {
    }
}
Find Security Bugs Detector. , , .
, : visitClassContext(), , report(), , .
? , Spring endpoint- , , :
public void visitClassContext(ClassContext classContext) {
List<Method> endpoints = findEndpoints(classContext);
for (Method m : endpoint) {
    checkCanAccessCalled(classContext, m);
}
Spring endpoint-? Spring? , .
    REQUEST_MAPPING_ANNOTATION_TYPES = Arrays.asList(
        "Lorg/springframework/web/bind/annotation/GetMapping;",
        "Lorg/springframework/web/bind/annotation/PostMapping;",
        
private List<Method> findEndpoints(JavaClass javaClass) {
     
    for (Method m : javaClass.getMethods()) {
         for (AnnotationEntry ae : m.getAnnotationEntries())) {
             if (REQUEST_MAPPING_ANNOTATION_TYPES
                       .contains(ae.getAnnotationType())) {
                 endpoints.add(m);
             }
       }
}
, Spring ( , ). , , . , .
. ? control flow graph, .
private void checkCanAccessCalled(ClassContext classContext, Method m) {
    
    CFG cfg = classContext.getCFG(m);
    for (Iterator<Location> i = cfg.locationIterator(); i.hasNext(); ) {
        Instruction inst = i.next().getHandle().getInstruction();
        if (inst instanceof INVOKESPECIAL)  {
            if (CAN_ACCESS_METHOD_NAME.equals(invoke.getMethodName(cpg)) &&
                className.equals(invoke.getClassName(cpgΒ» {
                     found = true;
            }
         }
}
CFG endpoint- . , .
if (!found) {
    bugReporter.reportBug(
        new BugInstance(this, "IDOR", Priorities.NORMAL_PRIORITY)
            .addClass(javaClass)
            .addMethod(javaClass, method));
}
endpoint, , .
Find Security Bugs , , .
, . , .
?
, , , - .
, :
:
public abstract class BaseController {
    protected boolean canAccess() {
        return false;
    }
}
public class Controller extends BaseController {
     @GetMapping("foo")
     public String foo() {
     
         canAccess()
     
}
:
public class Controller {
    private boolean canAccess() {
        
    }
    private boolean canAccessEx() {
        canAccess()
        
     }
    @GetMapping("foo")
    public String foo() {
        
        canAccessEx()
        
    }
}
:
public class Controller {
    private boolean canAccess() {
        
    }
    private boolean canAccessEx() {
        if (x) {
            canAccess()
        } else {
            
        }
        
     }
    @GetMapping("foo")
    public String foo() {
        
        canAccessEx()
        
    }
}
, , , :).
, , , .
, β β , , , .
Find Security Bugs , , Java.
: