prevent search terms triggering SQL injection vulns
This commit is contained in:
		
							parent
							
								
									38e4b05e56
								
							
						
					
					
						commit
						018e3221a7
					
				@ -37,7 +37,6 @@ import android.view.ViewGroup;
 | 
			
		||||
import android.widget.LinearLayout;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import android.widget.Toast;
 | 
			
		||||
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.annotation.Nullable;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
@ -45,11 +44,9 @@ import androidx.core.content.ContextCompat;
 | 
			
		||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
 | 
			
		||||
import androidx.recyclerview.widget.LinearLayoutManager;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
 | 
			
		||||
import com.ashokvarma.bottomnavigation.BottomNavigationBar;
 | 
			
		||||
import com.ashokvarma.bottomnavigation.BottomNavigationItem;
 | 
			
		||||
import com.ashokvarma.bottomnavigation.TextBadgeItem;
 | 
			
		||||
 | 
			
		||||
import org.fdroid.fdroid.AppUpdateStatusManager;
 | 
			
		||||
import org.fdroid.fdroid.AppUpdateStatusManager.AppUpdateStatus;
 | 
			
		||||
import org.fdroid.fdroid.BuildConfig;
 | 
			
		||||
@ -305,6 +302,11 @@ public class MainActivity extends AppCompatActivity implements BottomNavigationB
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Since any app could send this {@link Intent}, and the search terms are
 | 
			
		||||
     * fed into a SQL query, the data must be strictly sanitized to avoid
 | 
			
		||||
     * SQL injection attacks.
 | 
			
		||||
     */
 | 
			
		||||
    private void handleSearchOrAppViewIntent(Intent intent) {
 | 
			
		||||
        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
 | 
			
		||||
            String query = intent.getStringExtra(SearchManager.QUERY);
 | 
			
		||||
@ -391,6 +393,8 @@ public class MainActivity extends AppCompatActivity implements BottomNavigationB
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!TextUtils.isEmpty(packageName)) {
 | 
			
		||||
            // sanitize packageName to be a valid Java packageName and prevent exploits
 | 
			
		||||
            packageName = packageName.replaceAll("[^A-Za-z\\d_.]", "");
 | 
			
		||||
            Utils.debugLog(TAG, "FDroid launched via app link for '" + packageName + "'");
 | 
			
		||||
            Intent intentToInvoke = new Intent(this, AppDetailsActivity.class);
 | 
			
		||||
            intentToInvoke.putExtra(AppDetailsActivity.EXTRA_APPID, packageName);
 | 
			
		||||
@ -402,12 +406,19 @@ public class MainActivity extends AppCompatActivity implements BottomNavigationB
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * These strings might end up in a SQL query, so strip all non-alpha-num
 | 
			
		||||
     */
 | 
			
		||||
    static String sanitizeSearchTerms(String query) {
 | 
			
		||||
        return query.replaceAll("[^\\p{L}\\d_ -]", " ");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Initiates the {@link AppListActivity} with the relevant search terms passed in via the query arg.
 | 
			
		||||
     */
 | 
			
		||||
    private void performSearch(String query) {
 | 
			
		||||
        Intent searchIntent = new Intent(this, AppListActivity.class);
 | 
			
		||||
        searchIntent.putExtra(AppListActivity.EXTRA_SEARCH_TERMS, query);
 | 
			
		||||
        searchIntent.putExtra(AppListActivity.EXTRA_SEARCH_TERMS, sanitizeSearchTerms(query));
 | 
			
		||||
        startActivity(searchIntent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,7 @@ import org.junit.Test;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
 | 
			
		||||
import static org.junit.Assert.assertEquals;
 | 
			
		||||
import static org.junit.Assert.assertNotEquals;
 | 
			
		||||
import static org.junit.Assume.assumeTrue;
 | 
			
		||||
 | 
			
		||||
public class SanitizedFileTest {
 | 
			
		||||
@ -45,4 +46,13 @@ public class SanitizedFileTest {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testSanitizeFileName() {
 | 
			
		||||
        for (String valid : new String[]{"An.stop", "a.0", "packageName", "com.this-and-that", "A_.o"}) {
 | 
			
		||||
            assertEquals(valid, SanitizedFile.sanitizeFileName(valid));
 | 
			
		||||
        }
 | 
			
		||||
        for (String invalid : new String[]{"'--;DROP", "a.0)", "packageName\n"}) {
 | 
			
		||||
            assertNotEquals(invalid, SanitizedFile.sanitizeFileName(invalid));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,25 @@
 | 
			
		||||
package org.fdroid.fdroid.views.main;
 | 
			
		||||
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
 | 
			
		||||
import static org.junit.Assert.assertEquals;
 | 
			
		||||
import static org.junit.Assert.assertNotEquals;
 | 
			
		||||
 | 
			
		||||
public class MainActivityTest {
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testSanitizeSearchTerms() {
 | 
			
		||||
        for (String valid : new String[]{"private browser", "πÇÇ", "现代 通用字", "български", "عربي"}) {
 | 
			
		||||
            assertEquals(valid, MainActivity.sanitizeSearchTerms(valid));
 | 
			
		||||
        }
 | 
			
		||||
        for (String invalid : new String[]{
 | 
			
		||||
                "Robert'); DROP TABLE Students; --",
 | 
			
		||||
                "xxx') OR 1 = 1 -- ]",
 | 
			
		||||
                "105 OR 1=1;",
 | 
			
		||||
                "\" OR \"=\"",
 | 
			
		||||
        }) {
 | 
			
		||||
            assertNotEquals(invalid, MainActivity.sanitizeSearchTerms(invalid));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user