Contaminated Squares
JavaScript, 105 97 bytes
Saved 8 bytes thanks to @Patrick Roberts!
l=a=&gt;a.slice(1,-1)
p=a=&gt;l(a).map(l)
c=a=&gt;a.join``.replace(/[^0]/g,&quot;&quot;)
s=a=&gt;c(p(a))&lt;c(a)?s(p(a)):a

Defines function s, which returns a 2D array of integers when provided a 2D array of integers as input.
How it Works

function l: given an array a, returns a copy without its first and last indexes.

function p: given a 2D array a, calls l to remove the first and last row, then for each remaining row calls l to remove the fist and last column. This performs the onion peeling.

function c: given a 2D array a, returns a string that only contains the 0s in the stringified form of a.

function s: given a 2D array a, calls c on the peeled form of the array given by p, and on the array itself. Compares these strings lexicographically to determine if the peeled form has less 0s than the original. If it does, then the original is contaminated, so call s recursively on the peeled form. Otherwise return the original.