NumberType > A (reflexive, transitive) subtype of java.lang.Number.
ParameterizedType 这个类,官方的一些解释。
A parameterized type is an instantiation of a generic type(泛型类), where each formal type variable has been replaced with a type argument.
For example, List<Number> is a parameterization of the generic type List<E>, where E is a type parameter.
1 2 3 4 5 6 7 8
override predicate isSanitizer(DataFlow::Node node) { node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType or node.getType() instanceof NumberType or exists(ParameterizedType pt| node.getType() = pt and pt.getTypeArgument(0) instanceof NumberType ) }
解决漏报
我们发现,如下的SQL注入并没有被CodeQL捕捉到。
1 2 3 4 5
public List<Student> getStudentWithOptional(Optional<String> username) { StringsqlWithOptional="select * from students where username like '%" + username.get() + "%'"; //String sql = "select * from students where username like ?"; return jdbcTemplate.query(sqlWithOptional, ROW_MAPPER); }
classStringValueextendsMethodAccess { StringValue(){ this.getCallee().getDeclaringType() instanceof TypeStringLib and this.getCallee().hasName("valueOf") } }
/** * A unit class for adding additional taint steps that are specific to server-side request forgery (SSRF) attacks. * * Extend this class to add additional taint steps to the SSRF query. */ classRequestForgeryAdditionalTaintStepextendsUnit { /** * Holds if the step from `pred` to `succ` should be considered a taint * step for server-side request forgery. */ abstract predicate propagatesTaint(DataFlow::Node pred, DataFlow::Node succ); }
privateclassDefaultRequestForgeryAdditionalTaintStepextendsRequestForgeryAdditionalTaintStep { override predicate propagatesTaint(DataFlow::Node pred, DataFlow::Node succ) { // propagate to a URI when its host is assigned to exists(UriCreation c | c.getHostArg() = pred.asExpr() | succ.asExpr() = c) or // propagate to a URL when its host is assigned to exists(UrlConstructorCall c | c.getHostArg() = pred.asExpr() | succ.asExpr() = c) or //处理String.valueOf(URL) exists(StringValue c | c.getArgument(0) = pred.asExpr() | succ.asExpr() = c) } }
privateclassTypePropertiesRequestForgeryAdditionalTaintStepextendsRequestForgeryAdditionalTaintStep { override predicate propagatesTaint(DataFlow::Node pred, DataFlow::Node succ) { exists(MethodAccess ma | // Properties props = new Properties(); // props.setProperty("jdbcUrl", tainted); // Propagate tainted value to the qualifier `props` ma.getMethod() instanceof PropertiesSetPropertyMethod and ma.getArgument(0).(CompileTimeConstantExpr).getStringValue() = "jdbcUrl" and pred.asExpr() = ma.getArgument(1) and succ.asExpr() = ma.getQualifier() ) } }
/** A data flow sink for server-side request forgery (SSRF) vulnerabilities. */ abstractclassRequestForgerySinkextendsDataFlow::Node { }
/** A sanitizer for request forgery vulnerabilities. */ abstractclassRequestForgerySanitizerextendsDataFlow::Node { }
privateclassPrimitiveSanitizerextendsRequestForgerySanitizer { PrimitiveSanitizer() { this.getType() instanceof PrimitiveType or this.getType() instanceof BoxedType or this.getType() instanceof NumberType } }
privateclassHostnameSanitizingPrefixextendsInterestingPrefix { int offset;
HostnameSanitizingPrefix() { // Matches strings that look like when prepended to untrusted input, they will restrict // the host or entity addressed: for example, anything containing `?` or `#`, or a slash that // doesn't appear to be a protocol specifier (e.g. `http://` is not sanitizing), or specifically // the string "/". exists(this.getStringValue().regexpFind("([?#]|[^?#:/\\\\][/\\\\])|^/$", 0, offset)) }
override intgetOffset() { result = offset } }
/** * A value that is the result of prepending a string that prevents any value from controlling the * host of a URL. */ privateclassHostnameSantizerextendsRequestForgerySanitizer { HostnameSantizer() { this.asExpr() = any(HostnameSanitizingPrefix hsp).getAnAppendedExpression() } }
classStringValueextendsMethodAccess { StringValue(){ this.getCallee().getDeclaringType() instanceof TypeStringLib and this.getCallee().hasName("valueOf") } }
privateclassMyRequestForgeryAdditionalTaintStepextendsRequestForgeryAdditionalTaintStep { override predicate propagatesTaint(DataFlow::Node pred, DataFlow::Node succ) { // propagate to a URI when its host is assigned to exists(UriCreation c | c.getHostArg() = pred.asExpr() | succ.asExpr() = c) or // propagate to a URL when its host is assigned to exists(UrlConstructorCall c | c.getHostArg() = pred.asExpr() | succ.asExpr() = c) or //处理String.valueOf(URL) exists(StringValue c | c.getArgument(0) = pred.asExpr() | succ.asExpr() = c) } }
classSSRFVulConfigextendsTaintTracking::Configuration { SSRFVulConfig() { this = "first_modifySSRF" }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource and // Exclude results of remote HTTP requests: fetching something else based on that result // is no worse than following a redirect returned by the remote server, and typically // we're requesting a resource via https which we trust to only send us to safe URLs. not source.asExpr().(MethodAccess).getCallee() instanceof UrlConnectionGetInputStreamMethod }
MethodAccess url(MethodAccess ma,DataFlow::Node node){ exists( MethodAccess mc | mc = ma.getAChildExpr()| if mc.getCallee().hasName("url") and mc.getArgument(0) = node.asExpr() thenresult= mc else result = url(mc,node) ) }
MethodAccess m(DataFlow::Node node){ exists( MethodAccess ma | ma.getCallee().hasName("build") and ma.getCallee().getDeclaringType().hasName("Builder") |result = url(ma,node) ) }
classStringValueextendsMethodAccess { StringValue(){ this.getCallee().getDeclaringType() instanceof TypeStringLib and this.getCallee().hasName("valueOf") } }
privateclassMyRequestForgeryAdditionalTaintStepextendsRequestForgeryAdditionalTaintStep { override predicate propagatesTaint(DataFlow::Node pred, DataFlow::Node succ) { // propagate to a URI when its host is assigned to exists(UriCreation c | c.getHostArg() = pred.asExpr() | succ.asExpr() = c) or // propagate to a URL when its host is assigned to exists(UrlConstructorCall c | c.getHostArg() = pred.asExpr() | succ.asExpr() = c) or //处理String.valueOf(URL) exists(StringValue c | c.getArgument(0) = pred.asExpr() | succ.asExpr() = c) } }
classSSRFVulConfigextendsTaintTracking::Configuration { SSRFVulConfig() { this = "first_modifySSRF" }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource and // Exclude results of remote HTTP requests: fetching something else based on that result // is no worse than following a redirect returned by the remote server, and typically // we're requesting a resource via https which we trust to only send us to safe URLs. not source.asExpr().(MethodAccess).getCallee() instanceof UrlConnectionGetInputStreamMethod }