
, . ? , — . .
? , ? , ? — , .
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.
: