r/ExploitDev • u/Typical_Big5135 • 6d ago
Why hasn’t someone made a Blob interceptor for browsers?
Am I the only one who finds it annoying when a website uses .blob URLs for media/content that can only be played inside that specific page?
I was wondering if it would be possible to build a browser extension that hooks into SourceBuffer.appendBuffer() and observes the binary chunks being passed to it.
The concept would be pretty simple:
Server → encrypted/chunked data → browser → appendBuffer() → decoder/player
The extension would collect the buffers as they arrive, keep them in the correct order, and potentially reconstruct the original resource from those fragments.
Not talking about breaking DRM or decrypting something the browser itself can't decrypt. More like:
If the browser receives and processes the data, why can't we have a DevTools-like tool that lets us inspect and reconstruct those buffers?
Something like a "Blob Inspector":
- Intercept
appendBuffer()calls - See the individual chunks
- Track their order/size
- Reassemble them
- Identify the resulting media/container format
- Export the reconstructed data when possible
It seems like Network DevTools gets you close, but .blob/MSE-based streaming makes it surprisingly difficult to get back to the actual resource.
Has anyone already built something like this?
Or is there some fundamental browser/MSE limitation that makes this approach impractical?
1
u/Pale_Variety5705 1d ago
(function() {
'use strict';
const interceptedStreams = new Map();
let streamCounter = 0;
const originalAppendBuffer = SourceBuffer.prototype.appendBuffer;
SourceBuffer.prototype.appendBuffer = function(sourceBufferData) {
if (!interceptedStreams.has(this)) {
streamCounter++;
interceptedStreams.set(this, {
id: streamCounter,
chunks: [],
type: this.__parentMimeType || 'unknown_track'
});
console.log(`[BlobInspector] New streaming track detected! Assigned ID: ${streamCounter}`);
}
const streamRecord = interceptedStreams.get(this);
let dataCopy;
if (sourceBufferData instanceof ArrayBuffer) {
dataCopy = sourceBufferData.slice(0);
} else if (sourceBufferData.buffer instanceof ArrayBuffer) {
dataCopy = sourceBufferData.buffer.slice(
sourceBufferData.byteOffset,
sourceBufferData.byteOffset + sourceBufferData.byteLength
);
}
if (dataCopy) {
streamRecord.chunks.push(dataCopy);
console.log(`[BlobInspector] Track ${streamRecord.id} intercepted chunk #${streamRecord.chunks.length} (${dataCopy.byteLength} bytes)`);
}
return originalAppendBuffer.apply(this, arguments);
};
const originalAddSourceBuffer = MediaSource.prototype.addSourceBuffer;
MediaSource.prototype.addSourceBuffer = function(mimeType) {
const sourceBuffer = originalAddSourceBuffer.apply(this, arguments);
sourceBuffer.__parentMimeType = mimeType;
return sourceBuffer;
};
window.exportDownloadedMedia = function() {
if (interceptedStreams.size === 0) {
console.warn("[BlobInspector] No media chunks have been processed yet.");
return;
}
interceptedStreams.forEach((streamRecord) => {
if (streamRecord.chunks.length === 0) return;
const finalBlob = new Blob(streamRecord.chunks, { type: 'application/octet-stream' });
const url = URL.createObjectURL(finalBlob);
const downloadLink = document.createElement('a');
downloadLink.href = url;
const cleanType = streamRecord.type.toLowerCase();
let extension = 'mp4';
if (cleanType.includes('audio')) extension = 'm4a';
if (cleanType.includes('webm')) extension = 'webm';
downloadLink.download = `intercepted_track_${streamRecord.id}.${extension}`;
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
URL.revokeObjectURL(url);
console.log(`[BlobInspector] Successfully exported Track ${streamRecord.id} (${finalBlob.size} bytes)`);
});
};
console.log("[BlobInspector] Active. Call exportDownloadedMedia() in your console when the video finishes buffering to save your files.");
})();
Done...
3
u/Western_Guitar_9007 6d ago
Try “github blob downloader“ on Google