mirror of
https://github.com/github/codeql.git
synced 2025-12-17 09:13:20 +01:00
138 lines
4.2 KiB
JavaScript
138 lines
4.2 KiB
JavaScript
import Vue from 'vue';
|
|
import Vuex from 'vuex';
|
|
import { mapGetters, mapState, mapMutations, mapActions, createNamespacedHelpers } from 'vuex';
|
|
|
|
Vue.use(Vuex);
|
|
|
|
function sink(x) {}
|
|
function source() {}
|
|
|
|
const submoduleA = {
|
|
getters: {
|
|
foo: () => source(),
|
|
}
|
|
};
|
|
const submoduleB = {
|
|
getters: {
|
|
foo: () => 'safe',
|
|
}
|
|
};
|
|
|
|
const { mapGetters: mapGettersA } = createNamespacedHelpers('submoduleA');
|
|
const { mapGetters: mapGettersB } = createNamespacedHelpers('submoduleB');
|
|
|
|
const store = new Vuex.Store({
|
|
getters: {
|
|
getterWithSink: state => { sink(state.tainted); }, // NOT OK
|
|
taintedGetter: state => state.tainted,
|
|
untaintedGetter: state => state.untainted,
|
|
},
|
|
state: {
|
|
tainted: '',
|
|
tainted2: '',
|
|
tainted3: '',
|
|
tainted4: '',
|
|
untainted: '',
|
|
taintedAtSource: source(),
|
|
},
|
|
mutations: {
|
|
setTainted: (state, payload) => {
|
|
state.tainted = payload;
|
|
},
|
|
setTainted2: (state, payload) => {
|
|
state.tainted2 = payload;
|
|
},
|
|
setTainted3: (state, payload) => {
|
|
state.tainted3 = payload;
|
|
},
|
|
setTainted4: (state, payload) => {
|
|
state.tainted4 = payload;
|
|
},
|
|
clean: (state, payload) => {
|
|
state.untainted = payload;
|
|
}
|
|
},
|
|
actions: {
|
|
doTaint2(context, payload) {
|
|
context.commit('setTainted2', payload);
|
|
},
|
|
doTaint4(context, payload) {
|
|
context.commit('setTainted4', payload);
|
|
},
|
|
},
|
|
modules: { submoduleA, submoduleB }
|
|
});
|
|
|
|
const Component = new Vue({
|
|
computed: {
|
|
...mapGetters(['taintedGetter', 'untaintedGetter']),
|
|
...mapGetters({
|
|
namedGetter: 'taintedGetter',
|
|
}),
|
|
...mapState({
|
|
localTainted: 'tainted',
|
|
derivedTainted: state => state.tainted,
|
|
derivedUntainted: state => state.untainted,
|
|
}),
|
|
...mapState(['tainted2']),
|
|
...mapGetters('submoduleA', {fooA1: 'foo'}),
|
|
...mapGettersA({fooA2: 'foo'}),
|
|
...mapGetters('submoduleB', {fooB1: 'foo'}),
|
|
...mapGettersB({fooB2: 'foo'}),
|
|
},
|
|
methods: {
|
|
doCommitsAndActions() {
|
|
this.$store.commit('setTainted', source());
|
|
this.$store.dispatch('doTaint2', source());
|
|
this.$store.commit('clean', 'safe');
|
|
this.sneakyTaint3(source());
|
|
this.emitTaint4(source());
|
|
},
|
|
sinks() {
|
|
sink(this.taintedGetter); // NOT OK
|
|
sink(this.namedGetter); // NOT OK
|
|
sink(this.$store.state.taintedAtSource); // NOT OK
|
|
sink(this.$store.state.tainted3); // NOT OK
|
|
sink(this.$store.state.tainted4); // NOT OK
|
|
sink(this.localTainted); // NOT OK
|
|
sink(this.derivedTainted); // NOT OK
|
|
sink(this.tainted2); // NOT OK
|
|
sink(this.untaintedGetter); // OK
|
|
sink(this.derivedUntainted); // OK
|
|
|
|
sink(this.fooA1); // NOT OK
|
|
sink(this.fooA2); // NOT OK
|
|
sink(this.fooB1); // OK
|
|
sink(this.fooB2); // OK
|
|
},
|
|
...mapMutations({ sneakyTaint3: 'setTainted3' }),
|
|
...mapActions({ emitTaint4: 'doTaint4' }),
|
|
loopingState() {
|
|
// Make sure we do not fail by trying to compute infinitely long access paths.
|
|
// 'ref' can refer to state.foo, state.foo.foo, state.foo.foo.foo, and so on.
|
|
let ref = this.$store.state;
|
|
while (Math.random()) {
|
|
ref = ref.foo;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
const OtherComponent = new Vue({
|
|
methods: {
|
|
sinks() {
|
|
// By being in the same file, `this.$store` is assumed to refer to the same vuex store as above.
|
|
sink(this.$store.state.taintedAtSource); // NOT OK
|
|
|
|
// This component has no `computed` helpers installed, so the following are all safe.
|
|
sink(this.taintedGetter); // OK
|
|
sink(this.namedGetter); // OK
|
|
sink(this.localTainted); // OK
|
|
sink(this.derivedTainted); // OK
|
|
sink(this.tainted2); // OK
|
|
sink(this.untaintedGetter); // OK
|
|
sink(this.derivedUntainted); // OK
|
|
}
|
|
}
|
|
});
|