v2.1.0
What's Changed
- Added basic test coverage
- Fix: Handling Etherscan contracts with multiple sources
- Use the respective solc binary according to the platform, save binaries locally
- Update Etherscan chains
- Users can now import contracts from other Etherscan instances: Polygonscan, Snowtrace etc.
- Make use of
immutableReferences
on verification- This lets us verify contracts with immutables very often without needing alternative methods such as looking at the
creatorTxHash
or "simulation"
- This lets us verify contracts with immutables very often without needing alternative methods such as looking at the
- Fix
addLibraryAddresses
potential vulnerability with regex.
Fixed vulnerability
Thanks to @Hellobloc and @samczsun for reporting the vulnerability.
addLibraryAddress RegExp vulnerability
Risk Description
Previously the following code was used to replace libraryAddress
es.
export function addLibraryAddresses(
template: string,
real: string
): {
replaced: string;
libraryMap: StringMap;
} {
const PLACEHOLDER_START = '__$';
const PLACEHOLDER_LENGTH = 40;
const libraryMap: StringMap = {};
let index = template.indexOf(PLACEHOLDER_START);
for (; index !== -1; index = template.indexOf(PLACEHOLDER_START)) {
const placeholder = template.slice(index, index + PLACEHOLDER_LENGTH);
const address = real.slice(index, index + PLACEHOLDER_LENGTH);
libraryMap[placeholder] = address;
const regexCompatiblePlaceholder = placeholder
.replace('__$', '__\\\\$')
.replace('$__', '\\\\$__');
const regex = RegExp(regexCompatiblePlaceholder, 'g');
template = template.replace(regex, address);
}
return {
replaced: template,
libraryMap,
};
}
The code replaced the library placeholders in the bytecode by identifying __$
and constructed regular matching expressions from the placeholder.
But note that not all versions use the hash of the library name as a placeholder. For example, the 0.4
Solidity version uses __{Path:FileName}__
placeholder.
This allows a malicious user to manipulate regular expressions, which in turn allows other parts of the bytecode to be marked as a library address.
Example
As with the risks mentioned above, we can achieve arbitrary regular expression tampering by changing the file name of the library contract.
An example is the following:
pragma solidity ^0.4.0;
import "./$.{37}|2{40}|cantbematchedcharacters__";
contract A {
address constant public a = address(0x2222222222222222222222222222222222222222);
uint public b;
function cc() public{
b = L_.get4();
}
}
In the above code, a regular expression is written in the filename and the expression appears in the generated bytecode and is adopted by the addLibraryAddresses
function.
This regular expression will first replace itself, and then look for 22...22
to do the same. Here 2{40}
can also be modified to 5b.{...}
to perform arbitrary replacements of executable bytecode.
A real attack case(0x4AD29c9716569f3c466BB123Efdd0B9B43207dE1 in goerli) was constructed.
The tampering of constants in the above case is possible. Of course executable bytecode tampering is also possible, simply by changing
2{40}
to 5b.{...}
, and writing L_
address to the bytecode we want.
DOS Attack
In addition to performing bytecode tampering, one can also perform a DOS attack on Sourcify. Specifically, once can design a regular expression that will not have any matches in bytecode
, resulting in __$
not being replaced, which in turn makes addLibraryAddresses
a dead loop.
Solution
We replaced the regex replacement of the pattern with a simple string match to __
in the bytecode, and replacing the placeholder with a fixed length (40 chars = 20 bytes).
PRs
- Added wagmi to tools in the landing page by @SaTiSH-K-R in #962
- handle etherscan contracts with multiple sources by @marcocastignoli in #965
- Test coverage by @marcocastignoli in #963
- Default SolcJs compiler by @marcocastignoli in #964
- Add other Etherscan chains by @kuzdogan in #959
- Verify with
immutableReferences
by @kuzdogan in #973 - Fix CORS error on req too large by @kuzdogan in #977
- Handle solc links in repo when fetching compiler by @marcocastignoli in #979
- fix: auto-scroll to about section by @aalimsahin in #982
- Change how addLibraryAddresses replaces the library addresses from the recompiled bytecode by @marcocastignoli in #981
- Release by @kuzdogan in #985
New Contributors
- @SaTiSH-K-R made their first contribution in #962
- @aalimsahin made their first contribution in #982
Full Changelog: v2.0.0...v2.1.0