How to show the raw plain text secret detected by detect-secrets?
setu1421 opened this issue · 3 comments
I want to retrieve the exact matched string from hashed secret provided by the tool. So, I ran the detect-secrets tool for willymcallister/spinningnumbers repository and a sample output of the tool is shown below:
The tool has found a private key in line 184 of _articles/staticman-heroku.md file.
However, I tried to compute the hashed secret using hashlib with different combinations of the secrets such as by removing unnecessary texts. But I could not compute the exact hashed secret provided by the tool.
Which part of the actual secret string has been used to calculate the hashed secret? Or Is there any way to get the plain text secret instead of hashed secret in the report using any flag? Please let me know your feedback.
Hey, you can go into the library and remove a line in detect_secrets/core
/potential_secret.py at line number 56 , and insert this: self.secret_hash: str = secret
Better yet, you can keep the secret_hash
field and instead just add this to the json()
function that starts on line 98 of detect_secrets/core/potential_secret.py
:
attributes['raw_secret'] = self.secret_value
So the modified function would look like this:
def json(self) -> Dict[str, Union[str, int, bool]]:
"""Custom JSON encoder"""
attributes: Dict[str, Union[str, int, bool]] = {
'type': self.type,
'filename': self.filename,
'hashed_secret': self.secret_hash,
'is_verified': self.is_verified,
}
if hasattr(self, 'line_number') and self.line_number:
attributes['line_number'] = self.line_number
if hasattr(self, 'is_secret') and self.is_secret is not None:
attributes['is_secret'] = self.is_secret
# Include plaintext secret (NOT RECOMMENDED DUE TO SECURITY CONCERNS)
attributes['raw_secret'] = self.secret_value
return attributes
For one project, I personally modified it to also include the full line of source code that contains the secret (for easier contextual understanding):
def json(self) -> Dict[str, Union[str, int, bool]]:
"""Custom JSON encoder"""
attributes: Dict[str, Union[str, int, bool]] = {
'type': self.type,
'filename': self.filename,
'hashed_secret': self.secret_hash,
'is_verified': self.is_verified,
}
if hasattr(self, 'line_number') and self.line_number:
attributes['line_number'] = self.line_number
# Include the relevant line of source code (NOT RECOMMENDED DUE TO SECURITY CONCERNS)
with open(os.path.abspath(self.filename)) as fp:
for i, line in enumerate(fp):
if i == self.line_number-1:
attributes['source_code'] = line.strip()
break
if hasattr(self, 'is_secret') and self.is_secret is not None:
attributes['is_secret'] = self.is_secret
# Include plaintext secret (NOT RECOMMENDED DUE TO SECURITY CONCERNS)
attributes['raw_secret'] = self.secret_value
return attributes
Your resulting findings will look like this:
// ...
{
"type": "GitHub Token",
"filename": "src/test.js",
"hashed_secret": "ffffffffffffffffffffffffffffffffffffffff",
"is_verified": false,
"line_number": 451,
"raw_secret": "ghp",
"source_code": "let ghToken = \"ghp_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\";"
},
// ...
Note, of course, that none of this is recommended - it's bad practice to unnecessarily store plain-text secrets.
Hello everyone, @SeanPesce is right in bringing up the fact that writing the raw secrets in .secrets.baseline
is a security issue and defeats the purpose of running detect-secrets
to avoid pushing those secrets to your remote repository. I'll change the status of this issue as won't fix
for now, but won't close it so it can stay under our radar and we (and you all) can find a solution to address this in a way that would make sense.