Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add protection for raw sign #3288

Merged
merged 2 commits into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ public interface PreferenceRepositoryType

void setUse1559Transactions(boolean toggleState);

boolean getDeveloperOverride();

void setDeveloperOverride(boolean toggleState);

boolean isTestnetEnabled();

void setTestnetEnabled(boolean enabled);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public class SharedPreferenceRepository implements PreferenceRepositoryType {
public static final String HIDE_ZERO_BALANCE_TOKENS = "hide_zero_balance_tokens";
public static final String FULL_SCREEN_STATE = "full_screen";
public static final String EXPERIMENTAL_1559_TX = "ex_1559_tx";
public static final String DEVELOPER_OVERRIDE = "developer_override";
public static final String TESTNET_ENABLED = "testnet_enabled";
public static final String PRICE_ALERTS = "price_alerts";
private static final String SET_NETWORK_FILTERS = "set_filters";
Expand Down Expand Up @@ -184,6 +185,18 @@ public void setUse1559Transactions(boolean state)
pref.edit().putBoolean(EXPERIMENTAL_1559_TX, state).apply();
}

@Override
public boolean getDeveloperOverride()
{
return pref.getBoolean(DEVELOPER_OVERRIDE, false);
}

@Override
public void setDeveloperOverride(boolean state)
{
pref.edit().putBoolean(DEVELOPER_OVERRIDE, state).apply();
}

@Override
public boolean isTestnetEnabled()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public class AdvancedSettingsActivity extends BaseActivity
private SettingsItemView eip1559Transactions;
private SettingsItemView analytics;
private SettingsItemView crashReporting;
private SettingsItemView developerOverride;
private AWalletAlertDialog waitDialog = null;

@Nullable
Expand Down Expand Up @@ -142,8 +143,21 @@ private void initializeSettings()
.withListener(this::onCrashReportingClicked)
.build();

developerOverride = new SettingsItemView.Builder(this)
.withType(SettingsItemView.Type.TOGGLE)
.withIcon(R.drawable.ic_settings_warning)
.withTitle(R.string.developer_override)
.withListener(this::onDeveloperOverride)
.build();

fullScreenSettings.setToggleState(viewModel.getFullScreenState());
eip1559Transactions.setToggleState(viewModel.get1559TransactionsState());
developerOverride.setToggleState(viewModel.getDeveloperOverrideState());
}

private void onDeveloperOverride()
{
viewModel.toggleDeveloperOverride(developerOverride.getToggleState());
}

private void onFullScreenClicked()
Expand Down Expand Up @@ -172,6 +186,7 @@ private void addSettingsToLayout()
advancedSettingsLayout.addView(eip1559Transactions);
advancedSettingsLayout.addView(analytics);
advancedSettingsLayout.addView(crashReporting);
advancedSettingsLayout.addView(developerOverride);
}

private void onNodeStatusClicked()
Expand Down
20 changes: 19 additions & 1 deletion app/src/main/java/com/alphawallet/app/util/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,22 @@
import android.content.pm.InstallSourceInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.Build;
import android.text.Spannable;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan;
import android.util.Base64;
import android.util.TypedValue;
import android.webkit.URLUtil;

import androidx.annotation.ColorInt;
import androidx.annotation.RawRes;
import androidx.annotation.StyleRes;
import androidx.fragment.app.FragmentActivity;

import com.alphawallet.app.BuildConfig;
Expand Down Expand Up @@ -221,7 +225,7 @@ public static int getSigningTitle(Signable signable)
{
default:
case SIGN_MESSAGE:
return R.string.dialog_title_sign_message;
return R.string.dialog_title_sign_message_sheet; //warn user this is unsafe
case SIGN_PERSONAL_MESSAGE:
return R.string.dialog_title_sign_personal_message;
case SIGN_TYPED_DATA:
Expand All @@ -231,6 +235,20 @@ public static int getSigningTitle(Signable signable)
}
}

public static CharSequence getSignMessageTitle(String message)
{
//produce readable text to display in the signing prompt
StyledStringBuilder sb = new StyledStringBuilder();
sb.startStyleGroup();
sb.append(message);
int i = message.length();
sb.setSpan(new ForegroundColorSpan(Color.RED), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
sb.setSpan(new ForegroundColorSpan(Color.RED), i-1, i, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
sb.applyStyles();

return sb;
}

public static CharSequence formatTypedMessage(ProviderTypedData[] rawData)
{
//produce readable text to display in the signing prompt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,16 @@ public boolean get1559TransactionsState()
return preferenceRepository.getUse1559Transactions();
}

public boolean getDeveloperOverrideState()
{
return preferenceRepository.getDeveloperOverride();
}

public void toggleDeveloperOverride(boolean toggleState)
{
preferenceRepository.setDeveloperOverride(toggleState);
}

public boolean getFullScreenState()
{
return preferenceRepository.getFullScreenState();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package com.alphawallet.app.walletconnect;

import static com.alphawallet.app.repository.SharedPreferenceRepository.DEVELOPER_OVERRIDE;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentManager;
import androidx.preference.PreferenceManager;

import com.alphawallet.app.R;
import com.alphawallet.app.entity.walletconnect.SignType;
Expand All @@ -17,6 +21,8 @@
import com.alphawallet.app.widget.AWalletAlertDialog;
import com.alphawallet.app.widget.ActionSheet;
import com.alphawallet.app.widget.ActionSheetSignDialog;
import com.alphawallet.token.entity.EthereumMessage;
import com.alphawallet.token.entity.SignMessageType;
import com.alphawallet.token.entity.Signable;
import com.walletconnect.web3.wallet.client.Wallet;

Expand Down Expand Up @@ -72,9 +78,13 @@ private void showDialog(String method, ActionSheetCallback aCallback)
{
Signable signable = signRequest.getSignable(sessionRequest.getRequest().getId(),
Objects.requireNonNull(settledSession.getMetaData()).getUrl());
if (!validateChainId(signable))
if (signable.isDangerous())
{
showNotSigning(aCallback, signRequest, signable);
}
else if (!validateChainId(signable))
{
showErrorDialog(aCallback, signable, getSessionItem());
checkProceed(aCallback, signRequest, signable);
}
else
{
Expand All @@ -98,7 +108,7 @@ private boolean validateChainId(Signable signable)
case SIGN_TYPED_DATA_V3:
case SIGN_TYPED_DATA_V4:
return (signable.getChainId() == -1 || //if chainId is unspecified treat as no restriction intended
!getChainListFromSession().contains(signable.getChainId()));
getChainListFromSession().contains(signable.getChainId()));
case ATTESTATION:
//TODO: Check attestation signing chain
return true;
Expand Down Expand Up @@ -143,6 +153,25 @@ private void showActionSheet(ActionSheetCallback aCallback, BaseRequest signRequ
actionSheet.show();
}

private void checkProceed(ActionSheetCallback aCallback, BaseRequest signRequest, Signable signable)
{
AWalletAlertDialog errorDialog = new AWalletAlertDialog(activity, AWalletAlertDialog.ERROR);
String networkName = EthereumNetworkBase.isChainSupported(signable.getChainId()) ? EthereumNetworkBase.getShortChainName(signable.getChainId())
: Long.toString(signable.getChainId());
String message = activity.getString(R.string.session_not_authorised, networkName);
errorDialog.setMessage(message);
errorDialog.setButton(R.string.override, v -> {
errorDialog.dismiss();
showActionSheet(aCallback, signRequest, signable);
});
errorDialog.setSecondaryButton(R.string.action_cancel, v -> {
errorDialog.dismiss();
cancelRequest(aCallback, signable, errorDialog);
});
errorDialog.setCancelable(false);
errorDialog.show();
}

private void showErrorDialog(ActionSheetCallback aCallback, Signable signable, WalletConnectV2SessionItem session)
{
AWalletAlertDialog errorDialog = new AWalletAlertDialog(activity, AWalletAlertDialog.ERROR);
Expand All @@ -154,10 +183,32 @@ private void showErrorDialog(ActionSheetCallback aCallback, Signable signable, W
errorDialog.setButton(R.string.action_view_session, v -> {
openSessionDetail(session);
cancelRequest(aCallback, signable, errorDialog);
errorDialog.dismiss();
});
errorDialog.setSecondaryButton(R.string.action_cancel, v -> {
cancelRequest(aCallback, signable, errorDialog);
errorDialog.dismiss();
});
errorDialog.setCancelable(false);
errorDialog.show();
}

private void showNotSigning(ActionSheetCallback aCallback, BaseRequest signRequest, Signable signable)
{
final SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(activity);
boolean hasDeveloperOverride = pref.getBoolean(DEVELOPER_OVERRIDE, false);
AWalletAlertDialog errorDialog = new AWalletAlertDialog(activity, AWalletAlertDialog.ERROR);
errorDialog.setMessage(activity.getString(R.string.override_warning_text));
errorDialog.setButton(R.string.action_cancel, v -> {
cancelRequest(aCallback, signable, errorDialog);
});
if (hasDeveloperOverride)
{
errorDialog.setSecondaryButton(R.string.override, v -> {
showActionSheet(aCallback, signRequest, signable);
errorDialog.dismiss();
});
}
errorDialog.setCancelable(false);
errorDialog.show();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.alphawallet.app.viewmodel.SignDialogViewModel;
import com.alphawallet.hardware.SignatureFromKey;
import com.alphawallet.hardware.SignatureReturnType;
import com.alphawallet.token.entity.SignMessageType;
import com.alphawallet.token.entity.Signable;
import com.bumptech.glide.Glide;

Expand Down Expand Up @@ -93,6 +94,11 @@ private void setupView()
functionBar.setPrimaryButtonEnabled(true);
});
}
else if (signable.getMessageType() == SignMessageType.SIGN_MESSAGE)
{
toolbar.setTitle(Utils.getSignMessageTitle(getContext().getString(R.string.dialog_title_sign_message_sheet)));
signWidget.setupSignData(signable);
}
else
{
toolbar.setTitle(Utils.getSigningTitle(signable));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import com.alphawallet.app.R;
import com.alphawallet.app.entity.ActionSheetInterface;
import com.alphawallet.token.entity.SignMessageType;
import com.alphawallet.token.entity.Signable;

/**
Expand Down Expand Up @@ -98,8 +99,19 @@ public void setupSignData(Signable signable)
{
this.signable = signable;
String message = signable.getUserMessage().toString();
previewText.setText(message);
messageText.setText(message);

if (signable.getMessageType() == SignMessageType.SIGN_MESSAGE) //Warn user that sign is dangerous
{
((ImageView)findViewById(R.id.image_sign_warning)).setVisibility(View.VISIBLE);
previewText.setText(R.string.sign_message_could_be_a_scam);
message = getContext().getString(R.string.sign_message_could_be_a_scam2) + "\n\n" + message;
messageText.setText(message);
}
else
{
previewText.setText(message);
messageText.setText(message);
}

layoutHolder.setOnClickListener(v -> {
if (previewText.getVisibility() == View.VISIBLE)
Expand Down Expand Up @@ -140,4 +152,4 @@ public interface ScrollListener
{
void hasScrolledToBottom();
}
}
}
5 changes: 5 additions & 0 deletions app/src/main/res/drawable/ic_settings_warning.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<vector android:height="40dp" android:viewportHeight="24"
android:viewportWidth="24" android:width="40dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF3B30" android:fillType="evenOdd" android:pathData="M2.52,22.586h18.96c1.94,0 3.148,-2.068 2.178,-3.714l-9.48,-16.11c-0.97,-1.647 -3.387,-1.647 -4.356,0l-9.48,16.11c-0.97,1.646 0.239,3.714 2.178,3.714z"/>
<path android:fillColor="#FFF" android:fillType="evenOdd" android:pathData="M13.333,19.076h-2.666v-2.632h2.666zM12,14.689a1.329,1.329 0,0 1,-1.333 -1.316V10.74c0,-0.724 0.6,-1.316 1.333,-1.316s1.333,0.592 1.333,1.316v2.633c0,0.724 -0.6,1.316 -1.333,1.316z"/>
</vector>
39 changes: 27 additions & 12 deletions app/src/main/res/layout/item_sign_data.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,28 +28,43 @@
android:gravity="start|center_vertical"
android:text="@string/message_to_sign" />

<LinearLayout
JamesSmartCell marked this conversation as resolved.
Show resolved Hide resolved
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="@integer/widget_content"
android:layout_marginHorizontal="@dimen/small_12"
android:gravity="start">

<ImageView
android:id="@+id/image_sign_warning"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
tools:visibility="visible"
android:src="@drawable/ic_red_warning"/>

<TextView
android:id="@+id/text_preview"
style="@style/Aw.Typography.Caption"
android:layout_width="0dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/small_12"
android:layout_weight="@integer/widget_content"
android:ellipsize="end"
android:gravity="start"
android:maxLines="1"
android:visibility="visible"
tools:text="Message:\n Hi Alice!\nA number:\n 1337\nMessage:\n Hi Alice!\nA number:\n 1337\nMessage:\n Hi Alice!\nA number:\n 1337\nMessage:\n Hi Alice!\nA number:\n 1337\nMessage:\n Hi Alice!\nA number:\n 1337\nMessage:\n Hi Alice!\nA number:\n 1337\nMessage:\n Hi Alice!\nA number:\n 1337" />

</LinearLayout>

<ImageView
JamesSmartCell marked this conversation as resolved.
Show resolved Hide resolved
android:id="@+id/image_more"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_weight="@integer/widget_control"
android:background="@color/transparent"
android:src="@drawable/ic_expand_more"
app:tint="?colorControlNormal" />
android:id="@+id/image_more"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_weight="@integer/widget_control"
android:background="@color/transparent"
android:src="@drawable/ic_expand_more"
app:tint="?colorControlNormal" />

</LinearLayout>

Expand All @@ -72,4 +87,4 @@

</ScrollView>

</LinearLayout>
</LinearLayout>
7 changes: 7 additions & 0 deletions app/src/main/res/values-es/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,9 @@
<string name="signer_address">Dirección</string>
<string name="requester_url">Solicitante</string>
<string name="dialog_title_sign_message">Firmar mensaje</string>
<string name="dialog_title_sign_message_sheet">⚠ Firmar mensaje ⚠</string>
<string name="sign_message_could_be_a_scam">Peligro: Verifique antes de firmar</string>
<string name="sign_message_could_be_a_scam2">Podría estar en peligro de perder sus tokens, especialmente si esta solicitud proviene de un \'airdrop\'. Sign Message es utilizado principalmente por estafadores. Haga una búsqueda en la web de este sitio web y utilice \'estafa\'.</string>
<string name="dialog_title_sign_personal_message">Firmar \'Personal\' mensaje</string>
<string name="dialog_title_sign_typed_message">Firmar \'Typed\' mensaje</string>
<string name="dialog_reject">Rechazar</string>
Expand Down Expand Up @@ -988,4 +991,8 @@
<string name="imported_smart_pass">Smart Pass importado</string>
<string name="smartpass_imported">Se ha importado un pase inteligente. Su pase debe ser actualizado.</string>
<string name="no_connection_to_smart_layer">No hay conexión a la red Smart Layer: intente importar su Pass nuevamente más tarde.</string>
<string name="session_not_authorised">Esta sesión no está autorizada para firmar mensajes en %s, sin embargo, puedes evitar esta restricción para firmar. Con mensaje escrito no hay peligro.</string>
<string name="override">Anular</string>
<string name="developer_override">Anulación del Desarrollador</string>
<string name="override_warning_text">Es posible que esté a punto de firmar una transacción sin saberlo, lo que podría vaciar sus fondos. Es posible que desee firmar el código de bytes como desarrollador y puede anular esta advertencia si configura el modo de desarrollador en la configuración avanzada.</string>
</resources>
Loading
Loading