diff --git a/checker-qual/src/main/java/org/checkerframework/checker/confidential/qual/BottomConfidential.java b/checker-qual/src/main/java/org/checkerframework/checker/confidential/qual/BottomConfidential.java new file mode 100644 index 00000000000..79968aa803a --- /dev/null +++ b/checker-qual/src/main/java/org/checkerframework/checker/confidential/qual/BottomConfidential.java @@ -0,0 +1,27 @@ +package org.checkerframework.checker.confidential.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.DefaultFor; +import org.checkerframework.framework.qual.InvisibleQualifier; +import org.checkerframework.framework.qual.SubtypeOf; +import org.checkerframework.framework.qual.TargetLocations; +import org.checkerframework.framework.qual.TypeUseLocation; + +/** + * The bottom type in the Confidential type system. Programmers should rarely write this type. + * + * @checker_framework.manual #confidential-checker Confidential Checker + * @checker_framework.manual #bottom-type the bottom type + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND}) +@InvisibleQualifier +@SubtypeOf({Confidential.class, NonConfidential.class}) +@DefaultFor(value = {TypeUseLocation.LOWER_BOUND}) +public @interface BottomConfidential {} diff --git a/checker-qual/src/main/java/org/checkerframework/checker/confidential/qual/Confidential.java b/checker-qual/src/main/java/org/checkerframework/checker/confidential/qual/Confidential.java new file mode 100644 index 00000000000..cbbaede733d --- /dev/null +++ b/checker-qual/src/main/java/org/checkerframework/checker/confidential/qual/Confidential.java @@ -0,0 +1,26 @@ +package org.checkerframework.checker.confidential.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.SubtypeOf; + +/** + * Denotes a value that will not be exposed to end users or a sink that will not be able to be + * accessed by end users. + * + *

A Confidential value may contain sensitive, private, or otherwise privileged-access + * information. Examples include passwords, PII (personally identifiable information), and private + * keys. + * + * @see NonConfidential + * @see org.checkerframework.checker.confidential.ConfidentialChecker + * @checker_framework.manual #confidential-checker Confidential Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf(UnknownConfidential.class) +public @interface Confidential {} diff --git a/checker-qual/src/main/java/org/checkerframework/checker/confidential/qual/NonConfidential.java b/checker-qual/src/main/java/org/checkerframework/checker/confidential/qual/NonConfidential.java new file mode 100644 index 00000000000..76f9997cc96 --- /dev/null +++ b/checker-qual/src/main/java/org/checkerframework/checker/confidential/qual/NonConfidential.java @@ -0,0 +1,29 @@ +package org.checkerframework.checker.confidential.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.DefaultFor; +import org.checkerframework.framework.qual.DefaultQualifierInHierarchy; +import org.checkerframework.framework.qual.LiteralKind; +import org.checkerframework.framework.qual.QualifierForLiterals; +import org.checkerframework.framework.qual.SubtypeOf; +import org.checkerframework.framework.qual.TypeUseLocation; + +/** + * Denotes a value that may be exposed to end users, or a location that may be accessed by end + * users. NonConfidential locations will never contain sensitive, private, or otherwise + * privileged-access information. + * + * @checker_framework.manual #confidential-checker Confidential Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf(UnknownConfidential.class) +@QualifierForLiterals({LiteralKind.STRING, LiteralKind.PRIMITIVE}) +@DefaultQualifierInHierarchy +@DefaultFor(value = {TypeUseLocation.LOCAL_VARIABLE, TypeUseLocation.UPPER_BOUND}) +public @interface NonConfidential {} diff --git a/checker-qual/src/main/java/org/checkerframework/checker/confidential/qual/PolyConfidential.java b/checker-qual/src/main/java/org/checkerframework/checker/confidential/qual/PolyConfidential.java new file mode 100644 index 00000000000..e0bc07155f3 --- /dev/null +++ b/checker-qual/src/main/java/org/checkerframework/checker/confidential/qual/PolyConfidential.java @@ -0,0 +1,20 @@ +package org.checkerframework.checker.confidential.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.PolymorphicQualifier; + +/** + * A polymorphic qualifier for the Confidential type system. + * + * @checker_framework.manual #confidential-checker Confidential Checker + * @checker_framework.manual #qualifier-polymorphism Qualifier polymorphism + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@PolymorphicQualifier(UnknownConfidential.class) +public @interface PolyConfidential {} diff --git a/checker-qual/src/main/java/org/checkerframework/checker/confidential/qual/UnknownConfidential.java b/checker-qual/src/main/java/org/checkerframework/checker/confidential/qual/UnknownConfidential.java new file mode 100644 index 00000000000..f0d356c915a --- /dev/null +++ b/checker-qual/src/main/java/org/checkerframework/checker/confidential/qual/UnknownConfidential.java @@ -0,0 +1,25 @@ +package org.checkerframework.checker.confidential.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.InvisibleQualifier; +import org.checkerframework.framework.qual.SubtypeOf; +import org.checkerframework.framework.qual.TargetLocations; +import org.checkerframework.framework.qual.TypeUseLocation; + +/** + * Represents a value that might or might not be confidential. This is the top of the Confidential + * qualifier hierarchy. + * + * @checker_framework.manual #confidential-checker Confidential Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND}) +@InvisibleQualifier +@SubtypeOf({}) +public @interface UnknownConfidential {} diff --git a/checker/src/main/java/org/checkerframework/checker/confidential/AbstractAuthenticationTargetUrlRequestHandler.astub b/checker/src/main/java/org/checkerframework/checker/confidential/AbstractAuthenticationTargetUrlRequestHandler.astub new file mode 100644 index 00000000000..031a3e20db3 --- /dev/null +++ b/checker/src/main/java/org/checkerframework/checker/confidential/AbstractAuthenticationTargetUrlRequestHandler.astub @@ -0,0 +1,27 @@ +package org.springframework.security.web.authentication; + +import java.io.IOException; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.core.log.LogMessage; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.DefaultRedirectStrategy; +import org.springframework.security.web.RedirectStrategy; +import org.springframework.security.web.util.UrlUtils; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +import org.checkerframework.checker.confidential.qual.UnknownConfidential; + +public abstract class AbstractAuthenticationTargetUrlRequestHandler { + + protected void handle(HttpServletRequest request, HttpServletResponse response, @UnknownConfidential Authentication authentication); + + protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response, + @UnknownConfidential Authentication authentication); +} diff --git a/checker/src/main/java/org/checkerframework/checker/confidential/AlertDialog.astub b/checker/src/main/java/org/checkerframework/checker/confidential/AlertDialog.astub new file mode 100644 index 00000000000..78e48b6f71a --- /dev/null +++ b/checker/src/main/java/org/checkerframework/checker/confidential/AlertDialog.astub @@ -0,0 +1,131 @@ +package android.app; + +import android.annotation.ArrayRes; +import android.annotation.AttrRes; +import android.annotation.DrawableRes; +import android.annotation.StringRes; +import android.annotation.StyleRes; +import android.compat.annotation.UnsupportedAppUsage; +import android.content.Context; +import android.content.DialogInterface; +import android.content.res.ResourceId; +import android.content.res.Resources; +import android.database.Cursor; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.os.Message; +import android.text.Layout; +import android.text.method.MovementMethod; +import android.util.TypedValue; +import android.view.ContextThemeWrapper; +import android.view.KeyEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.Button; +import android.widget.ListAdapter; +import android.widget.ListView; +import com.android.internal.R; +import com.android.internal.app.AlertController; + +import org.checkerframework.checker.confidential.qual.*; + +public class AlertDialog extends Dialog implements DialogInterface { + + protected AlertDialog(@UnknownConfidential Context context); + + protected AlertDialog(@UnknownConfidential Context context, boolean cancelable, + @UnknownConfidential OnCancelListener cancelListener); + + protected AlertDialog(@UnknownConfidential Context context, @StyleRes int themeResId); + + AlertDialog(@UnknownConfidential Context context, @StyleRes int themeResId, + boolean createContextThemeWrapper); + + static @StyleRes int resolveDialogTheme(@UnknownConfidential Context context, + @StyleRes int themeResId); + + public static class Builder { + public @UnknownConfidential Builder(@UnknownConfidential Context context); + + public @UnknownConfidential Builder(@UnknownConfidential Context context, int themeResId); + + public @UnknownConfidential Context getContext(); + + public @UnknownConfidential Builder setTitle(@StringRes int titleId); + + public @UnknownConfidential Builder setTitle(CharSequence title); + + public @UnknownConfidential Builder setCustomTitle(View customTitleView); + + public @UnknownConfidential Builder setMessage(@StringRes int messageId); + + public @UnknownConfidential Builder setMessage(CharSequence message); + + public @UnknownConfidential Builder setIcon(@DrawableRes int iconId); + + public @UnknownConfidential Builder setIcon(Drawable icon); + + public @UnknownConfidential Builder setIconAttribute(@AttrRes int attrId); + + public @UnknownConfidential Builder setPositiveButton(@StringRes int textId, final @UnknownConfidential OnClickListener listener); + + public @UnknownConfidential Builder setPositiveButton(CharSequence text, final @UnknownConfidential OnClickListener listener); + + public @UnknownConfidential Builder setNegativeButton(@StringRes int textId, final @UnknownConfidential OnClickListener listener); + + public @UnknownConfidential Builder setNegativeButton(CharSequence text, final @UnknownConfidential OnClickListener listener); + + public @UnknownConfidential Builder setNeutralButton(@StringRes int textId, final @UnknownConfidential OnClickListener listener); + + public @UnknownConfidential Builder setNeutralButton(CharSequence text, final @UnknownConfidential OnClickListener listener); + + public @UnknownConfidential Builder setCancelable(boolean cancelable); + + public @UnknownConfidential Builder setOnCancelListener(@UnknownConfidential OnCancelListener onCancelListener); + + public @UnknownConfidential Builder setOnDismissListener(@UnknownConfidential OnDismissListener onDismissListener); + + public @UnknownConfidential Builder setOnKeyListener(@UnknownConfidential OnKeyListener onKeyListener); + + public @UnknownConfidential Builder setItems(@ArrayRes int itemsId, final @UnknownConfidential OnClickListener listener); + + public @UnknownConfidential Builder setItems(CharSequence[] items, final @UnknownConfidential OnClickListener listener); + + public @UnknownConfidential Builder setAdapter(final @UnknownConfidential ListAdapter adapter, final @UnknownConfidential OnClickListener listener); + + public @UnknownConfidential Builder setCursor(final @UnknownConfidential Cursor cursor, final @UnknownConfidential OnClickListener listener, + String labelColumn); + + public @UnknownConfidential Builder setMultiChoiceItems(@ArrayRes int itemsId, boolean[] checkedItems, + final @UnknownConfidential OnMultiChoiceClickListener listener); + + public @UnknownConfidential Builder setMultiChoiceItems(CharSequence[] items, boolean[] checkedItems, + final @UnknownConfidential OnMultiChoiceClickListener listener); + + public @UnknownConfidential Builder setMultiChoiceItems(@UnknownConfidential Cursor cursor, String isCheckedColumn, String labelColumn, + final @UnknownConfidential OnMultiChoiceClickListener listener); + + public @UnknownConfidential Builder setSingleChoiceItems(@ArrayRes int itemsId, int checkedItem, + final @UnknownConfidential OnClickListener listener); + + public @UnknownConfidential Builder setSingleChoiceItems(@UnknownConfidential Cursor cursor, int checkedItem, String labelColumn, + final @UnknownConfidential OnClickListener listener); + + public @UnknownConfidential Builder setSingleChoiceItems(CharSequence[] items, int checkedItem, final @UnknownConfidential OnClickListener listener); + + public @UnknownConfidential Builder setSingleChoiceItems(@UnknownConfidential ListAdapter adapter, int checkedItem, final @UnknownConfidential OnClickListener listener); + + public @UnknownConfidential Builder setOnItemSelectedListener(final @UnknownConfidential AdapterView.OnItemSelectedListener listener); + + public @UnknownConfidential Builder setView(int layoutResId); + + public @UnknownConfidential Builder setView(View view); + + @UnsupportedAppUsage + public @UnknownConfidential Builder setRecycleOnMeasureEnabled(boolean enabled); + + public @UnknownConfidential AlertDialog create(); + + public @UnknownConfidential AlertDialog show(); + } +} diff --git a/checker/src/main/java/org/checkerframework/checker/confidential/AndroidLog.astub b/checker/src/main/java/org/checkerframework/checker/confidential/AndroidLog.astub new file mode 100644 index 00000000000..e95219dd955 --- /dev/null +++ b/checker/src/main/java/org/checkerframework/checker/confidential/AndroidLog.astub @@ -0,0 +1,50 @@ +package android.util; +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.compat.annotation.UnsupportedAppUsage; +import android.os.DeadSystemException; +import com.android.internal.os.RuntimeInit; +import com.android.internal.util.FastPrintWriter; +import com.android.internal.util.LineBreakBufferedWriter; +import dalvik.annotation.optimization.FastNative; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.Writer; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.net.UnknownHostException; + +import org.checkerframework.checker.confidential.qual.*; + +public final class Log { + + public static int d(@Nullable String tag, @Nullable String msg, @Nullable @UnknownConfidential Throwable tr); + + public static int w(@Nullable String tag, @Nullable String msg, @Nullable @UnknownConfidential Throwable tr); + + public static int w(@Nullable String tag, @Nullable @UnknownConfidential Throwable tr); + + public static int v(@Nullable String tag, @Nullable String msg, @Nullable @UnknownConfidential Throwable tr); + + public static int i(@Nullable String tag, @Nullable String msg, @Nullable @UnknownConfidential Throwable tr); + + public static int e(@Nullable String tag, @Nullable String msg, @Nullable @UnknownConfidential Throwable tr); + + public static int wtf(@Nullable String tag, @NonNull @UnknownConfidential Throwable tr); + + public static int wtf(@Nullable String tag, @Nullable String msg, @Nullable @UnknownConfidential Throwable tr); + + static int wtf(int logId, @Nullable String tag, @Nullable String msg, @Nullable @UnknownConfidential Throwable tr, + boolean localStack, boolean system); + + @NonNull + public static @UnknownConfidential TerribleFailureHandler setWtfHandler(@NonNull @UnknownConfidential TerribleFailureHandler handler); + + @NonNull + public static String getStackTraceString(@Nullable @UnknownConfidential Throwable tr); + + public static int printlns(int bufID, int priority, @Nullable String tag, @NonNull String msg, + @Nullable @UnknownConfidential Throwable tr); +} diff --git a/checker/src/main/java/org/checkerframework/checker/confidential/ApacheLog.astub b/checker/src/main/java/org/checkerframework/checker/confidential/ApacheLog.astub new file mode 100644 index 00000000000..ab6f380348e --- /dev/null +++ b/checker/src/main/java/org/checkerframework/checker/confidential/ApacheLog.astub @@ -0,0 +1,18 @@ +package org.apache.commons.logging; + +import org.checkerframework.checker.confidential.qual.UnknownConfidential; + +public interface Log { + + void debug(Object var1, @UnknownConfidential Throwable var2); + + void error(Object var1, @UnknownConfidential Throwable var2); + + void fatal(Object var1, @UnknownConfidential Throwable var2); + + void info(Object var1, @UnknownConfidential Throwable var2); + + void trace(Object var1, @UnknownConfidential Throwable var2); + + void warn(Object var1, @UnknownConfidential Throwable var2); +} diff --git a/checker/src/main/java/org/checkerframework/checker/confidential/Authentication.astub b/checker/src/main/java/org/checkerframework/checker/confidential/Authentication.astub new file mode 100644 index 00000000000..c09af83eb54 --- /dev/null +++ b/checker/src/main/java/org/checkerframework/checker/confidential/Authentication.astub @@ -0,0 +1,21 @@ +package org.springframework.security.core; + +import java.io.Serializable; +import java.security.Principal; +import java.util.Collection; + +import org.checkerframework.checker.confidential.qual.Confidential; + +public interface Authentication extends Principal, Serializable { + Collection getAuthorities(); + + @Confidential Object getCredentials(); + + Object getDetails(); + + Object getPrincipal(); + + boolean isAuthenticated(); + + void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException; +} diff --git a/checker/src/main/java/org/checkerframework/checker/confidential/Claims.astub b/checker/src/main/java/org/checkerframework/checker/confidential/Claims.astub new file mode 100644 index 00000000000..2526fa1c289 --- /dev/null +++ b/checker/src/main/java/org/checkerframework/checker/confidential/Claims.astub @@ -0,0 +1,36 @@ +import org.checkerframework.checker.confidential.qual.PolyConfidential; + +import java.util.Date; +import java.util.Map; + +public interface Claims extends Map<@PolyConfidential String, @PolyConfidential Object>, ClaimsMutator { + String getIssuer(); + + Claims setIssuer(String var1); + + String getSubject(@PolyConfidential Claims this); + + Claims setSubject(String var1); + + String getAudience(@PolyConfidential Claims this); + + Claims setAudience(String var1); + + Date getExpiration(@PolyConfidential Claims this); + + Claims setExpiration(Date var1); + + Date getNotBefore(@PolyConfidential Claims this); + + Claims setNotBefore(Date var1); + + Date getIssuedAt(@PolyConfidential Claims this); + + Claims setIssuedAt(Date var1); + + String getId(@PolyConfidential Claims this); + + Claims setId(String var1); + + T get(String var1, Class var2); +} diff --git a/checker/src/main/java/org/checkerframework/checker/confidential/ConfidentialAnnotatedTypeFactory.java b/checker/src/main/java/org/checkerframework/checker/confidential/ConfidentialAnnotatedTypeFactory.java new file mode 100644 index 00000000000..7953520d82d --- /dev/null +++ b/checker/src/main/java/org/checkerframework/checker/confidential/ConfidentialAnnotatedTypeFactory.java @@ -0,0 +1,140 @@ +package org.checkerframework.checker.confidential; + +import com.sun.source.tree.MethodInvocationTree; +import java.util.Set; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.ExecutableElement; +import org.checkerframework.checker.confidential.qual.BottomConfidential; +import org.checkerframework.checker.confidential.qual.Confidential; +import org.checkerframework.checker.confidential.qual.NonConfidential; +import org.checkerframework.checker.confidential.qual.UnknownConfidential; +import org.checkerframework.common.basetype.BaseAnnotatedTypeFactory; +import org.checkerframework.common.basetype.BaseTypeChecker; +import org.checkerframework.framework.flow.CFAbstractAnalysis; +import org.checkerframework.framework.flow.CFStore; +import org.checkerframework.framework.flow.CFTransfer; +import org.checkerframework.framework.flow.CFValue; +import org.checkerframework.framework.type.AnnotatedTypeFactory; +import org.checkerframework.framework.type.AnnotatedTypeMirror; +import org.checkerframework.framework.type.treeannotator.ListTreeAnnotator; +import org.checkerframework.framework.type.treeannotator.TreeAnnotator; +import org.checkerframework.javacutil.AnnotationBuilder; +import org.checkerframework.javacutil.AnnotationMirrorSet; +import org.checkerframework.javacutil.TreeUtils; + +/** Annotated type factory for the Confidential Checker. */ +public class ConfidentialAnnotatedTypeFactory extends BaseAnnotatedTypeFactory { + + /** The {@code @}{@link NonConfidential} annotation mirror. */ + protected final AnnotationMirror NONCONFIDENTIAL; + + /** The {@code @}{@link Confidential} annotation mirror. */ + protected final AnnotationMirror CONFIDENTIAL; + + /** The {@code @}{@link UnknownConfidential} annotation mirror. */ + protected final AnnotationMirror UNKNOWN_CONFIDENTIAL; + + /** The {@code @}{@link BottomConfidential} annotation mirror. */ + protected final AnnotationMirror BOTTOM_CONFIDENTIAL; + + /** Fully-qualified class name of {@link NonConfidential}. */ + public static final String NONCONFIDENTIAL_NAME = + "org.checkerframework.checker.confidential.qual.NonConfidential"; + + /** Fully-qualified class name of {@link Confidential}. */ + public static final String CONFIDENTIAL_NAME = + "org.checkerframework.checker.confidential.qual.Confidential"; + + /** Fully-qualified class name of {@link UnknownConfidential}. */ + public static final String UNKNOWN_CONFIDENTIAL_NAME = + "org.checkerframework.checker.confidential.qual.UnknownConfidential"; + + /** Fully-qualified class name of {@link BottomConfidential}. */ + public static final String BOTTOM_CONFIDENTIAL_NAME = + "org.checkerframework.checker.confidential.qual.BottomConfidential"; + + /** A singleton set containing the {@code @}{@link NonConfidential} annotation mirror. */ + private final AnnotationMirrorSet setOfNonConfidential; + + /** The Object.toString method. */ + private final ExecutableElement objectToString = + TreeUtils.getMethod("java.lang.Object", "toString", 0, processingEnv); + + /** + * Creates a {@link ConfidentialAnnotatedTypeFactory}. + * + * @param checker the confidential checker + */ + public ConfidentialAnnotatedTypeFactory(BaseTypeChecker checker) { + super(checker); + this.NONCONFIDENTIAL = AnnotationBuilder.fromClass(getElementUtils(), NonConfidential.class); + this.CONFIDENTIAL = AnnotationBuilder.fromClass(getElementUtils(), Confidential.class); + this.UNKNOWN_CONFIDENTIAL = + AnnotationBuilder.fromClass(getElementUtils(), UnknownConfidential.class); + this.BOTTOM_CONFIDENTIAL = + AnnotationBuilder.fromClass(getElementUtils(), BottomConfidential.class); + this.setOfNonConfidential = AnnotationMirrorSet.singleton(NONCONFIDENTIAL); + postInit(); + } + + @Override + protected Set getEnumConstructorQualifiers() { + return setOfNonConfidential; + } + + @Override + public TreeAnnotator createTreeAnnotator() { + return new ListTreeAnnotator( + super.createTreeAnnotator(), + new ConfidentialAnnotatedTypeFactory.ConfidentialTreeAnnotator(this)); + } + + @Override + public CFTransfer createFlowTransferFunction( + CFAbstractAnalysis analysis) { + return new ConfidentialTransfer(analysis); + } + + /** + * A TreeAnnotator to enforce certain toString return type rules: + * + *

+ */ + private class ConfidentialTreeAnnotator extends TreeAnnotator { + /** + * Creates a {@link ConfidentialAnnotatedTypeFactory.ConfidentialTreeAnnotator} + * + * @param atypeFactory the annotated type factory + */ + public ConfidentialTreeAnnotator(AnnotatedTypeFactory atypeFactory) { + super(atypeFactory); + } + + /** + * Visits a method invocation node. Enforces specific type-checking rules for Object.toString() + * that allow a @NonConfidential Object to return a @NonConfidential String. + * + *

Supplements the @Confidential String return in Object.toString() to cover all secure use + * cases, i.e. all cases covered by a @PolyConfidential receiver and return excepting + * a @NonConfidential String from @Confidential receivers. + * + * @param tree an AST node representing a method call + * @param type the type obtained from tree + */ + @Override + public Void visitMethodInvocation(MethodInvocationTree tree, AnnotatedTypeMirror type) { + if (TreeUtils.isMethodInvocation(tree, objectToString, processingEnv)) { + AnnotatedTypeMirror receiver = getReceiverType(tree); + if (receiver.hasPrimaryAnnotation(NONCONFIDENTIAL)) { + type.replaceAnnotation(NONCONFIDENTIAL); + } else { + type.replaceAnnotation(CONFIDENTIAL); + } + } + return super.visitMethodInvocation(tree, type); + } + } +} diff --git a/checker/src/main/java/org/checkerframework/checker/confidential/ConfidentialChecker.java b/checker/src/main/java/org/checkerframework/checker/confidential/ConfidentialChecker.java new file mode 100644 index 00000000000..53f14ebd8a9 --- /dev/null +++ b/checker/src/main/java/org/checkerframework/checker/confidential/ConfidentialChecker.java @@ -0,0 +1,38 @@ +package org.checkerframework.checker.confidential; + +import org.checkerframework.common.basetype.BaseTypeChecker; +import org.checkerframework.framework.qual.StubFiles; +import org.checkerframework.framework.source.SuppressWarningsPrefix; + +/** + * A type-checker plug-in for the Confidential type system qualifier that finds (and verifies the + * absence of) information leakage bugs. + * + *

It verifies that no confidential values are passed to sensitive sinks. A sensitive sink has a + * formal parameter type of {@code @NonConfidential}. One example of a sensitive sink is a method + * that displays information to the user. + * + * @checker_framework.manual #confidential-checker Confidential Checker + */ +@StubFiles({ + "Log4jLogger.astub", + "AndroidLog.astub", + "Slf4jLogger.astub", + "ApacheLog.astub", + "AlertDialog.astub", + "AbstractAuthenticationTargetUrlRequestHandler.astub", + "UsernamePasswordAuthenticationToken.astub", + "PasswordEncoder.astub", + "HttpServletResponse.astub", + "Cookie.astub", + "UserDetails.astub", + "ExpiringMap.astub", + "JwtParser.astub", + "Authentication.astub", + "Claims.astub" +}) +@SuppressWarningsPrefix({"confidential"}) +public class ConfidentialChecker extends BaseTypeChecker { + /** Creates a ConfidentialChecker. */ + public ConfidentialChecker() {} +} diff --git a/checker/src/main/java/org/checkerframework/checker/confidential/ConfidentialTransfer.java b/checker/src/main/java/org/checkerframework/checker/confidential/ConfidentialTransfer.java new file mode 100644 index 00000000000..0482265ed12 --- /dev/null +++ b/checker/src/main/java/org/checkerframework/checker/confidential/ConfidentialTransfer.java @@ -0,0 +1,115 @@ +package org.checkerframework.checker.confidential; + +import javax.lang.model.element.AnnotationMirror; +import org.checkerframework.dataflow.analysis.TransferInput; +import org.checkerframework.dataflow.analysis.TransferResult; +import org.checkerframework.dataflow.cfg.node.Node; +import org.checkerframework.dataflow.cfg.node.StringConcatenateNode; +import org.checkerframework.framework.flow.CFAbstractAnalysis; +import org.checkerframework.framework.flow.CFStore; +import org.checkerframework.framework.flow.CFTransfer; +import org.checkerframework.framework.flow.CFValue; +import org.checkerframework.framework.type.QualifierHierarchy; +import org.checkerframework.javacutil.AnnotationUtils; + +/** The transfer class for the Confidential Checker. */ +public class ConfidentialTransfer extends CFTransfer { + + /** The Confidential type factory. */ + protected final ConfidentialAnnotatedTypeFactory atypeFactory; + + /** The Confidential qualifier hierarchy. */ + protected final QualifierHierarchy qualHierarchy; + + /** + * Create a new ConfidentialTransfer. + * + * @param analysis the corresponding analysis + */ + public ConfidentialTransfer(CFAbstractAnalysis analysis) { + super(analysis); + atypeFactory = (ConfidentialAnnotatedTypeFactory) analysis.getTypeFactory(); + qualHierarchy = atypeFactory.getQualifierHierarchy(); + } + + /** + * Enforces Confidential String concatenation rules: + * + *

+ */ + @Override + public TransferResult visitStringConcatenate( + StringConcatenateNode n, TransferInput p) { + TransferResult result = super.visitStringConcatenate(n, p); + return stringConcatenation(n.getLeftOperand(), n.getRightOperand(), p, result); + } + + /** + * Determines the type of a string concatenation. + * + * @param leftOperand the left operand to be concatenated + * @param rightOperand the right operand to be concatenated + * @param p the input abstract values + * @param result the result abstract values + * @return the resulting type of the string concatenation operation + */ + public TransferResult stringConcatenation( + Node leftOperand, + Node rightOperand, + TransferInput p, + TransferResult result) { + AnnotationMirror resultAnno = + createAnnotationForStringConcatenation(leftOperand, rightOperand, p); + return recreateTransferResult(resultAnno, result); + } + + /** + * Creates an annotation for a result of string concatenation. + * + * @param leftOperand the left operand to be concatenated + * @param rightOperand the right operand to be concatenated + * @param p the input abstract values + * @return the resulting AnnotationMirror of the string concatenation operation, or null if either + * leftOperand or rightOperand is null or either operand does not belong to the Confidential + * hierarchy. + */ + private AnnotationMirror createAnnotationForStringConcatenation( + Node leftOperand, Node rightOperand, TransferInput p) { + CFValue leftValue = p.getValueOfSubNode(leftOperand); + AnnotationMirror leftAnno = getValueAnnotation(leftValue); + if (leftAnno == null) { + return null; + } + CFValue rightValue = p.getValueOfSubNode(rightOperand); + AnnotationMirror rightAnno = getValueAnnotation(rightValue); + if (rightAnno == null) { + return null; + } + + if (AnnotationUtils.areSameByName(leftAnno, ConfidentialAnnotatedTypeFactory.CONFIDENTIAL_NAME) + || AnnotationUtils.areSameByName( + rightAnno, ConfidentialAnnotatedTypeFactory.CONFIDENTIAL_NAME)) { + return atypeFactory.CONFIDENTIAL; + } + + return qualHierarchy.leastUpperBoundShallow( + leftAnno, leftOperand.getType(), rightAnno, rightOperand.getType()); + } + + /** + * Returns the annotation in the Confidential type hierarchy for the given value. + * + * @param cfValue the value + * @return the value's AnnotationMirror from the Confidential hierarchy + */ + private AnnotationMirror getValueAnnotation(CFValue cfValue) { + return qualHierarchy.findAnnotationInHierarchy( + cfValue.getAnnotations(), atypeFactory.UNKNOWN_CONFIDENTIAL); + } +} diff --git a/checker/src/main/java/org/checkerframework/checker/confidential/ConfidentialVisitor.java b/checker/src/main/java/org/checkerframework/checker/confidential/ConfidentialVisitor.java new file mode 100644 index 00000000000..527e11b155b --- /dev/null +++ b/checker/src/main/java/org/checkerframework/checker/confidential/ConfidentialVisitor.java @@ -0,0 +1,50 @@ +package org.checkerframework.checker.confidential; + +import com.sun.source.tree.Tree; +import javax.lang.model.element.ExecutableElement; +import org.checkerframework.checker.compilermsgs.qual.CompilerMessageKey; +import org.checkerframework.checker.confidential.qual.Confidential; +import org.checkerframework.checker.formatter.qual.FormatMethod; +import org.checkerframework.common.basetype.BaseAnnotatedTypeFactory; +import org.checkerframework.common.basetype.BaseTypeChecker; +import org.checkerframework.common.basetype.BaseTypeVisitor; +import org.checkerframework.framework.type.AnnotatedTypeMirror; +import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType; + +/** Visitor for the {@link ConfidentialChecker}. */ +public class ConfidentialVisitor extends BaseTypeVisitor { + + /** + * Creates a {@link ConfidentialVisitor}. + * + * @param checker the checker that uses this visitor + */ + public ConfidentialVisitor(BaseTypeChecker checker) { + super(checker); + } + + /** + * Don't check that the constructor result is top. Checking that the super() or this() call is a + * subtype of the constructor result is sufficient. + * + *

{@inheritDoc} + */ + @Override + protected void checkConstructorResult( + AnnotatedExecutableType constructorType, ExecutableElement constructorElement) {} + + @Override + @FormatMethod + protected boolean commonAssignmentCheck( + AnnotatedTypeMirror varType, + AnnotatedTypeMirror valueType, + Tree valueTree, + @CompilerMessageKey String errorKey, + Object... extraArgs) { + // Permit casting anything to @Confidential. + if (varType.hasEffectiveAnnotation(Confidential.class)) { + return true; + } + return super.commonAssignmentCheck(varType, valueType, valueTree, errorKey, extraArgs); + } +} diff --git a/checker/src/main/java/org/checkerframework/checker/confidential/Cookie.astub b/checker/src/main/java/org/checkerframework/checker/confidential/Cookie.astub new file mode 100644 index 00000000000..d585d02e7e2 --- /dev/null +++ b/checker/src/main/java/org/checkerframework/checker/confidential/Cookie.astub @@ -0,0 +1,14 @@ +package jakarta.servlet.http; + +import java.io.Serializable; +import java.text.MessageFormat; +import java.util.Locale; +import java.util.ResourceBundle; + +import org.checkerframework.checker.confidential.qual.*; + +public class Cookie implements Cloneable, Serializable { + + @Override + public boolean equals(@UnknownConfidential Object obj); +} diff --git a/checker/src/main/java/org/checkerframework/checker/confidential/ExpiringMap.astub b/checker/src/main/java/org/checkerframework/checker/confidential/ExpiringMap.astub new file mode 100644 index 00000000000..57561b63a9b --- /dev/null +++ b/checker/src/main/java/org/checkerframework/checker/confidential/ExpiringMap.astub @@ -0,0 +1,11 @@ +package net.jodah.expiringmap; + +import java.util.concurrent.ConcurrentMap; +import org.checkerframework.checker.confidential.qual.PolyConfidential; + +public class ExpiringMap<@PolyConfidential K, @PolyConfidential V> implements ConcurrentMap<@PolyConfidential K, @PolyConfidential V> { + + public boolean containsKey(@PolyConfidential Object key); + + public V put(@PolyConfidential K key, @PolyConfidential V value, long duration, TimeUnit timeUnit); +} diff --git a/checker/src/main/java/org/checkerframework/checker/confidential/HttpServletResponse.astub b/checker/src/main/java/org/checkerframework/checker/confidential/HttpServletResponse.astub new file mode 100644 index 00000000000..a0f737f4fbd --- /dev/null +++ b/checker/src/main/java/org/checkerframework/checker/confidential/HttpServletResponse.astub @@ -0,0 +1,18 @@ +package jakarta.servlet.http; + +import java.io.IOException; +import java.util.Collection; +import java.util.Map; +import java.util.function.Supplier; +import javax.servlet.ServletResponse; + +import org.checkerframework.checker.confidential.qual.*; + +public interface HttpServletResponse extends ServletResponse { + + void addCookie(@UnknownConfidential Cookie cookie); + + default void setTrailerFields(@UnknownConfidential Supplier> supplier); + + default @UnknownConfidential Supplier> getTrailerFields(); +} diff --git a/checker/src/main/java/org/checkerframework/checker/confidential/JwtParser.astub b/checker/src/main/java/org/checkerframework/checker/confidential/JwtParser.astub new file mode 100644 index 00000000000..eb658497dba --- /dev/null +++ b/checker/src/main/java/org/checkerframework/checker/confidential/JwtParser.astub @@ -0,0 +1,12 @@ +package io.jsonwebtoken; + +import java.security.Key; +import java.util.Date; + +import org.checkerframework.checker.confidential.qual.*; + +public interface JwtParser { + char SEPARATOR_CHAR = '.'; + + Jws<@Confidential Claims> parseClaimsJws(@Confidential String var1) throws ExpiredJwtException, UnsupportedJwtException, MalformedJwtException, SignatureException, IllegalArgumentException; +} diff --git a/checker/src/main/java/org/checkerframework/checker/confidential/Log4jLogger.astub b/checker/src/main/java/org/checkerframework/checker/confidential/Log4jLogger.astub new file mode 100644 index 00000000000..a4d5d85fcb1 --- /dev/null +++ b/checker/src/main/java/org/checkerframework/checker/confidential/Log4jLogger.astub @@ -0,0 +1,1146 @@ +package org.apache.logging.log4j; + +import org.apache.logging.log4j.message.EntryMessage; +import org.apache.logging.log4j.message.FlowMessageFactory; +import org.apache.logging.log4j.message.Message; +import org.apache.logging.log4j.message.MessageFactory; +import org.apache.logging.log4j.message.MessageFactory2; +import org.apache.logging.log4j.util.MessageSupplier; +import org.apache.logging.log4j.util.Supplier; + +import org.checkerframework.checker.confidential.qual.*; + +public interface Logger { + + void error(@UnknownConfidential Marker marker, Message message); + + void error(@UnknownConfidential Marker marker, Message message, @UnknownConfidential Throwable throwable); + + void error(@UnknownConfidential Marker marker, @UnknownConfidential MessageSupplier messageSupplier); + + void error(@UnknownConfidential Marker marker, @UnknownConfidential MessageSupplier messageSupplier, @UnknownConfidential Throwable throwable); + + void error(@UnknownConfidential Marker marker, CharSequence message); + + void error(@UnknownConfidential Marker marker, CharSequence message, @UnknownConfidential Throwable throwable); + + void error(@UnknownConfidential Marker marker, Object message); + + void error(@UnknownConfidential Marker marker, Object message, @UnknownConfidential Throwable throwable); + + void error(@UnknownConfidential Marker marker, String message); + + void error(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object... params); + + void error(@UnknownConfidential Marker marker, String message, @UnknownConfidential Supplier... paramSuppliers); + + void error(@UnknownConfidential Marker marker, String message, @UnknownConfidential Throwable throwable); + + void error(@UnknownConfidential Marker marker, @UnknownConfidential Supplier messageSupplier); + + void error(@UnknownConfidential Marker marker, @UnknownConfidential Supplier messageSupplier, @UnknownConfidential Throwable throwable); + + void error(Message message); + + void error(Message message, @UnknownConfidential Throwable throwable); + + void error(@UnknownConfidential MessageSupplier messageSupplier); + + void error(@UnknownConfidential MessageSupplier messageSupplier, @UnknownConfidential Throwable throwable); + + void error(CharSequence message); + + void error(CharSequence message, @UnknownConfidential Throwable throwable); + + void error(Object message); + + void error(Object message, @UnknownConfidential Throwable throwable); + + void error(String message); + + void error(String message, @UnknownConfidential Object... params); + + void error(String message, @UnknownConfidential Supplier... paramSuppliers); + + void error(String message, @UnknownConfidential Throwable throwable); + + void error(@UnknownConfidential Supplier messageSupplier); + + void error(@UnknownConfidential Supplier messageSupplier, @UnknownConfidential Throwable throwable); + + void error(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0); + + void error(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1); + + void error(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2); + + void error(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3); + + void error(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4); + + void error(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5); + + void error( + @UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5, @UnknownConfidential Object p6); + + void error( + @UnknownConfidential Marker marker, + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7); + + void error( + @UnknownConfidential Marker marker, + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8); + + void error( + @UnknownConfidential Marker marker, + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8, + @UnknownConfidential Object p9); + + void error(String message, @UnknownConfidential Object p0); + + void error(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1); + + void error(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2); + + void error(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3); + + void error(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4); + + void error(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5); + + void error(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5, @UnknownConfidential Object p6); + + void error(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5, @UnknownConfidential Object p6, @UnknownConfidential Object p7); + + void error( + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8); + + void error( + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8, + @UnknownConfidential Object p9); + + void info(@UnknownConfidential Marker marker, Message message); + + void info(@UnknownConfidential Marker marker, Message message, @UnknownConfidential Throwable throwable); + + void info(@UnknownConfidential Marker marker, @UnknownConfidential MessageSupplier messageSupplier); + + void info(@UnknownConfidential Marker marker, @UnknownConfidential MessageSupplier messageSupplier, @UnknownConfidential Throwable throwable); + + void info(@UnknownConfidential Marker marker, CharSequence message); + + void info(@UnknownConfidential Marker marker, CharSequence message, @UnknownConfidential Throwable throwable); + + void info(@UnknownConfidential Marker marker, Object message); + + void info(@UnknownConfidential Marker marker, Object message, @UnknownConfidential Throwable throwable); + + void info(@UnknownConfidential Marker marker, String message); + + void info(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object... params); + + void info(@UnknownConfidential Marker marker, String message, @UnknownConfidential Supplier... paramSuppliers); + + void info(@UnknownConfidential Marker marker, String message, @UnknownConfidential Throwable throwable); + + void info(@UnknownConfidential Marker marker, @UnknownConfidential Supplier messageSupplier); + + void info(@UnknownConfidential Marker marker, @UnknownConfidential Supplier messageSupplier, @UnknownConfidential Throwable throwable); + + void info(Message message); + + void info(Message message, @UnknownConfidential Throwable throwable); + + void info(@UnknownConfidential MessageSupplier messageSupplier); + + void info(@UnknownConfidential MessageSupplier messageSupplier, @UnknownConfidential Throwable throwable); + + void info(CharSequence message); + + void info(CharSequence message, @UnknownConfidential Throwable throwable); + + void info(Object message); + + void info(Object message, @UnknownConfidential Throwable throwable); + + void info(String message); + + void info(String message, @UnknownConfidential Object... params); + + void info(String message, @UnknownConfidential Supplier... paramSuppliers); + + void info(String message, @UnknownConfidential Throwable throwable); + + void info(@UnknownConfidential Supplier messageSupplier); + + void info(@UnknownConfidential Supplier messageSupplier, @UnknownConfidential Throwable throwable); + + void info(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0); + + void info(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1); + + void info(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2); + + void info(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3); + + void info(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4); + + void info(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5); + + void info( + @UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5, @UnknownConfidential Object p6); + + void info( + @UnknownConfidential Marker marker, + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7); + + void info( + @UnknownConfidential Marker marker, + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8); + + void info( + @UnknownConfidential Marker marker, + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8, + @UnknownConfidential Object p9); + + void info(String message, @UnknownConfidential Object p0); + + void info(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1); + + void info(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2); + + void info(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3); + + void info(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4); + + void info(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5); + + void info(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5, @UnknownConfidential Object p6); + + void info(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5, @UnknownConfidential Object p6, @UnknownConfidential Object p7); + + void info( + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8); + + void info( + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8, + @UnknownConfidential Object p9); + + void catching(Level level, @UnknownConfidential Throwable throwable); + + void catching(@UnknownConfidential Throwable throwable); + + void debug(@UnknownConfidential Marker marker, Message message); + + void debug(@UnknownConfidential Marker marker, Message message, @UnknownConfidential Throwable throwable); + + void debug(@UnknownConfidential Marker marker, @UnknownConfidential MessageSupplier messageSupplier); + + void debug(@UnknownConfidential Marker marker, @UnknownConfidential MessageSupplier messageSupplier, @UnknownConfidential Throwable throwable); + + void debug(@UnknownConfidential Marker marker, CharSequence message); + + void debug(@UnknownConfidential Marker marker, CharSequence message, @UnknownConfidential Throwable throwable); + + void debug(@UnknownConfidential Marker marker, Object message); + + void debug(@UnknownConfidential Marker marker, Object message, @UnknownConfidential Throwable throwable); + + void debug(@UnknownConfidential Marker marker, String message); + + void debug(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object... params); + + void debug(@UnknownConfidential Marker marker, String message, @UnknownConfidential Supplier... paramSuppliers); + + void debug(@UnknownConfidential Marker marker, String message, @UnknownConfidential Throwable throwable); + + void debug(@UnknownConfidential Marker marker, @UnknownConfidential Supplier messageSupplier); + + void debug(@UnknownConfidential Marker marker, @UnknownConfidential Supplier messageSupplier, @UnknownConfidential Throwable throwable); + + void debug(Message message); + + void debug(Message message, @UnknownConfidential Throwable throwable); + + void debug(@UnknownConfidential MessageSupplier messageSupplier); + + void debug(@UnknownConfidential MessageSupplier messageSupplier, @UnknownConfidential Throwable throwable); + + void debug(CharSequence message); + + void debug(CharSequence message, @UnknownConfidential Throwable throwable); + + void debug(Object message); + + void debug(Object message, @UnknownConfidential Throwable throwable); + + void debug(String message); + + void debug(String message, @UnknownConfidential Object... params); + + void debug(String message, @UnknownConfidential Supplier... paramSuppliers); + + void debug(String message, @UnknownConfidential Throwable throwable); + + void debug(@UnknownConfidential Supplier messageSupplier); + + void debug(@UnknownConfidential Supplier messageSupplier, @UnknownConfidential Throwable throwable); + + void debug(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0); + + void debug(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1); + + void debug(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2); + + void debug(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3); + + void debug(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4); + + void debug(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5); + + void debug( + @UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5, @UnknownConfidential Object p6); + + void debug( + @UnknownConfidential Marker marker, + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7); + + void debug( + @UnknownConfidential Marker marker, + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8); + + void debug( + @UnknownConfidential Marker marker, + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8, + @UnknownConfidential Object p9); + + void debug(String message, @UnknownConfidential Object p0); + + void debug(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1); + + void debug(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2); + + void debug(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3); + + void debug(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4); + + void debug(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5); + + void debug(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5, @UnknownConfidential Object p6); + + void debug(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5, @UnknownConfidential Object p6, @UnknownConfidential Object p7); + + void debug( + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8); + + void debug( + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8, + @UnknownConfidential Object p9); + + void fatal(@UnknownConfidential Marker marker, Message message); + + void fatal(@UnknownConfidential Marker marker, Message message, @UnknownConfidential Throwable throwable); + + void fatal(@UnknownConfidential Marker marker, @UnknownConfidential MessageSupplier messageSupplier); + + void fatal(@UnknownConfidential Marker marker, @UnknownConfidential MessageSupplier messageSupplier, @UnknownConfidential Throwable throwable); + + void fatal(@UnknownConfidential Marker marker, CharSequence message); + + void fatal(@UnknownConfidential Marker marker, CharSequence message, @UnknownConfidential Throwable throwable); + + void fatal(@UnknownConfidential Marker marker, Object message); + + void fatal(@UnknownConfidential Marker marker, Object message, @UnknownConfidential Throwable throwable); + + void fatal(@UnknownConfidential Marker marker, String message); + + void fatal(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object... params); + + void fatal(@UnknownConfidential Marker marker, String message, @UnknownConfidential Supplier... paramSuppliers); + + void fatal(@UnknownConfidential Marker marker, String message, @UnknownConfidential Throwable throwable); + + void fatal(@UnknownConfidential Marker marker, @UnknownConfidential Supplier messageSupplier); + + void fatal(@UnknownConfidential Marker marker, @UnknownConfidential Supplier messageSupplier, @UnknownConfidential Throwable throwable); + + void fatal(Message message); + + void fatal(Message message, @UnknownConfidential Throwable throwable); + + void fatal(@UnknownConfidential MessageSupplier messageSupplier); + + void fatal(@UnknownConfidential MessageSupplier messageSupplier, @UnknownConfidential Throwable throwable); + + void fatal(CharSequence message); + + void fatal(CharSequence message, @UnknownConfidential Throwable throwable); + + void fatal(Object message); + + void fatal(Object message, @UnknownConfidential Throwable throwable); + + void fatal(String message); + + void fatal(String message, @UnknownConfidential Object... params); + + void fatal(String message, @UnknownConfidential Supplier... paramSuppliers); + + void fatal(String message, @UnknownConfidential Throwable throwable); + + void fatal(@UnknownConfidential Supplier messageSupplier); + + void fatal(@UnknownConfidential Supplier messageSupplier, @UnknownConfidential Throwable throwable); + + void fatal(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0); + + void fatal(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1); + + void fatal(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2); + + void fatal(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3); + + void fatal(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4); + + void fatal(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5); + + void fatal( + @UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5, @UnknownConfidential Object p6); + + void fatal( + @UnknownConfidential Marker marker, + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7); + + void fatal( + @UnknownConfidential Marker marker, + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8); + + void fatal( + @UnknownConfidential Marker marker, + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8, + @UnknownConfidential Object p9); + + void fatal(String message, @UnknownConfidential Object p0); + + void fatal(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1); + + void fatal(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2); + + void fatal(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3); + + void fatal(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4); + + void fatal(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5); + + void fatal(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5, @UnknownConfidential Object p6); + + void fatal(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5, @UnknownConfidential Object p6, @UnknownConfidential Object p7); + + void fatal( + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8); + + void fatal( + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8, + @UnknownConfidential Object p9); + + void log(Level level, @UnknownConfidential Marker marker, Message message); + + void log(Level level, @UnknownConfidential Marker marker, Message message, @UnknownConfidential Throwable throwable); + + void log(Level level, @UnknownConfidential Marker marker, @UnknownConfidential MessageSupplier messageSupplier); + + void log(Level level, @UnknownConfidential Marker marker, @UnknownConfidential MessageSupplier messageSupplier, @UnknownConfidential Throwable throwable); + + void log(Level level, @UnknownConfidential Marker marker, CharSequence message); + + void log(Level level, @UnknownConfidential Marker marker, CharSequence message, @UnknownConfidential Throwable throwable); + + void log(Level level, @UnknownConfidential Marker marker, Object message); + + void log(Level level, @UnknownConfidential Marker marker, Object message, @UnknownConfidential Throwable throwable); + + void log(Level level, @UnknownConfidential Marker marker, String message); + + void log(Level level, @UnknownConfidential Marker marker, String message, @UnknownConfidential Object... params); + + void log(Level level, @UnknownConfidential Marker marker, String message, @UnknownConfidential Supplier... paramSuppliers); + + void log(Level level, @UnknownConfidential Marker marker, String message, @UnknownConfidential Throwable throwable); + + void log(Level level, @UnknownConfidential Marker marker, @UnknownConfidential Supplier messageSupplier); + + void log(Level level, @UnknownConfidential Marker marker, @UnknownConfidential Supplier messageSupplier, @UnknownConfidential Throwable throwable); + + void log(Level level, Message message); + + void log(Level level, Message message, @UnknownConfidential Throwable throwable); + + void log(Level level, @UnknownConfidential MessageSupplier messageSupplier); + + void log(Level level, @UnknownConfidential MessageSupplier messageSupplier, @UnknownConfidential Throwable throwable); + + void log(Level level, CharSequence message); + + void log(Level level, CharSequence message, @UnknownConfidential Throwable throwable); + + void log(Level level, Object message); + + void log(Level level, Object message, @UnknownConfidential Throwable throwable); + + void log(Level level, String message); + + void log(Level level, String message, @UnknownConfidential Object... params); + + void log(Level level, String message, @UnknownConfidential Supplier... paramSuppliers); + + void log(Level level, String message, @UnknownConfidential Throwable throwable); + + void log(Level level, @UnknownConfidential Supplier messageSupplier); + + void log(Level level, @UnknownConfidential Supplier messageSupplier, @UnknownConfidential Throwable throwable); + + void log(Level level, @UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0); + + void log(Level level, @UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1); + + void log(Level level, @UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2); + + void log(Level level, @UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3); + + void log(Level level, @UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4); + + void log( + Level level, + @UnknownConfidential Marker marker, + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5); + + void log( + Level level, + @UnknownConfidential Marker marker, + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6); + + void log( + Level level, + @UnknownConfidential Marker marker, + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7); + + void log( + Level level, + @UnknownConfidential Marker marker, + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8); + + void log( + Level level, + @UnknownConfidential Marker marker, + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8, + @UnknownConfidential Object p9); + + void log(Level level, String message, @UnknownConfidential Object p0); + + void log(Level level, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1); + + void log(Level level, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2); + + void log(Level level, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3); + + void log(Level level, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4); + + void log(Level level, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5); + + void log(Level level, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5, @UnknownConfidential Object p6); + + void log( + Level level, + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7); + + void log( + Level level, + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8); + + void log( + Level level, + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8, + @UnknownConfidential Object p9); + + default void logMessage( + final Level level, + final @UnknownConfidential Marker marker, + final String fqcn, + final StackTraceElement location, + final Message message, + final @UnknownConfidential Throwable throwable); + + void printf(Level level, @UnknownConfidential Marker marker, String format, @UnknownConfidential Object... params); + + void printf(Level level, String format, @UnknownConfidential Object... params); + + void trace(@UnknownConfidential Marker marker, Message message); + + void trace(@UnknownConfidential Marker marker, Message message, @UnknownConfidential Throwable throwable); + + void trace(@UnknownConfidential Marker marker, @UnknownConfidential MessageSupplier messageSupplier); + + void trace(@UnknownConfidential Marker marker, @UnknownConfidential MessageSupplier messageSupplier, @UnknownConfidential Throwable throwable); + + void trace(@UnknownConfidential Marker marker, CharSequence message); + + void trace(@UnknownConfidential Marker marker, CharSequence message, @UnknownConfidential Throwable throwable); + + void trace(@UnknownConfidential Marker marker, Object message); + + void trace(@UnknownConfidential Marker marker, Object message, @UnknownConfidential Throwable throwable); + + void trace(@UnknownConfidential Marker marker, String message); + + void trace(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object... params); + + void trace(@UnknownConfidential Marker marker, String message, @UnknownConfidential Supplier... paramSuppliers); + + void trace(@UnknownConfidential Marker marker, String message, @UnknownConfidential Throwable throwable); + + void trace(@UnknownConfidential Marker marker, @UnknownConfidential Supplier messageSupplier); + + void trace(@UnknownConfidential Marker marker, @UnknownConfidential Supplier messageSupplier, @UnknownConfidential Throwable throwable); + + void trace(Message message); + + void trace(Message message, @UnknownConfidential Throwable throwable); + + void trace(@UnknownConfidential MessageSupplier messageSupplier); + + void trace(@UnknownConfidential MessageSupplier messageSupplier, @UnknownConfidential Throwable throwable); + + void trace(CharSequence message); + + void trace(CharSequence message, @UnknownConfidential Throwable throwable); + + void trace(Object message); + + void trace(Object message, @UnknownConfidential Throwable throwable); + + void trace(String message); + + void trace(String message, @UnknownConfidential Object... params); + + void trace(String message, @UnknownConfidential Supplier... paramSuppliers); + + void trace(String message, @UnknownConfidential Throwable throwable); + + void trace(@UnknownConfidential Supplier messageSupplier); + + void trace(@UnknownConfidential Supplier messageSupplier, @UnknownConfidential Throwable throwable); + + void trace(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0); + + void trace(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1); + + void trace(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2); + + void trace(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3); + + void trace(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4); + + void trace(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5); + + void trace( + @UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5, @UnknownConfidential Object p6); + + void trace( + @UnknownConfidential Marker marker, + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7); + + void trace( + @UnknownConfidential Marker marker, + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8); + + void trace( + @UnknownConfidential Marker marker, + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8, + @UnknownConfidential Object p9); + + void trace(String message, @UnknownConfidential Object p0); + + void trace(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1); + + void trace(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2); + + void trace(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3); + + void trace(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4); + + void trace(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5); + + void trace(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5, @UnknownConfidential Object p6); + + void trace(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5, @UnknownConfidential Object p6, @UnknownConfidential Object p7); + + void trace( + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8); + + void trace( + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8, + @UnknownConfidential Object p9); + + void warn(@UnknownConfidential Marker marker, Message message); + + void warn(@UnknownConfidential Marker marker, Message message, @UnknownConfidential Throwable throwable); + + void warn(@UnknownConfidential Marker marker, @UnknownConfidential MessageSupplier messageSupplier); + + void warn(@UnknownConfidential Marker marker, @UnknownConfidential MessageSupplier messageSupplier, @UnknownConfidential Throwable throwable); + + void warn(@UnknownConfidential Marker marker, CharSequence message); + + void warn(@UnknownConfidential Marker marker, CharSequence message, @UnknownConfidential Throwable throwable); + + void warn(@UnknownConfidential Marker marker, Object message); + + void warn(@UnknownConfidential Marker marker, Object message, @UnknownConfidential Throwable throwable); + + void warn(@UnknownConfidential Marker marker, String message); + + void warn(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object... params); + + void warn(@UnknownConfidential Marker marker, String message, @UnknownConfidential Supplier... paramSuppliers); + + void warn(@UnknownConfidential Marker marker, String message, @UnknownConfidential Throwable throwable); + + void warn(@UnknownConfidential Marker marker, @UnknownConfidential Supplier messageSupplier); + + void warn(@UnknownConfidential Marker marker, @UnknownConfidential Supplier messageSupplier, @UnknownConfidential Throwable throwable); + + void warn(Message message); + + void warn(Message message, @UnknownConfidential Throwable throwable); + + void warn(@UnknownConfidential MessageSupplier messageSupplier); + + void warn(@UnknownConfidential MessageSupplier messageSupplier, @UnknownConfidential Throwable throwable); + + void warn(CharSequence message); + + void warn(CharSequence message, @UnknownConfidential Throwable throwable); + + void warn(Object message); + + void warn(Object message, @UnknownConfidential Throwable throwable); + + void warn(String message); + + void warn(String message, @UnknownConfidential Object... params); + + void warn(String message, @UnknownConfidential Supplier... paramSuppliers); + + void warn(String message, @UnknownConfidential Throwable throwable); + + void warn(@UnknownConfidential Supplier messageSupplier); + + void warn(@UnknownConfidential Supplier messageSupplier, @UnknownConfidential Throwable throwable); + + void warn(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0); + + void warn(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1); + + void warn(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2); + + void warn(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3); + + void warn(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4); + + void warn(@UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5); + + void warn( + @UnknownConfidential Marker marker, String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5, @UnknownConfidential Object p6); + + void warn( + @UnknownConfidential Marker marker, + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7); + + void warn( + @UnknownConfidential Marker marker, + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8); + + void warn( + @UnknownConfidential Marker marker, + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8, + @UnknownConfidential Object p9); + + void warn(String message, @UnknownConfidential Object p0); + + void warn(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1); + + void warn(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2); + + void warn(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3); + + void warn(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4); + + void warn(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5); + + void warn(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5, @UnknownConfidential Object p6); + + void warn(String message, @UnknownConfidential Object p0, @UnknownConfidential Object p1, @UnknownConfidential Object p2, @UnknownConfidential Object p3, @UnknownConfidential Object p4, @UnknownConfidential Object p5, @UnknownConfidential Object p6, @UnknownConfidential Object p7); + + void warn( + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8); + + void warn( + String message, + @UnknownConfidential Object p0, + @UnknownConfidential Object p1, + @UnknownConfidential Object p2, + @UnknownConfidential Object p3, + @UnknownConfidential Object p4, + @UnknownConfidential Object p5, + @UnknownConfidential Object p6, + @UnknownConfidential Object p7, + @UnknownConfidential Object p8, + @UnknownConfidential Object p9); + + T throwing(Level level, T throwable); + + T throwing(T throwable); + + boolean isDebugEnabled(@UnknownConfidential Marker marker); + + boolean isEnabled(Level level); + + boolean isEnabled(Level level, @UnknownConfidential Marker marker); + + boolean isErrorEnabled(@UnknownConfidential Marker marker); + + boolean isFatalEnabled(@UnknownConfidential Marker marker); + + boolean isInfoEnabled(@UnknownConfidential Marker marker); + + boolean isTraceEnabled(@UnknownConfidential Marker marker); + + boolean isWarnEnabled(@UnknownConfidential Marker marker); + + EntryMessage traceEntry(String format, @UnknownConfidential Object... params); + + EntryMessage traceEntry(@UnknownConfidential Supplier... paramSuppliers); + + EntryMessage traceEntry(String format, @UnknownConfidential Supplier... paramSuppliers); +} diff --git a/checker/src/main/java/org/checkerframework/checker/confidential/PasswordEncoder.astub b/checker/src/main/java/org/checkerframework/checker/confidential/PasswordEncoder.astub new file mode 100644 index 00000000000..77bac47a435 --- /dev/null +++ b/checker/src/main/java/org/checkerframework/checker/confidential/PasswordEncoder.astub @@ -0,0 +1,14 @@ +package org.springframework.security.crypto.password; + +import org.checkerframework.checker.confidential.qual.Confidential; +import org.checkerframework.checker.confidential.qual.UnknownConfidential; + +public interface PasswordEncoder { + @Confidential String encode(@UnknownConfidential CharSequence var1); + + boolean matches(@Confidential CharSequence var1, @Confidential String var2); + + default boolean upgradeEncoding(@Confidential String encodedPassword) { + return false; + } +} diff --git a/checker/src/main/java/org/checkerframework/checker/confidential/Slf4jLogger.astub b/checker/src/main/java/org/checkerframework/checker/confidential/Slf4jLogger.astub new file mode 100644 index 00000000000..e859b5d786e --- /dev/null +++ b/checker/src/main/java/org/checkerframework/checker/confidential/Slf4jLogger.astub @@ -0,0 +1,43 @@ +package org.slf4j; + +import static org.slf4j.event.EventConstants.DEBUG_INT; +import static org.slf4j.event.EventConstants.ERROR_INT; +import static org.slf4j.event.EventConstants.INFO_INT; +import static org.slf4j.event.EventConstants.TRACE_INT; +import static org.slf4j.event.EventConstants.WARN_INT; +import static org.slf4j.event.Level.DEBUG; +import static org.slf4j.event.Level.ERROR; +import static org.slf4j.event.Level.INFO; +import static org.slf4j.event.Level.TRACE; +import static org.slf4j.event.Level.WARN; + +import org.slf4j.event.Level; +import org.slf4j.helpers.CheckReturnValue; +import org.slf4j.spi.DefaultLoggingEventBuilder; +import org.slf4j.spi.LoggingEventBuilder; +import org.slf4j.spi.NOPLoggingEventBuilder; + +import org.checkerframework.checker.confidential.qual.UnknownConfidential; + +public interface Logger { + + public void error(String msg, @UnknownConfidential Throwable t); + + public void error(Marker marker, String msg, @UnknownConfidential Throwable t); + + public void info(String msg, @UnknownConfidential Throwable t); + + public void info(Marker marker, String msg, @UnknownConfidential Throwable t); + + public void debug(String msg, @UnknownConfidential Throwable t); + + public void debug(Marker marker, String msg, @UnknownConfidential Throwable t); + + public void trace(String msg, @UnknownConfidential Throwable t); + + public void trace(Marker marker, String msg, @UnknownConfidential Throwable t); + + public void warn(String msg, @UnknownConfidential Throwable t); + + public void warn(Marker marker, String msg, @UnknownConfidential Throwable t); +} diff --git a/checker/src/main/java/org/checkerframework/checker/confidential/UserDetails.astub b/checker/src/main/java/org/checkerframework/checker/confidential/UserDetails.astub new file mode 100644 index 00000000000..b0ec1a04e2b --- /dev/null +++ b/checker/src/main/java/org/checkerframework/checker/confidential/UserDetails.astub @@ -0,0 +1,22 @@ +package org.springframework.security.core.userdetails; + +import java.io.Serializable; +import java.util.Collection; +import org.springframework.security.core.GrantedAuthority; +import org.checkerframework.checker.confidential.qual.*; + +public interface UserDetails extends Serializable { + Collection getAuthorities(); + + @Confidential String getPassword(); + + String getUsername(); + + boolean isAccountNonExpired(); + + boolean isAccountNonLocked(); + + boolean isCredentialsNonExpired(); + + boolean isEnabled(); +} diff --git a/checker/src/main/java/org/checkerframework/checker/confidential/UsernamePasswordAuthenticationToken.astub b/checker/src/main/java/org/checkerframework/checker/confidential/UsernamePasswordAuthenticationToken.astub new file mode 100644 index 00000000000..99165c25b05 --- /dev/null +++ b/checker/src/main/java/org/checkerframework/checker/confidential/UsernamePasswordAuthenticationToken.astub @@ -0,0 +1,19 @@ +package org.springframework.security.authentication; + +import java.util.Collection; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.util.Assert; + +import org.checkerframework.checker.confidential.qual.Confidential; + +public class UsernamePasswordAuthenticationToken extends AbstractAuthenticationToken { + private static final long serialVersionUID = 550L; + private final Object principal; + private @Confidential Object credentials; + + public UsernamePasswordAuthenticationToken(Object principal, @Confidential Object credentials); + + public UsernamePasswordAuthenticationToken(Object principal, @Confidential Object credentials, Collection authorities); + + public @Confidential Object getCredentials(); +} diff --git a/checker/src/test/java/org/checkerframework/checker/test/junit/ConfidentialTest.java b/checker/src/test/java/org/checkerframework/checker/test/junit/ConfidentialTest.java new file mode 100644 index 00000000000..cb34dfd75e5 --- /dev/null +++ b/checker/src/test/java/org/checkerframework/checker/test/junit/ConfidentialTest.java @@ -0,0 +1,24 @@ +package org.checkerframework.checker.test.junit; + +import java.io.File; +import java.util.List; +import org.checkerframework.checker.confidential.ConfidentialChecker; +import org.checkerframework.framework.test.CheckerFrameworkPerDirectoryTest; +import org.junit.runners.Parameterized.Parameters; + +public class ConfidentialTest extends CheckerFrameworkPerDirectoryTest { + + /** + * Create a ConfidentialTest. + * + * @param testFiles the files containing test code, which will be type-checked + */ + public ConfidentialTest(List testFiles) { + super(testFiles, ConfidentialChecker.class, "confidential"); + } + + @Parameters + public static String[] getTestDirs() { + return new String[] {"confidential", "all-systems"}; + } +} diff --git a/checker/tests/confidential/ConfidentialConcatenation.java b/checker/tests/confidential/ConfidentialConcatenation.java new file mode 100644 index 00000000000..d76ee172095 --- /dev/null +++ b/checker/tests/confidential/ConfidentialConcatenation.java @@ -0,0 +1,50 @@ +// NonConfidential <: Confidential + +import org.checkerframework.checker.confidential.qual.Confidential; +import org.checkerframework.checker.confidential.qual.NonConfidential; + +public class ConfidentialConcatenation { + + void executeNonConfidential(@NonConfidential String s) {} + + void executeConfidential(@Confidential String s) {} + + void concatenation(@NonConfidential String s1, @Confidential String s2) { + @Confidential String s_1 = s1 + s1; + @Confidential String s_2 = s1 + s2; + @Confidential String s_3 = s2 + s1; + @Confidential String s_4 = s2 + s2; + + @NonConfidential String s_5 = s1 + s1; + // :: error: (assignment) + @NonConfidential String s_6 = s1 + s2; + // :: error: (assignment) + @NonConfidential String s_7 = s2 + s1; + // :: error: (assignment) + @NonConfidential String s_8 = s2 + s2; + } + + void concatenationInvocation(@NonConfidential String s1, @Confidential String s2) { + executeNonConfidential(s1 + s1); + // :: error: (argument) + executeNonConfidential(s1 + s2); + // :: error: (argument) + executeNonConfidential(s2 + s1); + // :: error: (argument) + executeNonConfidential(s2 + s2); + + executeConfidential(s1 + s1); + executeConfidential(s1 + s2); + executeConfidential(s2 + s1); + executeConfidential(s2 + s2); + } + + void compoundConcatenation(@NonConfidential String s1, @Confidential String s2) { + s1 += s1; + // :: error: (compound.assignment) + s1 += s2; + + s2 += s2; + s2 += s1; + } +} diff --git a/checker/tests/confidential/ConfidentialToString.java b/checker/tests/confidential/ConfidentialToString.java new file mode 100644 index 00000000000..19990f3c4aa --- /dev/null +++ b/checker/tests/confidential/ConfidentialToString.java @@ -0,0 +1,14 @@ +import org.checkerframework.checker.confidential.qual.Confidential; +import org.checkerframework.checker.confidential.qual.NonConfidential; + +public class ConfidentialToString { + void confObj(@Confidential Object confObj) { + // :: error: (assignment) + @NonConfidential String nonConfRes = confObj.toString(); + @Confidential String confRes = confObj.toString(); + } + + void nonConfObj(@NonConfidential Object nonConfObj) { + @NonConfidential String nonConfRes = nonConfObj.toString(); + } +} diff --git a/checker/tests/confidential/SimpleConfidential.java b/checker/tests/confidential/SimpleConfidential.java new file mode 100644 index 00000000000..0834d3ca9e2 --- /dev/null +++ b/checker/tests/confidential/SimpleConfidential.java @@ -0,0 +1,20 @@ +import org.checkerframework.checker.confidential.qual.Confidential; +import org.checkerframework.checker.confidential.qual.NonConfidential; + +public class SimpleConfidential { + + void executeNonConfidential(@NonConfidential String s) {} + + void executeConfidential(@Confidential String s) {} + + void nonConfidentialRef(@NonConfidential String s) { + executeNonConfidential(s); + executeConfidential(s); + } + + void confidentialRef(@Confidential String s) { + // :: error: (argument) + executeNonConfidential(s); + executeConfidential(s); + } +} diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index c9b198d4dc5..c55cb5ac4d3 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -3,6 +3,8 @@ Version 3.49.6 (August 1, 2025) **User-visible changes:** +New Confidential Checker to identify sensitive information exposure. + **Implementation details:** **Closed issues:** @@ -156,6 +158,9 @@ Version 3.46.0 (August 1, 2024) **User-visible changes:** +The new SqlQuotesChecker prevents errors in quoting in SQL queries. It prevents +injection attacks that exploit quoting errors. + Renamed `@EnsuresCalledMethodsVarArgs`to `@EnsuresCalledMethodsVarargs`. **Closed issues:** diff --git a/docs/manual/advanced-features.tex b/docs/manual/advanced-features.tex index 14f3dc5da46..3fce9566073 100644 --- a/docs/manual/advanced-features.tex +++ b/docs/manual/advanced-features.tex @@ -991,6 +991,9 @@ \item \ahrefloc{tainting-checker}{Tainting Checker} for trust and security errors (see \chapterpageref{tainting-checker}) +\item + \ahrefloc{confidential-checker}{Confidential Checker} to identify sensitive + information exposure (see \chapterpageref{confidential-checker}) \item \ahrefloc{guieffect-checker}{GUI Effect Checker} to ensure that non-GUI threads do not access the UI, which would crash the application diff --git a/docs/manual/confidential-checker.tex b/docs/manual/confidential-checker.tex new file mode 100644 index 00000000000..2b62ab6ce88 --- /dev/null +++ b/docs/manual/confidential-checker.tex @@ -0,0 +1,149 @@ +\htmlhr +\chapterAndLabel{Confidential Checker for information leakage}{confidential-checker} + +The Confidential Checker identifies +\href{https://cwe.mitre.org/data/definitions/1417.html}{sensitive information +exposure}, also known as information leakage. An information leak occurs +when private information is revealed by being passed to a public-facing +sink, such as website and app user interfaces, log files, error messages, +and URL targets. Private information includes PII (personally identifiable +information), passwords, local file paths, or whatever data the user +chooses. + +The Confidential Checker guarantees that no values marked as +\emph{confidential} flow to a location marked as \emph{non-confidential}. + +It is the responsibility of the user to annotate sources and sinks as +confidential or non-confidential. Sources are locations where information +is created, such as being read from a file. Sinks are locations where +information is used, such as being displayed on a screen or printed to a +log. The Confidential Checker ships with many sinks annotated, both in the +JDK and in popular libraries, but the user may want to annotate more sinks. + +Since \code{@NonConfidential} is the default annotation, if a programmer +forgets to annotate a sensitive source as \<@Confidential>, then there will +be an information leak that the Confidential Checker cannot warn about. +Once sources and sinks are annotated, the Confidential Checker guarantees +that any other annotations in the program are consistent with those +annotations, and that no information flows from confidential to +non-confidential locations. + +Exposure may occur mistakenly --- in which case +it should be fixed --- or with a benign objective in mind, such as when +logging to aid troubleshooting. After the Confidential Checker reveals a +leak, it is up to the user to decide whether the leakage is acceptable. + +To run the Confidential Checker, supply one of these +command-line options to javac: +\begin{Verbatim} +-processor ConfidentialChecker +-processor org.checkerframework.checker.confidential.ConfidentialChecker +\end{Verbatim} + + +\sectionAndLabel{Only direct leakage, via a chain of assignments}{confidential-direct-only} + +The Confidential Checker does \emph{not} identify \emph{indirect} +information flows, such as in: + +\begin{Verbatim} + // Information is leaked, but the Confidential Checker issues no error. + @Confidential boolean secret = ...; + @NonConfidential boolean revealed; + if (secret) { + revealed = true; + } else { + revealed = false; + } +\end{Verbatim} + + +\sectionAndLabel{Confidential annotations}{confidential-annotations} + +The Confidential Checker type system uses the following type qualifiers. +Figure~\ref{fig-confidential-hierarchy} shows their subtyping hierarchy. + +\begin{description} +\item[\refqualclass{checker/confidential/qual}{Confidential}] + An expression whose type is qualified with + \refqualclass{checker/confidential/qual}{Confidential} may evaluate to + a value that should not be exposed. +\item[\refqualclass{checker/confidential/qual}{NonConfidential}] + The value of an expression of type + \refqualclass{checker/confidential/qual}{NonConfidential} might be + exposed. It is written on the formal parameter type of a method such + as \ that may leak its argument. It is the default qualifier. +\item[\refqualclass{checker/confidential/qual}{UnknownConfidential}] + indicates a value whose confidentiality is unknown. + \code{@UnknownConfidential} is a supertype of \code{@Confidential} + and \code{@NonConfidential}. +\item[\refqualclass{checker/confidential/qual}{PolyConfidential}] + indicates qualifier polymorphism. For a description of qualifier polymorphism, + see Section~\ref{method-qualifier-polymorphism}. +\item[\refqualclass{checker/confidential/qual}{BottomConfidential}] + is the bottom qualifier. Programmers rarely need to write it. +\end{description} + + +\begin{figure} +\includeimage{confidential}{5.5cm} +\caption{The subtyping relationship of the Confidential Checker's qualifiers. + Any cast to \refqualclass{checker/confidential/qual}{Confidential} is permitted. + Qualifiers in gray are used internally by the type system and should rarely + be written by a programmer. +} +\label{fig-confidential-hierarchy} +\end{figure} + +The Confidential Checker's \code{@Confidential} qualifier has similarities +to the Taint Checker's \code{@Tainted} qualifier. One difference is that +there is no subtyping relationship between \code{@Confidential} and +\code{@NonConfidential}. However, the external behavior of these annotations +can strongly resemble that of a supertype and subtype, as casts from the +latter to the former are always permitted. As a result, while the +Confidential Checker (correctly) does not allow \code{@Confidential} values +to flow to \code{@NonConfidential} sinks, it does allow +\code{@NonConfidential} values in \code{@Confidential} sinks. + +\sectionAndLabel{Concatenation}{confidential-concatenation} + +Concatenation of \code{@Confidential} and \code{@NonConfidential} values +results in a \code{@Confidential} value. In other words, concatenation of +\code{@Confidential} and \code{@NonConfidential} values are most narrowly typed +as follows: + +\begin{Verbatim} + @Confidential String c; + @NonConfidential String nc; + c + c // has type @Confidential + c + nc // has type @Confidential + nc + c // has type @Confidential + nc + nc // has type @NonConfidential +\end{Verbatim} + + +\sectionAndLabel{Library annotations}{confidential-library-annotations} + +The Confidential Checker provides annotations for certain public-facing +sinks. For instance, methods in Android's \code{TextView} class have a +formal parameter of type \code{@NonConfidential CharSequence}, indicating +that they display the argument on the user's viewport. The Confidential +Checker will issue a type error anywhere that a \<@Confidential> value can +be passed to such functions. + +The built-in annotations appear in the Checker +Framework's annotated JDK and in stub files in directory +\. +A developer can write more annotations in stub files +(\sectionpageref{stub}), especially for libraries that do not already have +annotations. (Please share these with the Checker Framework developers, so +that they can distribute them to all users.) + +If a program contains a method that tests whether a run-time value is +confidential, use annotation +\refqualclass{framework/qual}{EnsuresQualifierIf} (\sectionpageref{type-refinement}). + +If a program contains a method that takes a possibly-confidential argument +and returns a non-confidential result, then suppress the warning +(\chapterpageref{suppressing-warnings}) after manually validating the +method's behavior. diff --git a/docs/manual/figures/confidential.svg b/docs/manual/figures/confidential.svg new file mode 100644 index 00000000000..d1d32fbf236 --- /dev/null +++ b/docs/manual/figures/confidential.svg @@ -0,0 +1,325 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + @Confidential + + + @NonConfidential + + + + + @UnknownConfidential + + + + + @BottomConfidential + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/manual/hevea.sty b/docs/manual/hevea.sty new file mode 100644 index 00000000000..b194858167f --- /dev/null +++ b/docs/manual/hevea.sty @@ -0,0 +1,90 @@ +% hevea : hevea.sty +% This is a very basic style file for latex document to be processed +% with hevea. It contains definitions of LaTeX environment which are +% processed in a special way by the translator. +% Mostly : +% - latexonly, not processed by hevea, processed by latex. +% - htmlonly , the reverse. +% - rawhtml, to include raw HTML in hevea output. +% - toimage, to send text to the image file. +% The package also provides hevea logos, html related commands (ahref +% etc.), void cutting and image commands. +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{hevea}[2002/01/11] +\RequirePackage{comment} +\newif\ifhevea\heveafalse +\@ifundefined{ifimagen}{\newif\ifimagen\imagenfalse} +\makeatletter% +\newcommand{\heveasmup}[2]{% +\raise #1\hbox{$\m@th$% + \csname S@\f@size\endcsname + \fontsize\sf@size 0% + \math@fontsfalse\selectfont +#2% +}}% +\DeclareRobustCommand{\hevea}{H\kern-.15em\heveasmup{.2ex}{E}\kern-.15emV\kern-.15em\heveasmup{.2ex}{E}\kern-.15emA}% +\DeclareRobustCommand{\hacha}{H\kern-.15em\heveasmup{.2ex}{A}\kern-.15emC\kern-.1em\heveasmup{.2ex}{H}\kern-.15emA}% +\DeclareRobustCommand{\html}{\protect\heveasmup{0.ex}{HTML}} +%%%%%%%%% Hyperlinks hevea style +\newcommand{\ahref}[2]{{#2}} +\newcommand{\ahrefloc}[2]{{#2}} +\newcommand{\aname}[2]{{#2}} +\newcommand{\ahrefurl}[1]{\texttt{#1}} +\newcommand{\footahref}[2]{#2\footnote{\texttt{#1}}} +\newcommand{\mailto}[1]{\texttt{#1}} +\newcommand{\imgsrc}[2][]{} +\newcommand{\home}[1]{\protect\raisebox{-.75ex}{\char126}#1} +\AtBeginDocument +{\@ifundefined{url} +{%url package is not loaded +\let\url\ahref\let\oneurl\ahrefurl\let\footurl\footahref} +{}} +%% Void cutting instructions +\newcounter{cuttingdepth} +\newcommand{\tocnumber}{} +\newcommand{\notocnumber}{} +\newcommand{\cuttingunit}{} +\newcommand{\cutdef}[2][]{} +\newcommand{\cuthere}[2]{} +\newcommand{\cutend}{} +\newcommand{\htmlhead}[1]{} +\newcommand{\htmlfoot}[1]{} +\newcommand{\htmlprefix}[1]{} +\newenvironment{cutflow}[1]{}{} +\newcommand{\cutname}[1]{} +\newcommand{\toplinks}[3]{} +\newcommand{\setlinkstext}[3]{} +\newcommand{\flushdef}[1]{} +\newcommand{\footnoteflush}[1]{} +%%%% Html only +\excludecomment{rawhtml} +\newcommand{\rawhtmlinput}[1]{} +\excludecomment{htmlonly} +%%%% Latex only +\newenvironment{latexonly}{}{} +\newenvironment{verblatex}{}{} +%%%% Image file stuff +\def\toimage{\endgroup} +\def\endtoimage{\begingroup\def\@currenvir{toimage}} +\def\verbimage{\endgroup} +\def\endverbimage{\begingroup\def\@currenvir{verbimage}} +\newcommand{\imageflush}[1][]{} +%%% Bgcolor definition +\newsavebox{\@bgcolorbin} +\newenvironment{bgcolor}[2][] + {\newcommand{\@mycolor}{#2}\begin{lrbox}{\@bgcolorbin}\vbox\bgroup} + {\egroup\end{lrbox}% + \begin{flushleft}% + \colorbox{\@mycolor}{\usebox{\@bgcolorbin}}% + \end{flushleft}} +%%% Style sheets macros, defined as no-ops +\newcommand{\newstyle}[2]{} +\newcommand{\addstyle}[1]{} +\newcommand{\setenvclass}[2]{} +\newcommand{\getenvclass}[1]{} +\newcommand{\loadcssfile}[1]{} +\newenvironment{divstyle}[1]{}{} +\newenvironment{cellstyle}[2]{}{} +\newif\ifexternalcss +%%% Postlude +\makeatother diff --git a/docs/manual/manual.tex b/docs/manual/manual.tex index dae9d7bdd4c..687c277a3b7 100644 --- a/docs/manual/manual.tex +++ b/docs/manual/manual.tex @@ -63,6 +63,7 @@ % These are related to tainting: \input{tainting-checker.tex} \input{sql-quotes-checker.tex} +\input{confidential-checker.tex} % These are focused on strings: \input{regex-checker.tex} diff --git a/framework/tests/all-systems/Issue577.java b/framework/tests/all-systems/Issue577.java index df27c3a9a6f..c6cbb3c26f2 100644 --- a/framework/tests/all-systems/Issue577.java +++ b/framework/tests/all-systems/Issue577.java @@ -58,6 +58,7 @@ void foo1(MyInterface param) throws Throwable { try { bar(); } catch (MyExceptionA | MyExceptionB ex1) { + @SuppressWarnings("confidential") // true positive: exception might be UnknownConfidential String s = ex1.getT(); } } diff --git a/framework/tests/all-systems/Issue6282.java b/framework/tests/all-systems/Issue6282.java index 3e99d2129cf..b590feebf3e 100644 --- a/framework/tests/all-systems/Issue6282.java +++ b/framework/tests/all-systems/Issue6282.java @@ -9,6 +9,7 @@ public static final MethodHandle setAccessible0_Method() { throw new RuntimeException(); } + @SuppressWarnings("confidential") // true positive: thrown exception might be @UnknownConfidential public static void setAccessible(final AccessibleObject accessibleObject) { try { diff --git a/framework/tests/all-systems/MultipleUnions.java b/framework/tests/all-systems/MultipleUnions.java index aafe839d92f..bc1b9afc29d 100644 --- a/framework/tests/all-systems/MultipleUnions.java +++ b/framework/tests/all-systems/MultipleUnions.java @@ -1,7 +1,10 @@ public class MultipleUnions { public static boolean flag = false; - @SuppressWarnings("ainfertest") // only check WPI for crashes + @SuppressWarnings({ + "ainfertest", // only check WPI for crashes + "confidential" // true positive: thrown exception might be @UnknownConfidential + }) void foo1(MyInterface param) throws Throwable { try { bar(); diff --git a/framework/tests/all-systems/UnionCrash.java b/framework/tests/all-systems/UnionCrash.java index 3ea9d253a66..de0b04ea3a7 100644 --- a/framework/tests/all-systems/UnionCrash.java +++ b/framework/tests/all-systems/UnionCrash.java @@ -1,7 +1,10 @@ // Test case for issue #775 // https://github.com/typetools/checker-framework/issues/775 -@SuppressWarnings("ainfertest") // only check WPI for crashes +@SuppressWarnings({ + "ainfertest", // only check WPI for crashes + "confidential" // true positive: thrown exception might be @UnknownConfidential +}) public class UnionCrash { void foo(MyInterface param) throws Throwable { try { diff --git a/framework/tests/all-systems/UnionTypes.java b/framework/tests/all-systems/UnionTypes.java index 4fc1717e433..dbfc5b7724b 100644 --- a/framework/tests/all-systems/UnionTypes.java +++ b/framework/tests/all-systems/UnionTypes.java @@ -6,6 +6,7 @@ public void TryCatch() { int[] arr = new int[10]; arr[4] = 1; } catch (ArrayIndexOutOfBoundsException | StringIndexOutOfBoundsException exc) { + @SuppressWarnings("confidential") // true positive: exception might be @UnknownConfidential Exception e = exc; } } diff --git a/framework/tests/all-systems/Unions.java b/framework/tests/all-systems/Unions.java index 3837a84e49c..1c048dcd421 100644 --- a/framework/tests/all-systems/Unions.java +++ b/framework/tests/all-systems/Unions.java @@ -1,5 +1,6 @@ @SuppressWarnings("ainfertest") // only check WPI for crashes public class Unions { + @SuppressWarnings("confidential") // true positive: thrown exception might be @UnknownConfidential void foo1(MyInterface param) throws Throwable { try { bar(); @@ -12,6 +13,7 @@ void foo1(MyInterface param) throws Throwable { } } + @SuppressWarnings("confidential") // true positive: thrown exception might be @UnknownConfidential void foo2(MyInterface param) throws Throwable { try { bar();