Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
45 changes: 45 additions & 0 deletions .github/workflows/android-lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Android Lint

on:
push:
branches: [master, dev]
paths:
- 'src/MobileShepherd/MobileShepherd/**'
pull_request:
branches: [master, dev]
paths:
- 'src/MobileShepherd/MobileShepherd/**'

jobs:
android-lint:
runs-on: ubuntu-latest
defaults:
run:
working-directory: src/MobileShepherd/MobileShepherd

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'

- name: Setup Android SDK
uses: android-actions/setup-android@v2

- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Run Android Lint
run: ./gradlew lintDebug

- name: Upload Lint Results
if: always()
uses: actions/upload-artifact@v4
with:
name: android-lint-report
path: src/MobileShepherd/MobileShepherd/app/build/reports/lint-results-debug.html
retention-days: 30
66 changes: 66 additions & 0 deletions .github/workflows/build-and-publish-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: build-and-publish-dev
on:
workflow_dispatch:
# Disabled for fork - requires Google Cloud credentials
# push:
# branches:
# - "dev"

permissions:
contents: read
id-token: write

jobs:
build-and-publish:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- id: "auth"
name: "Authenticate to Google Cloud"
uses: "google-github-actions/auth@v2"
with:
token_format: "access_token"
workload_identity_provider: ${{secrets.WORKLOAD_IDENTITY_PROVIDER_DEV}}
service_account: ${{secrets.SERVICE_ACCOUNT_ID_DEV}}

- name: Login to GCR
uses: docker/login-action@v2
with:
registry: us-docker.pkg.dev
username: oauth2accesstoken
password: ${{ steps.auth.outputs.access_token }}

- name: Set environment variables
uses: c-py/action-dotenv-to-setenv@v2
with:
env-file: .env

- name: Set up JDK 1.8
uses: actions/setup-java@v4
with:
java-version: 8
distribution: 'temurin'
- name: Build Maven with Docker Profile
run: mvn clean install -Pdocker -DskipTests -B
- name: Build and push
uses: docker/bake-action@master
with:
push: true
env:
IMAGE_TOMCAT: security-shepherd:latest
IMAGE_MARIADB: security-shepherd_mariadb:latest
IMAGE_MONGO: security-shepherd_mongo:latest
CONTAINER_TOMCAT: secshep-tomcat
CONTAINER_MARIADB: secshep-mariadb
CONTAINER_MONGO: secshep-mongo
MONGO_BIND_ADDRESS: "0.0.0.0"
# - name: Setup tmate session
# uses: mxschmitt/action-tmate@v3
# with:
# limit-access-to-actor: true
# if: ${{ failure() }}
48 changes: 20 additions & 28 deletions mobile/.gitignore
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
# built application files
*.apk
*.ap_

# files for the dex VM
*.dex

# Java class files
*.class

# generated files
bin/
gen/

# Local configuration file (sdk path, etc)
local.properties

# Eclipse project files
.classpath
.project

# Proguard folder generated by Eclipse
proguard/

# Intellij project files
*.iml
*.ipr
*.iws
.idea/
.gradle
/local.properties
# Ignore all IDE project files
.idea/
/.idea/
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
CHALLENGE_SOLUTIONS.txt
missing_challenges.txt
MOBILE_SHEPHERD_WALKTHROUGH.md
# Dev planning docs (local only)
MATERIAL3_IMPLEMENTATION_SUMMARY.md
MOBILE_UI_MODERNIZATION_PLAN.md
# Environment / secrets
.env
.env.*
1 change: 1 addition & 0 deletions mobile/app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
75 changes: 75 additions & 0 deletions mobile/app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
plugins {
id 'com.android.application'
}

android {
namespace 'org.owasp.mobileshepherd'
compileSdk 34

defaultConfig {
applicationId "org.owasp.mobileshepherd"
minSdk 21
targetSdk 34
versionCode 1
versionName "1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug {
minifyEnabled false
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
testOptions {
unitTests {
returnDefaultValues = true
}
}
sourceSets {
test {
java {
// These test files reference unimplemented modules — exclude from compilation
// until the corresponding fragments/models are implemented.
exclude 'org/owasp/mobileshepherd/InsecureData3Test.java'
exclude 'org/owasp/mobileshepherd/ReverseEngineering2Test.java'
exclude 'org/owasp/mobileshepherd/ReverseEngineeringChallenge3Test.java'
exclude 'org/owasp/mobileshepherd/SecurityMisconfigChallenge3Test.java'
exclude 'org/owasp/mobileshepherd/SupplyChainChallengeTest.java'
}
}
}
buildFeatures {
viewBinding true
}
}

dependencies {

implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.preference:preference:1.2.1'
implementation 'com.google.android.material:material:1.11.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2'
implementation 'androidx.navigation:navigation-fragment:2.7.7'
implementation 'androidx.navigation:navigation-ui:2.7.7'
implementation 'androidx.exifinterface:exifinterface:1.3.7'
implementation 'androidx.dynamicanimation:dynamicanimation:1.0.0'

// Unit testing
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.robolectric:robolectric:4.10'

// Instrumented testing
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
101 changes: 101 additions & 0 deletions mobile/app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# ===================================
# REVERSE ENGINEERING LESSONS/CHALLENGES
# Keep these unobfuscated for educational purposes
# ===================================

# Reverse Engineering Lesson - meant to be reverse engineered
-keep class org.owasp.mobileshepherd.ui.lessons.** { *; }

# Reverse Engineering Challenges 1-3 - meant to be reverse engineered
-keep class org.owasp.mobileshepherd.ui.challenges.** { *; }

# ===================================
# OBFUSCATE EVERYTHING ELSE
# These should be protected from reverse engineering
# ===================================

# Keep names for ViewBinding and ViewModels to avoid runtime issues
-keep class org.owasp.mobileshepherd.databinding.** { *; }
-keep class * extends androidx.lifecycle.ViewModel { *; }

# Keep MainActivity and navigation infrastructure
-keep class org.owasp.mobileshepherd.MainActivity { *; }
-keep class org.owasp.mobileshepherd.LandingActivity { *; }
-keep class org.owasp.mobileshepherd.Preferences { *; }

# Keep Fragment classes but obfuscate their internals
-keepnames class * extends androidx.fragment.app.Fragment

# Keep these challenge/lesson packages OBFUSCATED (not in RE category)
# Insecure Data Storage - should be obfuscated
-keepnames class org.owasp.mobileshepherd.ui.lessons.insecuredata.**
-keepnames class org.owasp.mobileshepherd.ui.challenges.insecuredata1.**
-keepnames class org.owasp.mobileshepherd.ui.challenges.insecuredata3.**

# Poor Authentication - should be obfuscated
-keepnames class org.owasp.mobileshepherd.ui.lessons.poorauth.**
-keepnames class org.owasp.mobileshepherd.ui.challenges.poorauth.**

# Supply Chain Security - should be obfuscated
-keepnames class org.owasp.mobileshepherd.ui.lessons.supplychain.**
-keepnames class org.owasp.mobileshepherd.ui.challenges.supplychain.**

# Insecure Communication - should be obfuscated
-keepnames class org.owasp.mobileshepherd.ui.lessons.insecurecomm.**
-keepnames class org.owasp.mobileshepherd.ui.challenges.insecurecomm.**

# Cryptography - should be obfuscated
-keepnames class org.owasp.mobileshepherd.ui.lessons.crypto.**
-keepnames class org.owasp.mobileshepherd.ui.challenges.crypto.**

# Security Misconfiguration - should be obfuscated
-keepnames class org.owasp.mobileshepherd.ui.lessons.securitymisconfig.**
-keepnames class org.owasp.mobileshepherd.ui.challenges.securitymisconfig.**

# Input Validation - should be obfuscated
-keepnames class org.owasp.mobileshepherd.ui.lessons.inputvalidation.**
-keepnames class org.owasp.mobileshepherd.ui.challenges.inputvalidation.**

# Insecure Authorization - should be obfuscated
-keepnames class org.owasp.mobileshepherd.ui.lessons.insecureauthorization.**

# Home fragment
-keepnames class org.owasp.mobileshepherd.ui.home.**

# Aggressive obfuscation settings
-optimizationpasses 5
-overloadaggressively
-repackageclasses ''
-allowaccessmodification

# Obfuscate string constants (except in RE packages)
-adaptclassstrings

# Remove logging for non-RE packages
-assumenosideeffects class android.util.Log {
public static *** d(...);
public static *** v(...);
public static *** i(...);
}

# Keep source file and line numbers for debugging
-keepattributes SourceFile,LineNumberTable
-renamesourcefileattribute SourceFile

# AndroidX and Material Components
-keep class androidx.** { *; }
-keep interface androidx.** { *; }
-keep class com.google.android.material.** { *; }

# Navigation component
-keep class androidx.navigation.** { *; }

# Prevent stripping of enum classes
-keepclassmembers enum * { *; }
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.owasp.mobileshepherd;

import android.content.Context;

import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.*;

/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("org.owasp.mobileshepherd", appContext.getPackageName());
}
}
Loading
Loading