diff --git a/go/ql/lib/semmle/go/Expr.qll b/go/ql/lib/semmle/go/Expr.qll index b1e1a1697843d..ce6c7d4cf1f6b 100644 --- a/go/ql/lib/semmle/go/Expr.qll +++ b/go/ql/lib/semmle/go/Expr.qll @@ -2098,6 +2098,7 @@ class LabelName extends Name { * may be identified as such, so not all type expressions can be determined by * a bottom-up analysis. In such cases, `isTypeExprTopDown` below is useful. */ +pragma[nomagic] private predicate isTypeExprBottomUp(Expr e) { e instanceof TypeName or diff --git a/go/ql/lib/semmle/go/controlflow/IR.qll b/go/ql/lib/semmle/go/controlflow/IR.qll index d337f526cdef0..59060e4065583 100644 --- a/go/ql/lib/semmle/go/controlflow/IR.qll +++ b/go/ql/lib/semmle/go/controlflow/IR.qll @@ -501,10 +501,11 @@ module IR { override StructLit lit; /** Gets the name of the initialized field. */ + pragma[nomagic] string getFieldName() { if elt instanceof KeyValueExpr then result = elt.(KeyValueExpr).getKey().(Ident).getName() - else lit.getStructType().hasOwnField(i, result, _, _) + else pragma[only_bind_out](lit.getStructType()).hasOwnField(i, result, _, _) } /** Gets the initialized field. */ diff --git a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll index 1b521d89d98da..281e283890adb 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll @@ -190,6 +190,7 @@ predicate sliceStep(DataFlow::Node pred, DataFlow::Node succ) { */ abstract class FunctionModel extends Function { /** Holds if taint propagates through this function from `input` to `output`. */ + pragma[nomagic] abstract predicate hasTaintFlow(FunctionInput input, FunctionOutput output); /** Gets an input node for this model for the call `c`. */ diff --git a/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll b/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll index 304bc004e0385..720f7ba44fd09 100644 --- a/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll +++ b/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll @@ -75,6 +75,15 @@ module OpenUrlRedirect { } } + bindingset[var, w] + pragma[inline_late] + private predicate useIsDominated( + SsaWithFields var, Write w, DataFlow::ReadNode sanitizedRead + ) { + w.dominatesNode(sanitizedRead.asInstruction()) and + sanitizedRead = var.getAUse() + } + /** * An access to a variable that is preceded by an assignment to its `Path` field. * @@ -83,13 +92,10 @@ module OpenUrlRedirect { */ class PathAssignmentBarrier extends Barrier, Read { PathAssignmentBarrier() { - exists(Write w, Field f, SsaWithFields var | - f.getName() = "Path" and + exists(Write w, SsaWithFields var | hasHostnameSanitizingSubstring(w.getRhs()) and - this = var.getAUse() - | - w.writesField(var.getAUse(), f, _) and - w.dominatesNode(insn) + w.writesField(var.getAUse(), any(Field f | f.getName() = "Path"), _) and + useIsDominated(var, w, this) ) } }