stavroskasidis/BlazorWasmAntivirusProtection

Alternative to BZ header?

Closed this issue · 4 comments

I'm not sure if there is some specific relevance to the BZ header or if its arbitrary?

If its arbitrary could there be an option to pick the header similar to how we can choose the file extension? (2 bytes I guess).

The reason I suggest this is I noted after I released a project with BZ headers but .dll file extensions our filter started blocking it. I released with corrected file extensions and the filter still blocked it. I assume this is because the file hash was the same as one already blocked. I disabled trimming on the blocked file to force a hash change and it went straight through.

This may be related to #6

If we can change the header it gives us a way to force a hash change.

There may be other ways to force a hash change along the lines of null 0x00 characters on the end of the dll. I haven't looked into if that will work or corrupt the dll's though.

The header is arbitrary but I haven't figured out yet a good way to pass options from the msbuild pipeline into the blazor js initialization module, so I have to keep it hardcoded for now.

It would require some kind of config.json file or something else to be included in the output and fetched dynamically during initialization, but that seems that it makes things even more complicated.

I will have to look into this further and see what the best solution would be.

I have taken a look a the js side and I think you can get away without working out passing in parameters.

The original just checks if the first character is an M or not so it could be any character passed in anyway not just B

var data = new Uint8Array(responseResult.buffer);
if (data[0] != 77) {
	console.log("Restoring binary header: " + name);
	data[0] = 77; //This restores header from BZ to MZ
}
var resp = new Response(data, { "status": 200, headers: responseResult.headers });
return resp;

Tweaked just to accommodate a check on the second character change e.g. MB:

var data = new Uint8Array(responseResult.buffer);
if (data[0] != 77 || data[1] != 90 ) {
	console.log("Restoring binary header: " + name);
	data[0] = 77; //This restores header to MZ
	data[1] = 90; 
}
var resp = new Response(data, { "status": 200, headers: responseResult.headers });
return resp;

If you take a look at my Fork I have taken this further and added a footer GUID to each dll which can be passed in as a parameter. Then in the js I just ignore the last 16 bytes like below. The guid footer will mean each developer can get unique file hashes.

var data = new Uint8Array(responseResult.buffer);
                if (data[0] != 77 || data[1] != 90) {
                    console.log("Restoring binary header: " + name);
                    //remove guid from end 16 bytes
                    var data2 = new Uint8Array(responseResult.buffer,0,(responseResult.buffer.byteLength-16));
                    //put MZ header
                    data2[0] = 77;
                    data2[1] = 90;
                    var resp = new Response(data2, { "status": 200, headers: responseResult.headers });
                    return resp;
                }
                var resp = new Response(data, { "status": 200, headers: responseResult.headers });
                return resp;

It does have a breaking change of renaming DisableChangingDllHeader to DisableChangingDllHeaderFooter for clarity and new parameters BlazorGuidFooter and BlazorTwoCharacterFileHeader which aren't documented as I was just experimenting.

I like your approach and the changes you made. I will consider pulling from your fork and adding these.

Thank you

Xoring achieves similar. Great update.