Categories
discuss

Change JsonProperty (Access.WRITE_ONLY) programmatically

My Java objects have some fields that are annotated write only because they should not be send over a REST interface to the users.

  @JsonProperty(access = Access.WRITE_ONLY)
  private List<Integer> integerList;

Now I am trying to implement an admin-controller, where these fields should be sent. My question is, can I change the property with code in my controller or do I have to create new objects for this purpose where the target fields are not annotated anymore. I think this wouldn’t be a clean solution so I guess I am missing some FasterXML Jackson feature here..

Thanks in advance for your help,

Codehai

Answer

Yes, there is a much simpler way to do that using fasterXML annotation.

Create filter using fasterXML, and define the fields you wish to filter. The list of properties can be defined hardcoded, or calculated in runtime. For example in admin controller the filter list is empty(or partial), and regular controller the filter is list contain values: The class you are serializing:

@JsonFilter("PersonFilter")
public class Person
{
   private List<Integer> integerList; 
   private Integer creditCardNUmber;
   private String firstName;
   private String lastName;

public static FilterProvider getFilter(){
    Set<String> fieldsToFilter= new HashSet<>(Arrays.asList("creditCardNUmber","integerList");
    SimpleBeanPropertyFilter theFilter = SimpleBeanPropertyFilter
            .serializeAllExcept(fieldsToFilter);
    FilterProvider filters = new SimpleFilterProvider()
            .addFilter("PersonFilter", theFilter);
    return filters;
}
}

When you serialize the object you can use predefined list of properties to filter (public static FilterProvider getFilter(){..} ), or define them in runtime.

public static String GetObjectAsStringWithFilter(FilterProvider filters, Object jsonObject)
{
    if (jsonObject == null)
    {
        return null;
    }
    String objectAsString = null;
    try
    {
        objectAsString = objectMapper.writer(filters).writeValueAsString(jsonObject);
    }
    catch (Exception e)
    {
        ...
    }

    return objectAsString;
}
Categories
discuss

What is VSYNC in android

This explains VSYNC, but the pace is very fast, and i am unable to find any other good resource to understand this topic.

What i have understand is this;

VSYNC happens at every 16ms, and all of the frame components INPUT ANIMATION LAYOUT RECORD DRAW & RENDER only happens 1 in this time, so with VSYNC the frame rendering is synchronized, and it restricts frame from redrawing in the specified time.

Kindly guide me if this understanding is correct or not.

Answer

VSYNC is vertical sync. Its a term common to TVs, monitors, displays, etc. You can basically think of it as the refresh rate, its how often the display is actually refreshed. The display can only update on the VSYNC signal, so changes to the display are basically batched until the next VSYNC.

The term comes from old school TVs where the VSYNC would actually change 1 row at a time from top to bottom of the TV. That’s why on some old tube TVs you could see a bar of change moving down the screen.

Categories
discuss

Spring WebFlux, how can I debug my WebClient POST exchange?

I am having trouble understanding what I’ve done wrong in constructing my WebClient request. I would like to understand what the actual HTTP request looks like. (e.g., dumping the raw request to console)

POST /rest/json/send HTTP/1.1
Host: emailapi.dynect.net
Cache-Control: no-cache
Postman-Token: 93e70432-2566-7627-6e08-e2bcf8d1ffcd
Content-Type: application/x-www-form-urlencoded

apikey=ABC123XYZ&from=example%40example.com&to=customer1%40domain.com&to=customer2%40domain.com&to=customer3%40domain.com&subject=New+Sale+Coming+Friday&bodytext=You+will+love+this+sale.

I am using Spring5’s reactive tools to build an API. I have a utility class that will send an email using Dyn’s email api. I would like to use The new WebClient class to accomplish this (org.springframework.web.reactive.function.client.WebClient)

The following command has been taken from : https://help.dyn.com/email-rest-methods-api/sending-api/#postsend

curl --request POST "https://emailapi.dynect.net/rest/json/send" --data "apikey=ABC123XYZ&from=example@example.com&to=customer1@domain.com&to=customer2@domain.com&to=customer3@domain.com&subject=New Sale Coming Friday&bodytext=You will love this sale."

When I make the call in curl with real values, the email sends correctly, so I feel like I am generating my request incorrectly.

My Send Command

public Mono<String> send( DynEmailOptions options )
{
    WebClient webClient = WebClient.create();
    HttpHeaders headers = new HttpHeaders();
    // this line causes unsupported content type exception :(
    // headers.setContentType( MediaType.APPLICATION_FORM_URLENCODED );
    Mono<String> result = webClient.post()
        .uri( "https://emailapi.dynect.net/rest/json/send" )
        .headers( headers )
        .accept( MediaType.APPLICATION_JSON )
        .body( BodyInserters.fromObject( options ) )
        .exchange()
        .flatMap( clientResponse -> clientResponse.bodyToMono( String.class ) );
    return result;
}

My DynEmailOptions Class

import java.util.Collections;
import java.util.Set;

public class DynEmailOptions
{
    public String getApikey()
    {
        return apiKey_;
    }

    public Set<String> getTo()
    {
        return Collections.unmodifiableSet( to_ );
    }

    public String getFrom()
    {
        return from_;
    }

    public String getSubject()
    {
        return subject_;
    }

    public String getBodytext()
    {
        return bodytext_;
    }

    protected DynEmailOptions(
        String apiKey,
        Set<String> to,
        String from,
        String subject,
        String bodytext
    )
    {
        apiKey_ = apiKey;
        to_ = to;
        from_ = from;
        subject_ = subject;
        bodytext_ = bodytext;
    }

    private Set<String> to_;
    private String from_;
    private String subject_;
    private String bodytext_;
    private String apiKey_;
}

Answer

You’re currently trying to serialize the request body “as is”, without using the right BodyInserter.

In this case, I think you should turn your DynEmailOptions object into a MultiValueMap<String, String> and then:

MultiValueMap<String, String> formData = ...
Mono<String> result = webClient.post()
                .uri( "https://emailapi.dynect.net/rest/json/send" )
                .contentType(MediaType.APPLICATION_FORM_URLENCODED)
                .accept( MediaType.APPLICATION_JSON )
                .body( BodyInserters.fromFormData(formData))
                .retrieve().bodyToMono(String.class);
Categories
discuss

Android equivalent of ios devicecheck

Is there an android equivalent of ios device check
https://developer.apple.com/documentation/devicecheck
or any way to verify that this is your undoctored apk making the api call?

Answer

First part of the question

Is there an android equivalent of ios device check https://developer.apple.com/documentation/devicecheck

As already point out the android equivalent is SafetyNet, but despite being a very good improvement for the Android security ecosystem was not designed to be used as a stand-alone defence, as per Google own statement:

The goal of this API is to provide you with confidence about the integrity of a device running your app. You can then obtain additional signals using the standard Android APIs. You should use the SafetyNet Attestation API as an additional in-depth defense signal as part of an anti-abuse system, not as the sole anti-abuse signal for your app.

Also when a developer is implementing the SafetyNet solution it needs to bear in mind:

  • It is part of Google Mobile Services (GMS) so only runs on devices that have this. In some markets, such as the far east, there are a significant number of devices that do not have this available.

  • There are a limited number of attestation calls that can be made with a standard free API key, so to use at scale a (presumably) paid level would be required.

  • It is primarily designed to check if the OS image that a particular Android device is running is considered to be secure and compatible or not. As such it can be considered to be quite advanced root check that is able to check for file system changes indicative of rooted devices.

  • Since the SafetyNet is doing a full analysis of the hashes of the OS image it can actually be quite slow (sometimes a few seconds). This means that it cannot be doing continuously and some care is needed in its use to hide this latency from the user, but without creating an opening for an attacker to exploit.

  • SafetyNet does not specifically analyse the memory map of running apps to detect instrumentation frameworks (it relies on the fact that they can only run on rooted devices), like XPosed and Frida.

  • SafetyNet does provide an attestation of the running app via the apkDigestSha256 feature. However, this can only be relied upon if full integrity is reported. This means that the integrity of the app is unknown if it is running on any kind of unusual or rooted devices. Some users root their devices only for customizations purposes and if the mobile app has a significant percentage of them then SafetyNet will exclude them from being able to use the app. In this scenarios we want to know specifically about the integrity of the running app rather then the system as a whole. SafetyNet is not able to do that, but a mobile app attestation service can.

  • In order to perform the attestation check in a way that cannot be spoofed then app cannot do its own check (as obviously this code could be tampered with itself). Thus there is a need to implement a server side to use the feature reliably.

Second part of the question

or any way to verify that this is your undoctored apk making the api call?

The way here is to use SafetyNet alongside a Mobile App Attestation service. OAUTH2 should also be used if user authentication and authentication is necessary in your mobile app. Last but not least important is the use of certificate pinning to secure the communication channel between the API server and the Mobile App, as covered in this series of articles about Mobile API Techniques.

Definition of a Mobile App Attestation service

The role of a Mobile App Attestation service is to guarantee at run-time that your App was not tampered or is not running in a rooted device by using an SDK integrated in your App and a service running in the cloud.

On successful attestation of the App Integrity a JWT token is issued and signed with a secret that only the API server of your App and the Mobile App Attestation service in the cloud are aware.

In the case of failure on the App Attestation the JWT is signed with a secret that the API server does not know.

Now the App must sent with every API call the JWT token in the headers of the request. This will allow the API server to only serve requests when it can verify the signature in the JWT token and refuse them when it fails the verification.

Once the secret used by the Mobile App Attestation service is not known by the App, is not possible to reverse engineer it at run-time even when the App is tampered, running in a rooted device or communicating over a connection that is being the target of a Man in the Middle Attack. This is where this type of service shines in relation to the SafetyNet solution.

As a side note if your App talks directly with third parts services, then I suggest that you delegate that responsibility to the API server, that will prevent
unauthorized use of your third part services in your behalf, once it only serves
now authentic requests from the Mobile App’s that passed the Integrity challenges.

The Mobile App Attestation service already exists as a SAAS solution at Approov(I work here) that provides SDKs for several platforms, including iOS. The integration will also need a small check in the API server code to verify the JWT token issued by the cloud service. This check is necessary for the API server to be able to decide what requests to serve and what ones to deny.

Categories
discuss

How to turn on/off wifi hotspot programmatically in Android 8.0 (Oreo)

I know how to turn on/off wifi hot spot using reflection in android using below method.

private static boolean changeWifiHotspotState(Context context,boolean enable) {
        try {
            WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
            Method method = manager.getClass().getDeclaredMethod("setWifiApEnabled", WifiConfiguration.class,
                    Boolean.TYPE);
            method.setAccessible(true);
            WifiConfiguration configuration = enable ? getWifiApConfiguration(manager) : null;
            boolean isSuccess = (Boolean) method.invoke(manager, configuration, enable);
            return isSuccess;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

But the above method is not working Android 8.0(Oreo).

When I execute above method in Android 8.0, I am getting below statement in logcat.

com.gck.dummy W/WifiManager: com.gck.dummy attempted call to setWifiApEnabled: enabled = true

Is there any other way to on/off hotspot on android 8.0

Answer

Finally I got the solution. Android 8.0, they provided public api to turn on/off hotspot. WifiManager

Below is the code to turn on hotspot

private WifiManager.LocalOnlyHotspotReservation mReservation;

@RequiresApi(api = Build.VERSION_CODES.O)
private void turnOnHotspot() {
    WifiManager manager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);

    manager.startLocalOnlyHotspot(new WifiManager.LocalOnlyHotspotCallback() {

        @Override
        public void onStarted(WifiManager.LocalOnlyHotspotReservation reservation) {
            super.onStarted(reservation);
            Log.d(TAG, "Wifi Hotspot is on now");
            mReservation = reservation;
        }

        @Override
        public void onStopped() {
            super.onStopped();
            Log.d(TAG, "onStopped: ");
        }

        @Override
        public void onFailed(int reason) {
            super.onFailed(reason);
            Log.d(TAG, "onFailed: ");
        }
    }, new Handler());
}

private void turnOffHotspot() {
    if (mReservation != null) {
        mReservation.close();
    }
}

onStarted(WifiManager.LocalOnlyHotspotReservation reservation) method will be called if hotspot is turned on.. Using WifiManager.LocalOnlyHotspotReservation reference you call close() method to turn off hotspot.

Note: To turn on hotspot, the Location(GPS) should be enabled in the device. Otherwise, it will throw SecurityException

Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..