-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JS CWE-732: Overpermissive file creation #6110
Conversation
Intraprocedural only. Causes incorrect results with eg module level defaults.
Tightens range to remove unnecessary iteration 1 past the end.
Now creating directories with secure modes.
Hi @dittyroma With some adjustments, we would like to merge this significant PR from you, can I convince you to reopen it? I think the query can be valuable for audits, but it I expect that it is too prone to false positives to be run by default, but will not prevent it from being being merged. Perhaps CWE-276 should be used to reflect that the query does not make an attempt to identify the kind of file/directory that is being created? The primary adjustment I would like to see is a consolidation of the 12 queries into one or perhaps two queries. It looks like your qll files already are general enough to support this (well done!). What do you think of that suggestion? I suspect that such an adjustment would cut significantly down on the need for qhelp and query info text, making the PR easier to review and maintain. As an example. Consider /**
* @name Modeless file or directory creation
* @description Creating files or directories as world writable may allow an attacker to control
* program behavior.
* @kind problem
* @problem.severity warning
* @id js/insecure-fs/modeless-entry-creation
* @tags security
* external/cwe/cwe-732
*/
import ModableEntryCreation
from ModableEntryCreation creation
where creation.isInsecure() and creation.isModeless()
select creation, "This modeless call creates world a writable " + creation.getEntryKind() + "." Similar simple unifications should be possible throughout the ql files. The tricky part may be the merging of the I am happy to help out with suggestions for how to merge additional queries if you get stuck. |
Hi @esbena. Thank you for suggesting this. I was thinking of the code as my main submission here. I imagined doing a series of builds like this. Chose something simple as a way to learn the language, hoping it would turn into some ongoing coding. Does that sound like something the team might be interested in? I've done some coding bounties on eg Bountysource in the past. Perhaps we could communicate beforehand and the team could set some requirements, similar to what you would post in a bounty. If there are areas valuable to the project that could be filled out, I'd be glad to do more builds with quality similar to this work. |
Sure. We are happy to iterate on pull requests.
https://github.com/github/securitylab/discussions is the suggested place to discuss potential queries. |
Alright. It won't lead to what I want so I'm leaving this one alone. |
Description
World writable resources such as config files can allow other users to control program behavior. In some cases there's code injection through the config file, which can lead to privilege elevation. World writable directories have the same weakness since they allow adding files within them. A world writable config directory
/etc/froznator/conf.d
offers a route to controlling program behavior through a new config file. MITRE calls this CWE-732, one of the top 25 most dangerous vulnerabilities.This set of queries finds creations of world writable files and directories. It aims to detect all the major ways of specifying mode:
fs.constants.S_IRWXU | fs.constants.S_IRWXG
0o777 & ~fs.constants.S_IRWXO
It also detects functions which offer no way of specifying mode. These functions always use the default world writable mode and are therefore unsecurable. Query help recommends replacing these functions with securable alternatives.
The queries check for these conditions:
The queries target the standard
fs
module plus replacement modules viaNodeJSLib::FS::moduleMember
, along with thefs/promises
interface. Several popular npm modules are also detected. They are, with weekly downloads:fs-extra
40Mfs-extra-p
20Kmkdirp
37Mjsonfile
26Mcp-file
2Mmake-dir
35Mcpy
1Mmove-file
200K@npmcli/move-file
5Mtrash
59KCalls and constructions are both detected since they both result in a creation. Number and octal numeric string mode specifiers are both detected and correctly interpreted.
Libraries
ModableFileCreation.qll
ModableDirectoryCreation.qll
define the functions that can take a mode. Tests can't import these due to the dash in the pathexperimental/Security/CWE-732/*
. I did a strange thing of defining libraries that expose a query predicate to make them testable,ModableFileCreationTest.qll
ModableDirectoryCreationTest.qll
. My inclination is to test these but if that's just an awful pattern I can remove them.I have equivalent queries for the other languages on the way.
Omitted
Related modules
ncp
cpr
were left out because they always copy permissions.rimraf
was left out because it never creates files.makedir
was left out for low usage.Hard links always have the same permissions as target. Symbolic links can sometimes have their own permissions but they can never bypass target permissions.
False Positives
The queries only find creation functions called with an insecure mode. But in some cases there's surrounding logic that makes creation impossible / virtually impossible. If there's an immediate preceding read from the same file, it will fail if the file doesn't exist and so the write should never create a new file. The queries don't detect this situation.
Results
Unsecurable file creation
https://lgtm.com/query/8754882199744511397/
Unsecurable directory creation
https://lgtm.com/query/2881405778980302287/
Modeless file creation
https://lgtm.com/query/308122751628928618/
Modeless directory creation
https://lgtm.com/query/8429440007276116881/
File creation with literal mode
https://lgtm.com/query/8337507973041063599/
Directory creation with literal mode
https://lgtm.com/query/7981273486056700546/
File creation with transported mode
https://lgtm.com/query/2480237548234300509/
Directory creation with transported mode
https://lgtm.com/query/1573873983796861180/
File creation with mode constructed by inclusion
Had to run this one locally.
Directory creation with mode constructed by inclusion
Had to run this one locally.
Mode constructed by exclusion
I do find examples of the exclusion pattern for constructing mode but none of them are vulnerable, so you guys might want those ones removed.
Reports
I reported to all the active projects. Only
jspm
was inactive. Receptiveness varied. Some projects updated right away, others were dismissive. PDF.js had mixed feelings, with some devs thinking it's valuable and others aggressively opposed.For the projects with a disclosure policy I sent private reports.
For the modules with unsecurable functions I suggested exposing a mode parameter so they can be secured.
Patches
semver
move-file
cp-file
trash
Modules
I went ahead and published
secure-fs
, a drop in replacementfs
with secure modes by default. Hopefully that can lower the cost of choosing security for devs.fs-extra
was unreceptive to changing the interface so I publishedsecure-fs-extra
. It uses secure modes by default and offers controllable modes everywhere.Discussion
This tentative blog post describes the queries, to be finalized after code review.
https://dittyroma.wordpress.com/2021/06/17/javascript-overpermissive-file-creation/