1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.os.strictmode;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.app.PendingIntent;
22 import android.content.Intent;
23 import android.net.Uri;
24 
25 import java.util.Objects;
26 
27 /**
28  * Violation raised when your app launches an {@link Intent} which originated
29  * from outside your app.
30  * <p>
31  * Violations may indicate security vulnerabilities in the design of your app,
32  * where a malicious app could trick you into granting {@link Uri} permissions
33  * or launching unexported components. Here are some typical design patterns
34  * that can be used to safely resolve these violations:
35  * <ul>
36  * <li>The ideal approach is to migrate to using a {@link PendingIntent}, which
37  * ensures that your launch is performed using the identity of the original
38  * creator, completely avoiding the security issues described above.
39  * <li>If using a {@link PendingIntent} isn't feasible, an alternative approach
40  * is to create a brand new {@link Intent} and carefully copy only specific
41  * values from the original {@link Intent} after careful validation.
42  * </ul>
43  * <p>
44  * Note that this <em>may</em> detect false-positives if your app sends itself
45  * an {@link Intent} which is first routed through the OS, such as using
46  * {@link Intent#createChooser}. In these cases, careful inspection is required
47  * to determine if the return point into your app is appropriately protected
48  * with a signature permission or marked as unexported. If the return point is
49  * not protected, your app is likely vulnerable to malicious apps.
50  */
51 public final class UnsafeIntentLaunchViolation extends Violation {
52     private transient Intent mIntent;
53 
UnsafeIntentLaunchViolation(@onNull Intent intent)54     public UnsafeIntentLaunchViolation(@NonNull Intent intent) {
55         super("Launch of unsafe intent: " + intent);
56         mIntent = Objects.requireNonNull(intent);
57     }
58 
59     /** @hide */
UnsafeIntentLaunchViolation(@onNull Intent intent, @NonNull String message)60     public UnsafeIntentLaunchViolation(@NonNull Intent intent, @NonNull String message) {
61         super(message);
62         mIntent = Objects.requireNonNull(intent);
63     }
64 
65     /**
66      * Return the {@link Intent} which caused this violation to be raised. Note
67      * that this value is not available if this violation has been serialized
68      * since intents cannot be serialized.
69      */
70     @SuppressWarnings("IntentBuilderName")
getIntent()71     public @Nullable Intent getIntent() {
72         return mIntent;
73     }
74 }
75