Compare commits

...

152 Commits

Author SHA1 Message Date
erwanlr
73cd862e83 Bumps version 2020-03-09 20:02:44 +01:00
erwanlr
3305e9b74f Adds DFs 2020-03-09 19:24:43 +01:00
erwanlr
c37ec0e8d0 Updates deps 2020-03-09 18:11:47 +01:00
erwanlr
0b005477c1 Adds additional message when checksums mismatch during an update 2020-03-08 20:48:01 +01:00
erwanlr
a1467f8dac Merge branch 'dfs' 2020-03-07 14:56:23 +01:00
erwanlr
40d2c34347 Adds DFs 2020-03-07 14:56:10 +01:00
Erwan
528270e767 Updates Target#wordpress_from_meta_comments_or_scripts Xpath check 2020-03-06 16:17:40 +01:00
erwanlr
f4a04b2387 Adds DFs 2020-03-03 18:54:41 +01:00
erwanlr
14ed6ae109 Fixes #1461 2020-03-02 15:34:51 +01:00
erwanlr
4fd43694ae Typo 2020-03-02 11:57:37 +01:00
erwanlr
552d731e6a Updates Readme to reflect #1460 2020-03-02 11:56:42 +01:00
erwanlr
49ac3ef528 Supports loading api token from ENV, Fixes #1460 2020-03-02 11:45:50 +01:00
erwanlr
4379313f12 Bumps version 2020-02-29 14:24:53 +01:00
erwanlr
3901949f36 Updates deps 2020-02-29 13:27:52 +01:00
erwanlr
a3d8593fed Adds DFs 2020-02-29 12:28:55 +01:00
erwanlr
7c5baeb9c7 Adds DF 2020-02-26 10:55:06 +01:00
erwanlr
c692db5f85 Adds DFs 2020-02-24 13:29:13 +01:00
erwanlr
9130196ffc Runs rubocop before rspec 2020-02-19 14:38:31 +01:00
erwanlr
dad4a65118 Adds Coveralls GH Action 2020-02-19 14:16:31 +01:00
Erwan
4c34c2feb7 Merge pull request #1457 from wpscanteam/dependabot/bundler/rubocop-tw-0.80.0
Update rubocop requirement from ~> 0.79.0 to ~> 0.80.0
2020-02-19 12:32:39 +01:00
dependabot-preview[bot]
23522f7775 Update rubocop requirement from ~> 0.79.0 to ~> 0.80.0
Updates the requirements on [rubocop](https://github.com/rubocop-hq/rubocop) to permit the latest version.
- [Release notes](https://github.com/rubocop-hq/rubocop/releases)
- [Changelog](https://github.com/rubocop-hq/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop-hq/rubocop/compare/v0.79.0...v0.80.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-19 05:23:43 +00:00
Christian Mehlmauer
82c61398ba change name 2020-02-17 07:32:20 +01:00
Christian Mehlmauer
02871050a6 change step names 2020-02-17 06:34:39 +01:00
Christian Mehlmauer
7d3b1fea6b ruby-head not supported 2020-02-17 06:32:18 +01:00
Christian Mehlmauer
24917fa2a6 wrong key 2020-02-17 06:29:14 +01:00
Christian Mehlmauer
de3d8e4a23 Use a build matrix 2020-02-17 06:28:09 +01:00
erwanlr
1502845d65 Adds DFs 2020-02-15 13:20:54 +01:00
erwanlr
af3f10f74e Reduces time to detect the sub_dir when a lot of urls 2020-02-13 20:07:25 +00:00
erwanlr
c100372b31 Reduces time to detect non WP sites 2020-02-13 19:15:30 +00:00
erwanlr
72d699b39a Adds more improvements re passive scanning when there are a lot of urls 2020-02-13 15:36:42 +00:00
erwanlr
7d2b8a2a8b Reduces time to detect non WP sites when there are a lof of links in pages 2020-02-12 19:50:00 +00:00
erwanlr
8729c68e22 Removes useless params set 2020-02-11 16:39:01 +00:00
erwanlr
e2d48bedd9 Better fix for #1451, adds target IP address to output, ref #1088 2020-02-11 16:28:59 +00:00
erwanlr
6b241ce9b3 Avoids merging CLI params when calling VulnAPI - Ref #1451 2020-02-11 09:14:14 +00:00
erwanlr
1b68bdb36c Bumps version 2020-02-09 13:31:40 +00:00
erwanlr
fb82538441 Fixes #1451 2020-02-09 12:40:48 +00:00
erwanlr
2709d0869a Adds DFs 2020-02-08 10:28:19 +00:00
erwanlr
343f87bbe7 Adds DFs 2020-02-01 10:02:38 +00:00
erwanlr
ecbfc6004c Adds DFs 2020-01-25 12:28:16 +00:00
erwanlr
c57eecc81b Adds DF 2020-01-23 12:30:27 +00:00
erwanlr
7ea14dc03f Adds DF 2020-01-23 11:15:28 +00:00
erwanlr
4340d27258 Bumps version 2020-01-21 16:14:26 +00:00
erwanlr
e911be8f14 Removes ruby 2.7.0 from failure matrix 2020-01-21 16:12:38 +00:00
erwanlr
a4c650cdff Fixes incorrect RDF URLs detection 2020-01-21 15:06:29 +00:00
erwanlr
31a58f8a8f Fixes rare crash 2020-01-21 14:47:17 +00:00
erwanlr
ba4f15f111 Adds DFs 2020-01-18 11:20:43 +00:00
Erwan
206a913eb9 Merge pull request #1447 from wpscanteam/dependabot/bundler/webmock-tw-3.8.0
Update webmock requirement from ~> 3.7.0 to ~> 3.8.0
2020-01-16 10:17:09 +01:00
dependabot-preview[bot]
21ba490073 Update webmock requirement from ~> 3.7.0 to ~> 3.8.0
Updates the requirements on [webmock](https://github.com/bblimke/webmock) to permit the latest version.
- [Release notes](https://github.com/bblimke/webmock/releases)
- [Changelog](https://github.com/bblimke/webmock/blob/master/CHANGELOG.md)
- [Commits](https://github.com/bblimke/webmock/compare/v3.7.0...v3.8.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-16 05:23:09 +00:00
erwanlr
2a29e2ed95 Adds DFs 2020-01-11 19:54:12 +00:00
Erwan
9517d14fd3 Fixes rubocop offence 2020-01-10 20:06:33 +01:00
Erwan
3deaa896df Fix rubocop typo 2020-01-10 19:28:01 +01:00
Erwan
c117007dc0 Merge pull request #1445 from wpscanteam/dependabot/bundler/rubocop-tw-0.79.0
Update rubocop requirement from ~> 0.78.0 to ~> 0.79.0
2020-01-07 08:53:56 +01:00
dependabot-preview[bot]
50baa238b9 Update rubocop requirement from ~> 0.78.0 to ~> 0.79.0
Updates the requirements on [rubocop](https://github.com/rubocop-hq/rubocop) to permit the latest version.
- [Release notes](https://github.com/rubocop-hq/rubocop/releases)
- [Changelog](https://github.com/rubocop-hq/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop-hq/rubocop/compare/v0.78.0...v0.79.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-07 05:21:29 +00:00
erwanlr
0e2d771660 Adds DFs 2020-01-04 12:17:51 +00:00
erwanlr
32b4670755 Bumps version 2020-01-02 15:28:33 +00:00
erwanlr
4a032d5e12 Merge branch 'ruby-2.7' 2020-01-02 14:53:46 +00:00
erwanlr
5887fede15 Updates deps 2020-01-02 13:53:28 +00:00
erwanlr
ad4eeb9f81 Fixes specs 2020-01-02 13:29:30 +00:00
erwanlr
a62c16d7cc Fixes Rubocop warning 2020-01-02 13:04:01 +00:00
erwanlr
e766e7392a Updates CMScanner dep 2020-01-02 12:52:03 +00:00
erwanlr
025c9c24ca Fixes GH Action 2020-01-02 12:51:23 +00:00
erwanlr
ab052add27 Allows Travis to fail on ruby-2.7 2019-12-28 13:14:19 +00:00
erwanlr
15cb99977b Fixes #1444 2019-12-28 13:10:57 +00:00
erwanlr
82d5af926f Adds Ruby 2.7.0 to Travis 2019-12-28 12:27:20 +00:00
erwanlr
76f73f3dc8 Adds DFs 2019-12-28 11:38:10 +00:00
erwanlr
575b22320e Merge branch 'df' 2019-12-21 10:49:32 +00:00
erwanlr
d20c07dc85 Adds DFs 2019-12-21 10:49:11 +00:00
erwanlr
f89071b87a Adds DFs, Updates rspec behaviour regarding --fail-fast 2019-12-20 15:47:56 +00:00
erwanlr
8b4e90f285 Updates deps + fixes travis 2019-12-19 13:56:06 +00:00
erwanlr
9c4f57c786 Adds DFs 2019-12-19 13:55:21 +00:00
erwanlr
902ec24b77 Adds DFs 2019-12-19 07:55:39 +00:00
erwanlr
7eba77fa63 Displays status code for KnownLocation finders 2019-12-15 09:00:30 +00:00
erwanlr
0753bbf7b3 Adds DF 2019-12-15 08:47:47 +00:00
erwanlr
6b2333614a Adds DFs 2019-12-14 12:14:37 +00:00
erwanlr
80b7f458f5 Fixes #1435 2019-12-08 10:34:18 +00:00
erwanlr
dbd8e59cf4 Typo 2019-12-07 15:46:31 +00:00
erwanlr
9948230ea0 Adds Dfs 2019-12-07 15:40:40 +00:00
Erwan
e2c858ac69 Merge pull request #1434 from crweiner/api-link
Fix links to API signup page
2019-12-03 13:37:55 +01:00
chandler
bac8b613e6 Fix links to API signup page 2019-12-02 17:03:36 -05:00
erwanlr
abbae15c6f Adds DFs 2019-11-30 12:47:32 +00:00
erwanlr
1548e8bfc1 Updates DFs 2019-11-28 20:19:25 +00:00
erwanlr
dc8cf3fc34 Disables a DF causing FP when checking the WP version 2019-11-28 17:15:05 +00:00
Erwan
c3cd815567 Merge pull request #1433 from wpscanteam/dependabot/bundler/rubocop-tw-0.77.0
Update rubocop requirement from ~> 0.76.0 to ~> 0.77.0
2019-11-28 08:50:50 +01:00
dependabot-preview[bot]
ce543b9384 Update rubocop requirement from ~> 0.76.0 to ~> 0.77.0
Updates the requirements on [rubocop](https://github.com/rubocop-hq/rubocop) to permit the latest version.
- [Release notes](https://github.com/rubocop-hq/rubocop/releases)
- [Changelog](https://github.com/rubocop-hq/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop-hq/rubocop/compare/v0.76.0...v0.77.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-28 05:21:09 +00:00
Christian Mehlmauer
9755c8cf42 Delete rubocop.yml 2019-11-26 23:33:52 +01:00
Christian Mehlmauer
434a210fb5 Update and rename rspec.yml to ruby.yml 2019-11-26 23:33:37 +01:00
Christian Mehlmauer
587602665a Update rubocop.yml 2019-11-26 23:29:30 +01:00
Christian Mehlmauer
bfec63df41 Update rspec.yml 2019-11-26 23:26:35 +01:00
Christian Mehlmauer
3b150df1af Update rspec.yml 2019-11-26 23:25:36 +01:00
Christian Mehlmauer
f24ecf0537 Update rubocop.yml 2019-11-26 23:23:13 +01:00
Christian Mehlmauer
9ddecbcc0a Update and rename ruby.yml to rspec.yml 2019-11-26 23:22:46 +01:00
Christian Mehlmauer
947bb8d3d5 Update ruby.yml 2019-11-26 23:18:33 +01:00
Christian Mehlmauer
30cbf87b35 Update gempush.yml 2019-11-26 23:14:53 +01:00
Christian Mehlmauer
69c3aab35a Update .dockerignore 2019-11-26 23:06:05 +01:00
Christian Mehlmauer
bdeb3547f1 Create rubocop.yml 2019-11-26 23:05:45 +01:00
Christian Mehlmauer
99e04b9669 Create ruby.yml 2019-11-26 23:04:03 +01:00
Christian Mehlmauer
680d2fb7eb add gem push 2019-11-26 23:03:23 +01:00
erwanlr
8814eda018 Adds DFs 2019-11-23 11:45:15 +00:00
erwanlr
7e72ba2885 Adds DFs 2019-11-16 11:18:23 +00:00
Christian Mehlmauer
b4d7a8490b change twitter handle 2019-11-13 08:23:18 +01:00
erwanlr
e9a5bc66df Bumps version 2019-11-11 12:41:29 +00:00
erwanlr
edebc77726 Fixes 1426 2019-11-09 17:55:31 +00:00
erwanlr
271dee824d Adds DFs 2019-11-09 10:59:46 +00:00
erwanlr
1e868d10ca Ignores slow specs when executing rake tasks 2019-11-05 20:11:03 +00:00
erwanlr
4be3f17ae4 Bumps version 2019-11-05 19:19:18 +00:00
erwanlr
f24e7be264 Updates dep 2019-11-05 18:47:41 +00:00
erwanlr
9adc26445d Adds DFs 2019-11-02 11:47:11 +00:00
erwanlr
353e7dcbb9 Removes ruby-head from Travis 2019-11-01 17:47:05 +00:00
erwanlr
430e65c12e Updates cms_scanner dep 2019-11-01 16:43:13 +00:00
erwanlr
1aa242a9d8 Avoids duplicates in finding the same thing diffrent pages 2019-11-01 15:20:46 +00:00
erwanlr
7173cd85fe Changes "Detected By" to "Found By" in cli output for consistency with JSON output 2019-11-01 10:52:31 +00:00
erwanlr
b95a4f55e3 Adds DFs 2019-11-01 10:32:02 +00:00
erwanlr
6b5e016770 Improves detection of WP Version, Plugins etc by checking 404 2019-11-01 09:47:44 +00:00
erwanlr
85aa9f61cd Center the banner text 2019-10-31 16:42:40 +00:00
erwanlr
5c187002d6 Updates cms_scanner dep 2019-10-31 16:27:41 +00:00
Erwan
9bc373308b Merge pull request #1420 from wpscanteam/dependabot/bundler/rubocop-tw-0.76.0
Update rubocop requirement from ~> 0.75.0 to ~> 0.76.0
2019-10-29 07:52:15 +01:00
dependabot-preview[bot]
cdeb0fc144 Update rubocop requirement from ~> 0.75.0 to ~> 0.76.0
Updates the requirements on [rubocop](https://github.com/rubocop-hq/rubocop) to permit the latest version.
- [Release notes](https://github.com/rubocop-hq/rubocop/releases)
- [Changelog](https://github.com/rubocop-hq/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop-hq/rubocop/compare/v0.75.0...v0.76.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-29 05:26:34 +00:00
ethicalhack3r
f1acdd9389 Remove 'no monetary cost' from LICENSE file 2019-10-28 16:42:15 +01:00
erwanlr
d6fac6a210 Adds DFs 2019-10-26 12:29:41 +01:00
Erwan
007cfb0801 Updates Ruby versions for Travis (now only latest in stable) 2019-10-26 10:58:56 +02:00
erwanlr
1f9829b7c0 Adds DFs 2019-10-19 22:56:38 +01:00
Erwan
e039d22565 Fix #1413 2019-10-17 20:31:28 +02:00
erwanlr
b0775b1610 Adds DFs 2019-10-15 17:18:40 +01:00
erwanlr
0e429700c6 Fixes #1412 2019-10-12 11:48:14 +01:00
erwanlr
af7804ca23 Adds DF 2019-10-12 10:54:21 +01:00
erwanlr
9da326967b Bumps version 2019-10-11 15:07:50 +01:00
erwanlr
62600b3a66 Fixes #1411 2019-10-11 14:32:00 +01:00
erwanlr
b236138fb5 Adds additional specs related to previous commit 2019-10-10 22:57:26 +01:00
erwanlr
40c2e9a54b Fixes non detection of plugins/themes from homepage in some cases 2019-10-10 22:33:19 +01:00
erwanlr
a9062db57f Improves detection speed of plugins/themes from homepage 2019-10-10 21:15:59 +01:00
erwanlr
2621404c5f Removes useless spec comment 2019-10-10 21:03:54 +01:00
erwanlr
c47211ca79 Fixes empty username returned in some cases 2019-10-10 20:34:39 +01:00
erwanlr
e39a192e8d Checks default wp-content dir regardless of detection mode if not found passively 2019-10-10 19:59:09 +01:00
Erwan
d85035d5ef Merge pull request #1407 from wpscanteam/dependabot/bundler/rspec-tw-3.9.0
Update rspec requirement from ~> 3.8.0 to ~> 3.9.0
2019-10-09 12:50:59 +02:00
dependabot-preview[bot]
de09a97343 Update rspec requirement from ~> 3.8.0 to ~> 3.9.0
Updates the requirements on [rspec](https://github.com/rspec/rspec) to permit the latest version.
- [Release notes](https://github.com/rspec/rspec/releases)
- [Commits](https://github.com/rspec/rspec/compare/v3.8.0...v3.9.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-09 05:48:37 +00:00
erwanlr
a6855345d7 Fixes #1406 2019-10-07 07:03:06 +01:00
erwanlr
a53f88b626 Improves WP detection 2019-10-06 16:51:35 +01:00
erwanlr
7048c82124 Adds DFs 2019-10-06 10:46:12 +01:00
erwanlr
6aa7cda478 Fixes #1404 2019-10-05 20:25:35 +01:00
erwanlr
ff339b9a8c Updates rubocop config 2019-10-03 13:09:14 +01:00
Erwan
8898cc20fe Merge pull request #1403 from wpscanteam/dependabot/bundler/rubocop-performance-tw-1.5.0
Update rubocop-performance requirement from ~> 1.4.0 to ~> 1.5.0
2019-10-02 18:35:11 +02:00
dependabot-preview[bot]
770d1da280 Update rubocop-performance requirement from ~> 1.4.0 to ~> 1.5.0
Updates the requirements on [rubocop-performance](https://github.com/rubocop-hq/rubocop-performance) to permit the latest version.
- [Release notes](https://github.com/rubocop-hq/rubocop-performance/releases)
- [Changelog](https://github.com/rubocop-hq/rubocop-performance/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop-hq/rubocop-performance/compare/v1.4.0...v1.5.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-02 06:46:49 +00:00
Erwan
6ba4e8a29b Merge pull request #1402 from wpscanteam/dependabot/bundler/rubocop-tw-0.75.0
Update rubocop requirement from ~> 0.74.0 to ~> 0.75.0
2019-10-02 08:45:36 +02:00
dependabot-preview[bot]
953ca68495 Update rubocop requirement from ~> 0.74.0 to ~> 0.75.0
Updates the requirements on [rubocop](https://github.com/rubocop-hq/rubocop) to permit the latest version.
- [Release notes](https://github.com/rubocop-hq/rubocop/releases)
- [Changelog](https://github.com/rubocop-hq/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop-hq/rubocop/compare/v0.74.0...v0.75.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-01 06:21:21 +00:00
Erwan
4289dfb37d Merge pull request #1401 from wpscanteam/dependabot/bundler/rake-tw-13.0
Update rake requirement from ~> 12.3 to ~> 13.0
2019-09-30 12:37:15 +02:00
dependabot-preview[bot]
4f6f2f436a Update rake requirement from ~> 12.3 to ~> 13.0
Updates the requirements on [rake](https://github.com/ruby/rake) to permit the latest version.
- [Release notes](https://github.com/ruby/rake/releases)
- [Changelog](https://github.com/ruby/rake/blob/master/History.rdoc)
- [Commits](https://github.com/ruby/rake/compare/v12.3.0...v13.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-30 05:44:30 +00:00
erwanlr
237979a479 Adds DFs 2019-09-28 17:29:35 +01:00
erwanlr
2e48968fd3 Bumps version 2019-09-25 16:00:24 +01:00
erwanlr
9a0c4a5c8f Fixes #1399 2019-09-25 10:02:15 +01:00
Erwan
9a011f0007 Merge pull request #1397 from noplanman/fix_registration_link
Fix broken registration / signup link.
2019-09-25 10:52:06 +02:00
Armando Lüscher
3f907a706f Fix broken registration / signup link. 2019-09-24 23:19:47 +02:00
erwanlr
9446141716 Adds DFs 2019-09-21 10:20:59 +01:00
447 changed files with 153436 additions and 620 deletions

View File

@@ -14,3 +14,4 @@ Dockerfile
*.orig
bin/wpscan-*
.wpscan/
.github/

49
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,49 @@
name: Build
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
ruby: [2.4, 2.5, 2.6, 2.7]
steps:
- name: Checkout code
uses: actions/checkout@v1
- name: Set up Ruby ${{ matrix.ruby }}
uses: actions/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
- name: Restore GEM cache
uses: actions/cache@v1
with:
path: vendor/bundle
key: ${{ runner.os }}-${{ matrix.ruby }}-gem-${{ hashFiles('**/wpscan.gemspec') }}
restore-keys: |
${{ runner.os }}-${{ matrix.ruby }}-gem-
- name: Install GEMs
run: |
gem install bundler
bundle config force_ruby_platform true
bundle config path vendor/bundle
bundle install --jobs 4 --retry 3
- name: rubocop
run: |
bundle exec rubocop
- name: rspec
run: |
bundle exec rspec
- name: Coveralls
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

40
.github/workflows/gempush.yml vendored Normal file
View File

@@ -0,0 +1,40 @@
name: Ruby Gem
on:
release:
types: [published]
jobs:
build:
name: Build + Publish
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Set up Ruby 2.6
uses: actions/setup-ruby@v1
with:
ruby-version: 2.6.x
#- name: Publish to GPR
# run: |
# mkdir -p $HOME/.gem
# touch $HOME/.gem/credentials
# chmod 0600 $HOME/.gem/credentials
# printf -- "---\n:github: Bearer ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
# gem build *.gemspec
# gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} *.gem
# env:
# GEM_HOST_API_KEY: ${{secrets.GITHUB_TOKEN}}
# OWNER: wpscanteam
- name: Publish to RubyGems
run: |
mkdir -p $HOME/.gem
touch $HOME/.gem/credentials
chmod 0600 $HOME/.gem/credentials
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
gem build *.gemspec
gem push *.gem
env:
GEM_HOST_API_KEY: ${{secrets.RUBYGEMS_AUTH_TOKEN}}

5
.rspec
View File

@@ -1,3 +1,2 @@
--color
--fail-fast
--require spec_helper
--require spec_helper
--color

View File

@@ -4,16 +4,10 @@ AllCops:
Exclude:
- '*.gemspec'
- 'vendor/**/*'
ClassVars:
Enabled: false
LineLength:
Layout/LineLength:
Max: 120
Lint/UriEscapeUnescape:
Enabled: false
MethodLength:
Max: 20
Exclude:
- 'app/controllers/enumeration/cli_options.rb'
Metrics/AbcSize:
Max: 25
Metrics/BlockLength:
@@ -25,6 +19,12 @@ Metrics/ClassLength:
- 'app/controllers/enumeration/cli_options.rb'
Metrics/CyclomaticComplexity:
Max: 8
Metrics/MethodLength:
Max: 20
Exclude:
- 'app/controllers/enumeration/cli_options.rb'
Style/ClassVars:
Enabled: false
Style/Documentation:
Enabled: false
Style/FormatStringToken:

View File

@@ -1,4 +1,18 @@
if ENV['GITHUB_ACTION']
require 'simplecov-lcov'
SimpleCov::Formatter::LcovFormatter.config do |c|
c.single_report_path = 'coverage/lcov.info'
c.report_with_single_file = true
end
SimpleCov.formatter = SimpleCov::Formatter::LcovFormatter
end
SimpleCov.start do
enable_coverage :branch # Only supported for Ruby >= 2.5
add_filter '/spec/'
add_filter 'helper'
end

View File

@@ -1,33 +0,0 @@
language: ruby
sudo: false
cache: bundler
rvm:
- 2.4.1
- 2.4.2
- 2.4.3
- 2.4.4
- 2.4.5
- 2.4.6
- 2.5.0
- 2.5.1
- 2.5.2
- 2.5.3
- 2.5.4
- 2.5.5
- 2.6.0
- 2.6.1
- 2.6.2
- 2.6.3
- ruby-head
before_install:
- "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
- gem update --system
matrix:
allow_failures:
- rvm: ruby-head
script:
- bundle exec rubocop
- bundle exec rspec
notifications:
email:
- team@wpscan.org

View File

@@ -38,4 +38,3 @@ USER wpscan
RUN /usr/local/bundle/bin/wpscan --update --verbose
ENTRYPOINT ["/usr/local/bundle/bin/wpscan"]
CMD ["--help"]

View File

@@ -29,8 +29,6 @@ Example cases which do not require a commercial license, and thus fall under the
If you need to purchase a commercial license or are unsure whether you need to purchase a commercial license contact us - team@wpscan.org.
We may grant commercial licenses at no monetary cost at our own discretion if the commercial usage is deemed by the WPScan Team to significantly benefit WPScan.
Free-use Terms and Conditions;
3. Redistribution

View File

@@ -15,7 +15,7 @@
<p align="center">
<a href="https://badge.fury.io/rb/wpscan" target="_blank"><img src="https://badge.fury.io/rb/wpscan.svg"></a>
<a href="https://travis-ci.org/wpscanteam/wpscan" target="_blank"><img src="https://travis-ci.org/wpscanteam/wpscan.svg?branch=master"></a>
<a href="https://github.com/wpscanteam/wpscan/actions?query=workflow%3ABuild" target="_blank"><img src="https://github.com/wpscanteam/wpscan/workflows/Build/badge.svg"></a>
<a href="https://codeclimate.com/github/wpscanteam/wpscan" target="_blank"><img src="https://codeclimate.com/github/wpscanteam/wpscan/badges/gpa.svg"></a>
</p>
@@ -130,6 +130,11 @@ cli_options:
api_token: YOUR_API_TOKEN
```
## Load APi Token From ENV
The API Token will be automatically loaded from the ENV variable `WPSCAN_API_TOKEN` if present. If the `--api-token` CLI option is also provided, the value from the CLI will be used.
## Enumerating usernames
```shell

View File

@@ -6,14 +6,18 @@ exec = []
begin
require 'rubocop/rake_task'
RuboCop::RakeTask.new
exec << :rubocop
rescue LoadError
end
begin
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new(:spec)
RSpec::Core::RakeTask.new(:spec) { |t| t.rspec_opts = %w{--tag ~slow} }
exec << :spec
rescue LoadError
end

View File

@@ -18,9 +18,7 @@ module WPScan
target.content_dir = ParsedCli.wp_content_dir if ParsedCli.wp_content_dir
target.plugins_dir = ParsedCli.wp_plugins_dir if ParsedCli.wp_plugins_dir
return if target.content_dir(ParsedCli.detection_mode)
raise Error::WpContentDirNotDetected
raise Error::WpContentDirNotDetected unless target.content_dir
end
end
end

View File

@@ -69,7 +69,7 @@ module WPScan
OptInteger.new(
['--plugins-threshold THRESHOLD',
'Raise an error when the number of detected plugins via known locations reaches the threshold. ' \
'Set to 0 to ignore the threshold.'], default: 100
'Set to 0 to ignore the threshold.'], default: 100, advanced: true
)
]
end
@@ -98,7 +98,7 @@ module WPScan
OptInteger.new(
['--themes-threshold THRESHOLD',
'Raise an error when the number of detected themes via known locations reaches the threshold. ' \
'Set to 0 to ignore the threshold.'], default: 20
'Set to 0 to ignore the threshold.'], default: 20, advanced: true
)
]
end

View File

@@ -4,6 +4,8 @@ module WPScan
module Controller
# Controller to handle the API token
class VulnApi < CMSScanner::Controller::Base
ENV_KEY = 'WPSCAN_API_TOKEN'
def cli_options
[
OptString.new(['--api-token TOKEN', 'The WPVulnDB API Token to display vulnerability data'])
@@ -11,9 +13,9 @@ module WPScan
end
def before_scan
return unless ParsedCli.api_token
return unless ParsedCli.api_token || ENV.key?(ENV_KEY)
DB::VulnApi.token = ParsedCli.api_token
DB::VulnApi.token = ParsedCli.api_token || ENV[ENV_KEY]
api_status = DB::VulnApi.status

View File

@@ -4,7 +4,6 @@ module WPScan
module Finders
module DbExports
# DB Exports finder
# See https://github.com/wpscanteam/wpscan-v3/issues/62
class KnownLocations < CMSScanner::Finders::Finder
include CMSScanner::Finders::Finder::Enumerator
@@ -41,7 +40,7 @@ module WPScan
# @return [ Hash ]
def potential_urls(opts = {})
urls = {}
domain_name = target.uri.host[/(^[\w|-]+)/, 1]
domain_name = PublicSuffix.domain(target.uri.host)[/(^[\w|-]+)/, 1]
File.open(opts[:list]).each_with_index do |path, index|
path.gsub!('{domain_name}', domain_name)

View File

@@ -16,8 +16,7 @@ module WPScan
target.url(path),
confidence: 70,
found_by: DIRECT_ACCESS,
interesting_entries: target.directory_listing_entries(path),
references: { url: 'https://github.com/wpscanteam/wpscan/issues/422' }
interesting_entries: target.directory_listing_entries(path)
)
end
end

View File

@@ -11,11 +11,7 @@ module WPScan
return unless target.debug_log?(path)
Model::DebugLog.new(
target.url(path),
confidence: 100, found_by: DIRECT_ACCESS,
references: { url: 'https://codex.wordpress.org/Debugging_in_WordPress' }
)
Model::DebugLog.new(target.url(path), confidence: 100, found_by: DIRECT_ACCESS)
end
end
end

View File

@@ -11,12 +11,7 @@ module WPScan
return unless /DUPLICATOR INSTALL-LOG/.match?(target.head_and_get(path).body)
Model::DuplicatorInstallerLog.new(
target.url(path),
confidence: 100,
found_by: DIRECT_ACCESS,
references: { url: 'https://www.exploit-db.com/ghdb/3981/' }
)
Model::DuplicatorInstallerLog.new(target.url(path), confidence: 100, found_by: DIRECT_ACCESS)
end
end
end

View File

@@ -15,10 +15,7 @@ module WPScan
Model::EmergencyPwdResetScript.new(
target.url(path),
confidence: /password/i.match?(res.body) ? 100 : 40,
found_by: DIRECT_ACCESS,
references: {
url: 'https://codex.wordpress.org/Resetting_Your_Password#Using_the_Emergency_Password_Reset_Script'
}
found_by: DIRECT_ACCESS
)
end
end

View File

@@ -16,8 +16,7 @@ module WPScan
target.url(path),
confidence: 100,
found_by: DIRECT_ACCESS,
interesting_entries: fpd_entries,
references: { url: 'https://www.owasp.org/index.php/Full_Path_Disclosure' }
interesting_entries: fpd_entries
)
end
end

View File

@@ -9,20 +9,14 @@ module WPScan
def passive(_opts = {})
pattern = %r{#{target.content_dir}/mu\-plugins/}i
target.in_scope_uris(target.homepage_res) do |uri|
target.in_scope_uris(target.homepage_res, '(//@href|//@src)[contains(., "mu-plugins")]') do |uri|
next unless uri.path&.match?(pattern)
url = target.url('wp-content/mu-plugins/')
target.mu_plugins = true
return Model::MuPlugins.new(
url,
confidence: 70,
found_by: 'URLs In Homepage (Passive Detection)',
to_s: "This site has 'Must Use Plugins': #{url}",
references: { url: 'http://codex.wordpress.org/Must_Use_Plugins' }
)
return Model::MuPlugins.new(url, confidence: 70, found_by: 'URLs In Homepage (Passive Detection)')
end
nil
end
@@ -37,13 +31,7 @@ module WPScan
target.mu_plugins = true
Model::MuPlugins.new(
url,
confidence: 80,
found_by: DIRECT_ACCESS,
to_s: "This site has 'Must Use Plugins': #{url}",
references: { url: 'http://codex.wordpress.org/Must_Use_Plugins' }
)
Model::MuPlugins.new(url, confidence: 80, found_by: DIRECT_ACCESS)
end
end
end

View File

@@ -17,13 +17,7 @@ module WPScan
target.multisite = true
Model::Multisite.new(
url,
confidence: 100,
found_by: DIRECT_ACCESS,
to_s: 'This site seems to be a multisite',
references: { url: 'http://codex.wordpress.org/Glossary#Multisite' }
)
Model::Multisite.new(url, confidence: 100, found_by: DIRECT_ACCESS)
end
end
end

View File

@@ -20,12 +20,7 @@ module WPScan
target.registration_enabled = true
Model::Registration.new(
res.effective_url,
confidence: 100,
found_by: DIRECT_ACCESS,
to_s: "Registration is enabled: #{res.effective_url}"
)
Model::Registration.new(res.effective_url, confidence: 100, found_by: DIRECT_ACCESS)
end
end
end

View File

@@ -13,12 +13,7 @@ module WPScan
return unless res.code == 200 && res.headers['Content-Type'] =~ %r{\Aapplication/zip}i
Model::TmmDbMigrate.new(
url,
confidence: 100,
found_by: DIRECT_ACCESS,
references: { packetstorm: 131_957 }
)
Model::TmmDbMigrate.new(url, confidence: 100, found_by: DIRECT_ACCESS)
end
end
end

View File

@@ -13,12 +13,7 @@ module WPScan
url = target.url(path)
Model::UploadDirectoryListing.new(
url,
confidence: 100,
found_by: DIRECT_ACCESS,
to_s: "Upload directory has listing enabled: #{url}"
)
Model::UploadDirectoryListing.new(url, confidence: 100, found_by: DIRECT_ACCESS)
end
end
end

View File

@@ -14,11 +14,7 @@ module WPScan
return unless SQL_PATTERN.match?(res.body)
Model::UploadSQLDump.new(
target.url(path),
confidence: 100,
found_by: DIRECT_ACCESS
)
Model::UploadSQLDump.new(target.url(path), confidence: 100, found_by: DIRECT_ACCESS)
end
end
end

View File

@@ -11,17 +11,7 @@ module WPScan
return unless res.code == 200
Model::WPCron.new(
wp_cron_url,
confidence: 60,
found_by: DIRECT_ACCESS,
references: {
url: [
'https://www.iplocation.net/defend-wordpress-from-ddos',
'https://github.com/wpscanteam/wpscan/issues/1299'
]
}
)
Model::WPCron.new(wp_cron_url, confidence: 60, found_by: DIRECT_ACCESS)
end
def wp_cron_url

View File

@@ -1,8 +1,10 @@
# frozen_string_literal: true
require_relative 'main_theme/css_style'
require_relative 'main_theme/css_style_in_homepage'
require_relative 'main_theme/css_style_in_404_page'
require_relative 'main_theme/woo_framework_meta_generator'
require_relative 'main_theme/urls_in_homepage'
require_relative 'main_theme/urls_in_404_page'
module WPScan
module Finders
@@ -14,9 +16,11 @@ module WPScan
# @param [ WPScan::Target ] target
def initialize(target)
finders <<
MainTheme::CssStyle.new(target) <<
MainTheme::CssStyleInHomepage.new(target) <<
MainTheme::CssStyleIn404Page.new(target) <<
MainTheme::WooFrameworkMetaGenerator.new(target) <<
MainTheme::UrlsInHomepage.new(target)
MainTheme::UrlsInHomepage.new(target) <<
MainTheme::UrlsIn404Page.new(target)
end
end
end

View File

@@ -0,0 +1,14 @@
# frozen_string_literal: true
module WPScan
module Finders
module MainTheme
# From the CSS style in the 404 page
class CssStyleIn404Page < CssStyleInHomepage
def passive(opts = {})
passive_from_css_href(target.error_404_res, opts) || passive_from_style_code(target.error_404_res, opts)
end
end
end
end
end

View File

@@ -3,9 +3,9 @@
module WPScan
module Finders
module MainTheme
# From the css style
class CssStyle < CMSScanner::Finders::Finder
include Finders::WpItems::URLsInHomepage
# From the CSS style in the homepage
class CssStyleInHomepage < CMSScanner::Finders::Finder
include Finders::WpItems::UrlsInPage # To have the item_code_pattern method available here
def create_theme(slug, style_url, opts)
Model::Theme.new(
@@ -20,7 +20,7 @@ module WPScan
end
def passive_from_css_href(res, opts)
target.in_scope_uris(res, '//style/@src|//link/@href') do |uri|
target.in_scope_uris(res, '//link/@href[contains(., "style.css")]') do |uri|
next unless uri.path =~ %r{/themes/([^\/]+)/style.css\z}i
return create_theme(Regexp.last_match[1], uri.to_s, opts)

View File

@@ -0,0 +1,15 @@
# frozen_string_literal: true
module WPScan
module Finders
module MainTheme
# URLs In 404 Page Finder
class UrlsIn404Page < UrlsInHomepage
# @return [ Typhoeus::Response ]
def page_res
@page_res ||= target.error_404_res
end
end
end
end
end

View File

@@ -5,7 +5,7 @@ module WPScan
module MainTheme
# URLs In Homepage Finder
class UrlsInHomepage < CMSScanner::Finders::Finder
include WpItems::URLsInHomepage
include WpItems::UrlsInPage
# @param [ Hash ] opts
#
@@ -21,6 +21,11 @@ module WPScan
found
end
# @return [ Typhoeus::Response ]
def page_res
@page_res ||= target.homepage_res
end
end
end
end

View File

@@ -10,7 +10,7 @@ module WPScan
PATTERN = /#{THEME_PATTERN}\s+#{FRAMEWORK_PATTERN}/i.freeze
def passive(opts = {})
return unless target.homepage_res.body =~ PATTERN
return unless target.homepage_res.body =~ PATTERN || target.error_404_res.body =~ PATTERN
Model::Theme.new(
Regexp.last_match[1],

View File

@@ -1,6 +1,7 @@
# frozen_string_literal: true
require_relative 'plugins/urls_in_homepage'
require_relative 'plugins/urls_in_404_page'
require_relative 'plugins/known_locations'
# From the DynamicFinders
require_relative 'plugins/comment'
@@ -22,6 +23,7 @@ module WPScan
def initialize(target)
finders <<
Plugins::UrlsInHomepage.new(target) <<
Plugins::UrlsIn404Page.new(target) <<
Plugins::HeaderPattern.new(target) <<
Plugins::Comment.new(target) <<
Plugins::Xpath.new(target) <<

View File

@@ -19,8 +19,12 @@ module WPScan
def aggressive(opts = {})
found = []
enumerate(target_urls(opts), opts.merge(check_full_response: true)) do |_res, slug|
found << Model::Plugin.new(slug, target, opts.merge(found_by: found_by, confidence: 80))
enumerate(target_urls(opts), opts.merge(check_full_response: true)) do |res, slug|
finding_opts = opts.merge(found_by: found_by,
confidence: 80,
interesting_entries: ["#{res.effective_url}, status: #{res.code}"])
found << Model::Plugin.new(slug, target, finding_opts)
raise Error::PluginsThresholdReached if opts[:threshold].positive? && found.size >= opts[:threshold]
end

View File

@@ -0,0 +1,16 @@
# frozen_string_literal: true
module WPScan
module Finders
module Plugins
# URLs In 404 Page Finder
# Typically, the items detected from URLs like /wp-content/plugins/<slug>/
class UrlsIn404Page < UrlsInHomepage
# @return [ Typhoeus::Response ]
def page_res
@page_res ||= target.error_404_res
end
end
end
end
end

View File

@@ -4,10 +4,9 @@ module WPScan
module Finders
module Plugins
# URLs In Homepage Finder
# Typically, the items detected from URLs like
# /wp-content/plugins/<slug>/
# Typically, the items detected from URLs like /wp-content/plugins/<slug>/
class UrlsInHomepage < CMSScanner::Finders::Finder
include WpItems::URLsInHomepage
include WpItems::UrlsInPage
# @param [ Hash ] opts
#
@@ -21,6 +20,11 @@ module WPScan
found
end
# @return [ Typhoeus::Response ]
def page_res
@page_res ||= target.homepage_res
end
end
end
end

View File

@@ -1,12 +1,13 @@
# frozen_string_literal: true
require_relative 'themes/urls_in_homepage'
require_relative 'themes/urls_in_404_page'
require_relative 'themes/known_locations'
module WPScan
module Finders
module Themes
# themes Finder
# Themes Finder
class Base
include CMSScanner::Finders::SameTypeFinder
@@ -14,6 +15,7 @@ module WPScan
def initialize(target)
finders <<
Themes::UrlsInHomepage.new(target) <<
Themes::UrlsIn404Page.new(target) <<
Themes::KnownLocations.new(target)
end
end

View File

@@ -19,8 +19,12 @@ module WPScan
def aggressive(opts = {})
found = []
enumerate(target_urls(opts), opts.merge(check_full_response: true)) do |_res, slug|
found << Model::Theme.new(slug, target, opts.merge(found_by: found_by, confidence: 80))
enumerate(target_urls(opts), opts.merge(check_full_response: true)) do |res, slug|
finding_opts = opts.merge(found_by: found_by,
confidence: 80,
interesting_entries: ["#{res.effective_url}, status: #{res.code}"])
found << Model::Theme.new(slug, target, finding_opts)
raise Error::ThemesThresholdReached if opts[:threshold].positive? && found.size >= opts[:threshold]
end

View File

@@ -0,0 +1,15 @@
# frozen_string_literal: true
module WPScan
module Finders
module Themes
# URLs In 04 Page Finder
class UrlsIn404Page < UrlsInHomepage
# @return [ Typhoeus::Response ]
def page_res
@page_res ||= target.error_404_res
end
end
end
end
end

View File

@@ -5,7 +5,7 @@ module WPScan
module Themes
# URLs In Homepage Finder
class UrlsInHomepage < CMSScanner::Finders::Finder
include WpItems::URLsInHomepage
include WpItems::UrlsInPage
# @param [ Hash ] opts
#
@@ -19,6 +19,11 @@ module WPScan
found
end
# @return [ Typhoeus::Response ]
def page_res
@page_res ||= target.homepage_res
end
end
end
end

View File

@@ -71,11 +71,13 @@ module WPScan
return username, 'Display Name', 50 if username
end
# @param [ String ] url
# @param [ String, Addressable::URI ] uri
#
# @return [ String, nil ]
def username_from_author_url(url)
url[%r{/author/([^/\b]+)/?}i, 1]
def username_from_author_url(uri)
uri = Addressable::URI.parse(uri) unless uri.is_a?(Addressable::URI)
uri.path[%r{/author/([^/\b]+)/?}i, 1]
end
# @param [ Typhoeus::Response ] res
@@ -83,12 +85,12 @@ module WPScan
# @return [ String, nil ] The username found
def username_from_response(res)
# Permalink enabled
target.in_scope_uris(res, '//link/@href|//a/@href') do |uri|
username = username_from_author_url(uri.to_s)
target.in_scope_uris(res, '//@href[contains(., "author/")]') do |uri|
username = username_from_author_url(uri)
return username if username
end
# No permalink
# No permalink, TODO Maybe use xpath to extract the classes ?
res.body[/<body class="archive author author-([^\s]+)[ "]/i, 1]
end
@@ -97,9 +99,12 @@ module WPScan
# @return [ String, nil ]
def display_name_from_body(body)
page = Nokogiri::HTML.parse(body)
# WP >= 3.0
page.css('h1.page-title span').each do |node|
return node.text.to_s
text = node.text.to_s.strip
return text unless text.empty?
end
# WP < 3.0

View File

@@ -45,7 +45,7 @@ module WPScan
def potential_usernames(res)
usernames = []
target.in_scope_uris(res, '//a/@href') do |uri, node|
target.in_scope_uris(res, '//a/@href[contains(., "author")]') do |uri, node|
if uri.path =~ %r{/author/([^/\b]+)/?\z}i
usernames << [Regexp.last_match[1], 'Author Pattern', 100]
elsif /author=[0-9]+/.match?(uri.query)

View File

@@ -34,6 +34,8 @@ module WPScan
def user_details_from_oembed_data(oembed_data)
return unless oembed_data
oembed_data = oembed_data.first if oembed_data.is_a?(Array)
if oembed_data['author_url'] =~ %r{/author/([^/]+)/?\z}
details = [Regexp.last_match[1], 'Author URL', 90]
elsif oembed_data['author_name'] && !oembed_data['author_name'].empty?

View File

@@ -1,3 +1,3 @@
# frozen_string_literal: true
require_relative 'wp_items/urls_in_homepage'
require_relative 'wp_items/urls_in_page'

View File

@@ -4,18 +4,24 @@ module WPScan
module Finders
module WpItems
# URLs In Homepage Module to use in plugins & themes finders
module URLsInHomepage
module UrlsInPage
# @param [ String ] type plugins / themes
# @param [ Boolean ] uniq Wether or not to apply the #uniq on the results
#
# @return [Array<String> ] The plugins/themes detected in the href, src attributes of the homepage
# @return [ Array<String> ] The plugins/themes detected in the href, src attributes of the page
def items_from_links(type, uniq = true)
found = []
xpath = format(
'(//@href|//@src|//@data-src)[contains(., "%s")]',
type == 'plugins' ? target.plugins_dir : target.content_dir
)
target.in_scope_uris(target.homepage_res) do |uri|
target.in_scope_uris(page_res, xpath) do |uri|
next unless uri.to_s =~ item_attribute_pattern(type)
found << Regexp.last_match[1]
slug = Regexp.last_match[1]&.strip
found << slug unless slug&.empty?
end
uniq ? found.uniq.sort : found.sort
@@ -28,7 +34,7 @@ module WPScan
def items_from_codes(type, uniq = true)
found = []
target.homepage_res.html.css('script,style').each do |tag|
page_res.html.xpath('//script[not(@src)]|//style[not(@src)]').each do |tag|
code = tag.text.to_s
next if code.empty?
@@ -42,7 +48,7 @@ module WPScan
#
# @return [ Regexp ]
def item_attribute_pattern(type)
@item_attribute_pattern ||= %r{\A#{item_url_pattern(type)}([^/]+)/}i
@item_attribute_pattern ||= %r{#{item_url_pattern(type)}([^/]+)/}i
end
# @param [ String ] type
@@ -59,7 +65,7 @@ module WPScan
item_dir = type == 'plugins' ? target.plugins_dir : target.content_dir
item_url = type == 'plugins' ? target.plugins_url : target.content_url
url = /#{item_url.gsub(/\A(?:http|https)/i, 'https?').gsub('/', '\\\\\?\/')}/i
url = /#{item_url.gsub(/\A(?:https?)/i, 'https?').gsub('/', '\\\\\?\/')}/i
item_dir = %r{(?:#{url}|\\?\/#{item_dir.gsub('/', '\\\\\?\/')}\\?/)}i
type == 'plugins' ? item_dir : %r{#{item_dir}#{type}\\?\/}i

View File

@@ -28,7 +28,7 @@ module WPScan
end
def passive_urls_xpath
'//a[contains(@href, "rdf")]/@href'
'//a[contains(@href, "/rdf")]/@href'
end
def aggressive_urls(_opts = {})

View File

@@ -8,45 +8,110 @@ module WPScan
end
#
# Empty classes for the #type to be correctly displayed (as taken from the self.class from the parent)
# Some classes are empty for the #type to be correctly displayed (as taken from the self.class from the parent)
#
class BackupDB < InterestingFinding
# @return [ Hash ]
def references
@references ||= { url: ['https://github.com/wpscanteam/wpscan/issues/422'] }
end
end
class DebugLog < InterestingFinding
# @ return [ Hash ]
def references
@references ||= { url: 'https://codex.wordpress.org/Debugging_in_WordPress' }
end
end
class DuplicatorInstallerLog < InterestingFinding
# @return [ Hash ]
def references
@references ||= { url: ['https://www.exploit-db.com/ghdb/3981/'] }
end
end
class EmergencyPwdResetScript < InterestingFinding
def references
@references ||= {
url: ['https://codex.wordpress.org/Resetting_Your_Password#Using_the_Emergency_Password_Reset_Script']
}
end
end
class FullPathDisclosure < InterestingFinding
# @return [ Hash ]
def references
@references ||= { url: ['https://www.owasp.org/index.php/Full_Path_Disclosure'] }
end
end
class MuPlugins < InterestingFinding
# @return [ String ]
def to_s
@to_s ||= "This site has 'Must Use Plugins': #{url}"
end
# @return [ Hash ]
def references
@references ||= { url: ['http://codex.wordpress.org/Must_Use_Plugins'] }
end
end
class Multisite < InterestingFinding
# @return [ String ]
def to_s
@to_s ||= 'This site seems to be a multisite'
end
# @return [ Hash ]
def references
@references ||= { url: ['http://codex.wordpress.org/Glossary#Multisite'] }
end
end
class Readme < InterestingFinding
end
class Registration < InterestingFinding
# @return [ String ]
def to_s
@to_s ||= "Registration is enabled: #{url}"
end
end
class TmmDbMigrate < InterestingFinding
# @return [ Hash ]
def references
@references ||= { packetstorm: [131_957] }
end
end
class UploadDirectoryListing < InterestingFinding
# @return [ String ]
def to_s
@to_s ||= "Upload directory has listing enabled: #{url}"
end
end
class UploadSQLDump < InterestingFinding
end
class WPCron < InterestingFinding
# @return [ String ]
def to_s
@to_s ||= "The external WP-Cron seems to be enabled: #{url}"
end
# @return [ Hash ]
def references
@references ||= {
url: [
'https://www.iplocation.net/defend-wordpress-from-ddos',
'https://github.com/wpscanteam/wpscan/issues/1299'
]
}
end
end
end
end

View File

@@ -101,7 +101,7 @@ module WPScan
#
# @return [ String ]
def parse_style_tag(body, tag)
value = body[/^\s*#{Regexp.escape(tag)}:[\t ]*([^\r\n]+)/i, 1]
value = body[/#{Regexp.escape(tag)}:[\t ]*([^\r\n\*]+)/i, 1]
value && !value.strip.empty? ? value.strip : nil
end

View File

@@ -14,7 +14,7 @@ module WPScan
attr_reader :uri, :slug, :detection_opts, :version_detection_opts, :blog, :path_from_blog, :db_data
delegate :homepage_res, :xpath_pattern_from_page, :in_scope_uris, :head_or_get_params, to: :blog
delegate :homepage_res, :error_404_res, :xpath_pattern_from_page, :in_scope_uris, :head_or_get_params, to: :blog
# @param [ String ] slug The plugin/theme slug
# @param [ Target ] blog The targeted blog
@@ -23,7 +23,7 @@ module WPScan
# @option opts [ Hash ] :version_detection The options to use when looking for the version
# @option opts [ String ] :url The URL of the item
def initialize(slug, blog, opts = {})
@slug = URI.decode(slug)
@slug = Addressable::URI.unencode(slug)
@blog = blog
@uri = Addressable::URI.parse(opts[:url]) if opts[:url]
@@ -83,11 +83,6 @@ module WPScan
end
end
# URI.encode is preferered over Addressable::URI.encode as it will encode
# leading # character:
# URI.encode('#t#') => %23t%23
# Addressable::URI.encode('#t#') => #t%23
#
# @param [ String ] path Optional path to merge with the uri
#
# @return [ String ]
@@ -95,7 +90,7 @@ module WPScan
return unless @uri
return @uri.to_s unless path
@uri.join(URI.encode(path)).to_s
@uri.join(Addressable::URI.encode(path)).to_s
end
# @return [ Boolean ]
@@ -166,7 +161,7 @@ module WPScan
# @return [ Typhoeus::Response ]
def head_and_get(path, codes = [200], params = {})
final_path = +@path_from_blog
final_path << URI.encode(path) unless path.nil?
final_path << path unless path.nil?
blog.head_and_get(final_path, codes, params)
end

View File

@@ -8,7 +8,7 @@ module WPScan
# @return [ Hash ]
def references
{
@references ||= {
url: ['http://codex.wordpress.org/XML-RPC_Pingback_API'],
metasploit: [
'auxiliary/scanner/http/wordpress_ghost_scanner',

View File

@@ -1,14 +1,14 @@
_______________________________________________________________
__ _______ _____
\ \ / / __ \ / ____|
\ \ /\ / /| |__) | (___ ___ __ _ _ __ ®
\ \/ \/ / | ___/ \___ \ / __|/ _` | '_ \
\ /\ / | | ____) | (__| (_| | | | |
\/ \/ |_| |_____/ \___|\__,_|_| |_|
__ _______ _____
\ \ / / __ \ / ____|
\ \ /\ / /| |__) | (___ ___ __ _ _ __ ®
\ \/ \/ / | ___/ \___ \ / __|/ _` | '_ \
\ /\ / | | ____) | (__| (_| | | | |
\/ \/ |_| |_____/ \___|\__,_|_| |_|
WordPress Security Scanner by the WPScan Team
Version <%= WPScan::VERSION %>
WordPress Security Scanner by the WPScan Team
Version <%= WPScan::VERSION %>
<%= ' ' * ((63 - WPScan::DB::Sponsor.text.length)/2) + WPScan::DB::Sponsor.text %>
@_WPScan_, @ethicalhack3r, @erwan_lr, @_FireFart_
@_WPScan_, @ethicalhack3r, @erwan_lr, @firefart
_______________________________________________________________

View File

@@ -1,4 +1,4 @@
| Detected By: <%= @item.found_by %>
| Found By: <%= @item.found_by %>
<% @item.interesting_entries.each do |entry| -%>
| - <%= entry %>
<% end -%>

View File

@@ -9,5 +9,5 @@
<% end -%>
<% else -%>
<%= warning_icon %> No WPVulnDB API Token given, as a result vulnerability data has not been output.
<%= warning_icon %> You can get a free API token with 50 daily requests by registering at https://wpvulndb.com/register.
<%= warning_icon %> You can get a free API token with 50 daily requests by registering at https://wpvulndb.com/users/sign_up
<% end -%>

View File

@@ -5,7 +5,7 @@
"@_WPScan_",
"@ethicalhack3r",
"@erwan_lr",
"@_FireFart_"
"@firefart"
],
"sponsor": <%= WPScan::DB::Sponsor.text.to_json %>
},

View File

@@ -8,6 +8,6 @@
"requests_remaining": <%= @status['requests_remaining'].to_json %>
<% end -%>
<% else -%>
"error": "No WPVulnDB API Token given, as a result vulnerability data has not been output.\nYou can get a free API token with 50 daily requests by registering at https://wpvulndb.com/register."
"error": "No WPVulnDB API Token given, as a result vulnerability data has not been output.\nYou can get a free API token with 50 daily requests by registering at https://wpvulndb.com/users/sign_up"
<% end -%>
},

View File

@@ -67,13 +67,13 @@ module WPScan
# @return [ Hash ] The params for Typhoeus::Request
# @note Those params can't be overriden by CLI options
def request_params
@request_params ||= {
@request_params ||= Browser.instance.default_connect_request_params.merge(
timeout: 600,
connecttimeout: 300,
accept_encoding: 'gzip, deflate',
cache_ttl: 0,
headers: { 'User-Agent' => Browser.instance.default_user_agent, 'Referer' => nil }
}
headers: { 'User-Agent' => Browser.instance.default_user_agent }
)
end
# @return [ String ] The raw file URL associated with the given filename
@@ -85,7 +85,7 @@ module WPScan
def remote_file_checksum(filename)
url = "#{remote_file_url(filename)}.sha512"
res = Browser.get(url, request_params)
res = Typhoeus.get(url, request_params)
raise Error::Download, res if res.timed_out? || res.code != 200
res.body.chomp
@@ -126,7 +126,7 @@ module WPScan
file_path = local_file_path(filename)
file_url = remote_file_url(filename)
res = Browser.get(file_url, request_params)
res = Typhoeus.get(file_url, request_params)
raise Error::Download, res if res.timed_out? || res.code != 200
File.open(file_path, 'wb') { |f| f.write(res.body) }
@@ -148,7 +148,7 @@ module WPScan
create_backup(filename)
dl_checksum = download(filename)
raise "#{filename}: checksums do not match" unless dl_checksum == db_checksum
raise Error::ChecksumsMismatch, filename unless dl_checksum == db_checksum
updated << filename
rescue StandardError => e

View File

@@ -21,8 +21,10 @@ module WPScan
# @return [ Hash ]
def self.get(path, params = {})
return {} unless token
return {} if path.end_with?('/latest') # Remove this when api/v4 is up
res = Browser.get(uri.join(path), params.merge(request_params))
# Typhoeus.get is used rather than Browser.get to avoid merging irrelevant params from the CLI
res = Typhoeus.get(uri.join(path), default_request_params.merge(params))
return {} if res.code == 404 # This is for API inconsistencies when dots in path
return JSON.parse(res.body) if NON_ERROR_CODES.include?(res.code)
@@ -64,15 +66,14 @@ module WPScan
end
# @return [ Hash ]
def self.request_params
{
# @note Those params can not be overriden by CLI options
def self.default_request_params
Browser.instance.default_connect_request_params.merge(
headers: {
'Host' => uri.host, # Reset in case user provided a --vhost for the target
'Referer' => nil, # Removes referer set by the cmsscanner to the target url
'User-Agent' => Browser.instance.default_user_agent,
'Authorization' => "Token token=#{token}"
}
}
)
end
end
end

View File

@@ -8,5 +8,17 @@ module WPScan
'Update required, you can not run a scan if a database file is missing.'
end
end
class ChecksumsMismatch < Standard
attr_reader :db_file
def initialize(db_file)
@db_file = db_file
end
def to_s
"#{db_file}: checksums do not match. Please try again in a few minutes."
end
end
end
end

View File

@@ -44,19 +44,27 @@ module WPScan
#
# @param [ Typhoeus::Response ] response
# @param [ Hash ] opts
# @return [ Mixed ]
# @return [ Mixed: nil, Object, Array ]
def find(_response, _opts = {})
raise NoMethodError
end
# @param [ Hash ] opts
# @return [ Mixed ] See #find
def passive(opts = {})
return if self.class::PATH
find(target.homepage_res, opts)
homepage_result = find(target.homepage_res, opts)
if homepage_result
return homepage_result unless homepage_result.is_a?(Array) && homepage_result.empty?
end
find(target.error_404_res, opts)
end
# @param [ Hash ] opts
# @return [ Mixed ] See #find
def aggressive(opts = {})
return unless self.class::PATH

View File

@@ -31,9 +31,14 @@ module WPScan
passive_configs.each do |slug, configs|
configs.each do |klass, config|
item = process_response(opts, target.homepage_res, slug, klass, config)
[target.homepage_res, target.error_404_res].each do |page_res|
item = process_response(opts, page_res, slug, klass, config)
found << item if item.is_a?(Model::WpItem)
if item.is_a?(Model::WpItem)
found << item
break # No need to check the other page if detected in the current
end
end
end
end

View File

@@ -37,6 +37,8 @@ module WPScan
end
end
# This one has been disabled from the DF.yml as it was causing FPs when a plugin had numerous
# files matching a known WP version.
class WpItemQueryParameter < QueryParameter
def xpath
@xpath ||=

View File

@@ -11,7 +11,9 @@ module WPScan
module WordPress
include CMSScanner::Target::Platform::PHP
WORDPRESS_PATTERN = %r{/(?:(?:wp-content/(?:themes|(?:mu\-)?plugins|uploads))|wp-includes)/}i.freeze
WORDPRESS_PATTERN = %r{/(?:(?:wp-content/(?:themes|(?:mu\-)?plugins|uploads))|wp-includes)/}i.freeze
WP_JSON_OEMBED_PATTERN = %r{/wp\-json/oembed/}i.freeze
WP_ADMIN_AJAX_PATTERN = %r{\\?/wp\-admin\\?/admin\-ajax\.php}i.freeze
# These methods are used in the associated interesting_findings finders
# to keep the boolean state of the finding rather than re-check the whole thing again
@@ -22,22 +24,20 @@ module WPScan
# @param [ Symbol ] detection_mode
#
# @return [ Boolean ]
# @return [ Boolean ] Whether or not the target is running WordPress
def wordpress?(detection_mode)
in_scope_uris(homepage_res) do |uri|
return true if uri.path.match(WORDPRESS_PATTERN)
[homepage_res, error_404_res].each do |page_res|
return true if wordpress_from_meta_comments_or_scripts?(page_res)
end
homepage_res.html.css('meta[name="generator"]').each do |node|
return true if /wordpress/i.match?(node['content'])
end
return true unless comments_from_page(/wordpress/i, homepage_res).empty?
if %i[mixed aggressive].include?(detection_mode)
%w[wp-admin/install.php wp-login.php].each do |path|
in_scope_uris(Browser.get_and_follow_location(url(path))).each do |uri|
return true if uri.path.match(WORDPRESS_PATTERN)
res = Browser.get_and_follow_location(url(path))
next unless res.code == 200
in_scope_uris(res, '//link/@href|//script/@src') do |uri|
return true if WORDPRESS_PATTERN.match?(uri.path)
end
end
end
@@ -45,6 +45,26 @@ module WPScan
false
end
# @param [ Typhoeus::Response ] response
# @return [ Boolean ]
def wordpress_from_meta_comments_or_scripts?(response)
in_scope_uris(response, '//link/@href|//script/@src') do |uri|
return true if WORDPRESS_PATTERN.match?(uri.path) || WP_JSON_OEMBED_PATTERN.match?(uri.path)
end
return true if response.html.css('meta[name="generator"]').any? do |node|
/wordpress/i.match?(node['content'])
end
return true unless comments_from_page(/wordpress/i, response).empty?
return true if response.html.xpath('//script[not(@src)]').any? do |node|
WP_ADMIN_AJAX_PATTERN.match?(node.text)
end
false
end
COOKIE_PATTERNS = {
'vjs' => /createCookie\('vjs','(?<c_value>\d+)',\d+\);/i
}.freeze
@@ -82,10 +102,11 @@ module WPScan
def wordpress_hosted?
return true if /\.wordpress\.com$/i.match?(uri.host)
unless content_dir(:passive)
unless content_dir
pattern = %r{https?://s\d\.wp\.com#{WORDPRESS_PATTERN}}i.freeze
xpath = '(//@href|//@src)[contains(., "wp.com")]'
uris_from_page(homepage_res) do |uri|
uris_from_page(homepage_res, xpath) do |uri|
return true if uri.to_s.match?(pattern)
end
end

View File

@@ -13,25 +13,24 @@ module WPScan
@plugins_dir = dir.chomp('/')
end
# @param [ Symbol ] detection_mode
# @return [ String ] The wp-content directory
def content_dir(detection_mode = :mixed)
def content_dir
unless @content_dir
# scope_url_pattern is from CMSScanner::Target
pattern = %r{#{scope_url_pattern}([\w\s\-/]+)\\?/(?:themes|plugins|uploads|cache)\\?/}i
pattern = %r{#{scope_url_pattern}([\w\s\-/]+?)\\?/(?:themes|plugins|uploads|cache)\\?/}i
in_scope_uris(homepage_res) do |uri|
return @content_dir = Regexp.last_match[1] if uri.to_s.match(pattern)
[homepage_res, error_404_res].each do |page_res|
in_scope_uris(page_res, '//link/@href|//script/@src|//img/@src') do |uri|
return @content_dir = Regexp.last_match[1] if uri.to_s.match(pattern)
end
# Checks for the pattern in raw JS code, as well as @content attributes of meta tags
xpath_pattern_from_page('//script[not(@src)]|//meta/@content', pattern, page_res) do |match|
return @content_dir = match[1]
end
end
# Checks for the pattern in raw JS code, as well as @content attributes of meta tags
xpath_pattern_from_page('//script[not(@src)]|//meta/@content', pattern, homepage_res) do |match|
return @content_dir = match[1]
end
unless detection_mode == :passive
return @content_dir = 'wp-content' if default_content_dir_exists?
end
return @content_dir = 'wp-content' if default_content_dir_exists?
end
@content_dir
@@ -72,7 +71,7 @@ module WPScan
#
# @return [ String ]
def plugin_url(slug)
plugins_uri.join("#{URI.encode(slug)}/").to_s
plugins_uri.join("#{Addressable::URI.encode(slug)}/").to_s
end
# @return [ String ]
@@ -94,7 +93,7 @@ module WPScan
#
# @return [ String ]
def theme_url(slug)
themes_uri.join("#{URI.encode(slug)}/").to_s
themes_uri.join("#{Addressable::URI.encode(slug)}/").to_s
end
# @return [ String, False ] String of the sub_dir found, false otherwise
@@ -106,9 +105,12 @@ module WPScan
# url_pattern is from CMSScanner::Target
pattern = %r{#{url_pattern}(.+?)/(?:xmlrpc\.php|wp\-includes/)}i
xpath = '(//@src|//@href|//@data-src)[contains(., "xmlrpc.php") or contains(., "wp-includes/")]'
in_scope_uris(homepage_res) do |uri|
return @sub_dir = Regexp.last_match[1] if uri.to_s.match(pattern)
[homepage_res, error_404_res].each do |page_res|
in_scope_uris(page_res, xpath) do |uri|
return @sub_dir = Regexp.last_match[1] if uri.to_s.match(pattern)
end
end
@sub_dir = false

View File

@@ -2,5 +2,5 @@
# Version
module WPScan
VERSION = '3.7.1'
VERSION = '3.7.10'
end

View File

@@ -166,6 +166,7 @@ describe WPScan::Controller::Core do
before do
expect(core).to receive(:load_server_module)
expect(core.target).to receive(:wordpress?).with(:mixed).and_return(true)
expect(core.target).to receive(:wordpress_hosted?).and_return(false)
end
it 'calls the formatter when started and finished to update the db' do
@@ -174,56 +175,6 @@ describe WPScan::Controller::Core do
end
end
context 'when a redirect occurs' do
before do
stub_request(:any, target_url)
expect(core.target).to receive(:homepage_res)
.at_least(1)
.and_return(Typhoeus::Response.new(effective_url: redirection, body: ''))
end
context 'to the wp-admin/install.php' do
let(:redirection) { "#{target_url}wp-admin/install.php" }
it 'calls the formatter with the correct parameters and exit' do
expect(core.formatter).to receive(:output)
.with('not_fully_configured', hash_including(url: redirection), 'core').ordered
# TODO: Would be cool to be able to test the exit code
expect { core.before_scan }.to raise_error(SystemExit)
end
end
context 'to something else' do
let(:redirection) { 'http://g.com/' }
it 'raises an error' do
expect { core.before_scan }.to raise_error(CMSScanner::Error::HTTPRedirect)
end
end
context 'to another path with the wp-admin/install.php in the query' do
let(:redirection) { "#{target_url}index.php?a=/wp-admin/install.php" }
context 'when wordpress' do
it 'does not raise an error' do
expect(core.target).to receive(:wordpress?).with(:mixed).and_return(true)
expect { core.before_scan }.to_not raise_error
end
end
context 'when not wordpress' do
it 'raises an error' do
expect(core.target).to receive(:wordpress?).twice.with(:mixed).and_return(false)
expect { core.before_scan }.to raise_error(WPScan::Error::NotWordPress)
end
end
end
end
context 'when hosted on wordpress.com' do
let(:target_url) { 'http://ex.wordpress.com' }
@@ -234,52 +185,106 @@ describe WPScan::Controller::Core do
end
end
context 'when wordpress' do
before do
expect(core).to receive(:load_server_module)
expect(core.target).to receive(:wordpress?).with(:mixed).and_return(true)
end
context 'when not hosted on wordpress.com' do
before { allow(core.target).to receive(:wordpress_hosted?).and_return(false) }
it 'does not raise any error' do
expect { core.before_scan }.to_not raise_error
end
end
context 'when a redirect occurs' do
before do
stub_request(:any, target_url)
context 'when not wordpress' do
before do
expect(core).to receive(:load_server_module)
end
expect(core.target).to receive(:homepage_res)
.at_least(1)
.and_return(Typhoeus::Response.new(effective_url: redirection, body: ''))
end
context 'when no --force' do
before { expect(core.target).to receive(:maybe_add_cookies) }
context 'to the wp-admin/install.php' do
let(:redirection) { "#{target_url}wp-admin/install.php" }
context 'when no cookies added or still not wordpress after being added' do
it 'raises an error' do
expect(core.target).to receive(:wordpress?).twice.with(:mixed).and_return(false)
it 'calls the formatter with the correct parameters and exit' do
expect(core.formatter).to receive(:output)
.with('not_fully_configured', hash_including(url: redirection), 'core').ordered
expect { core.before_scan }.to raise_error(WPScan::Error::NotWordPress)
# TODO: Would be cool to be able to test the exit code
expect { core.before_scan }.to raise_error(SystemExit)
end
end
context 'when the added cookies solved it' do
it 'does not raise an error' do
expect(core.target).to receive(:wordpress?).with(:mixed).and_return(false).ordered
expect(core.target).to receive(:wordpress?).with(:mixed).and_return(true).ordered
context 'to something else' do
let(:redirection) { 'http://g.com/' }
it 'raises an error' do
expect { core.before_scan }.to raise_error(CMSScanner::Error::HTTPRedirect)
end
end
context 'to another path with the wp-admin/install.php in the query' do
let(:redirection) { "#{target_url}index.php?a=/wp-admin/install.php" }
context 'when wordpress' do
it 'does not raise an error' do
expect(core.target).to receive(:wordpress?).with(:mixed).and_return(true)
expect { core.before_scan }.to_not raise_error
end
end
context 'when not wordpress' do
it 'raises an error' do
expect(core.target).to receive(:wordpress?).twice.with(:mixed).and_return(false)
expect { core.before_scan }.to raise_error(WPScan::Error::NotWordPress)
end
end
end
end
context 'when wordpress' do
before do
expect(core).to receive(:load_server_module)
expect(core.target).to receive(:wordpress?).with(:mixed).and_return(true)
end
it 'does not raise any error' do
expect { core.before_scan }.to_not raise_error
end
end
context 'when not wordpress' do
before do
expect(core).to receive(:load_server_module)
end
context 'when no --force' do
before { expect(core.target).to receive(:maybe_add_cookies) }
context 'when no cookies added or still not wordpress after being added' do
it 'raises an error' do
expect(core.target).to receive(:wordpress?).twice.with(:mixed).and_return(false)
expect { core.before_scan }.to raise_error(WPScan::Error::NotWordPress)
end
end
context 'when the added cookies solved it' do
it 'does not raise an error' do
expect(core.target).to receive(:wordpress?).with(:mixed).and_return(false).ordered
expect(core.target).to receive(:wordpress?).with(:mixed).and_return(true).ordered
expect { core.before_scan }.to_not raise_error
end
end
end
context 'when --force' do
let(:cli_args) { "#{super()} --force" }
it 'does not raise any error' do
expect(core.target).to receive(:wordpress?).with(:mixed).and_return(false)
expect { core.before_scan }.to_not raise_error
end
end
end
context 'when --force' do
let(:cli_args) { "#{super()} --force" }
it 'does not raise any error' do
expect(core.target).to receive(:wordpress?).with(:mixed).and_return(false)
expect { core.before_scan }.to_not raise_error
end
end
end
end
end

View File

@@ -20,7 +20,7 @@ describe WPScan::Controller::CustomDirectories do
describe '#before_scan' do
context 'when the content_dir is not found and not supplied' do
before { expect(controller.target).to receive(:content_dir).with(:mixed) }
before { expect(controller.target).to receive(:content_dir).and_return(nil) }
it 'raises an exception' do
expect { controller.before_scan }.to raise_error(WPScan::Error::WpContentDirNotDetected)

View File

@@ -74,20 +74,40 @@ describe WPScan::Controller::VulnApi do
context 'when limited requests' do
let(:requests) { 100 }
it 'does not raise an error' do
it 'sets the token and does not raise an error' do
expect { controller.before_scan }.to_not raise_error
expect(WPScan::DB::VulnApi.token).to eql 'token'
end
context 'when unlimited requests' do
let(:requests) { 'Unlimited' }
it 'does not raise an error' do
it 'sets the token and does not raise an error' do
expect { controller.before_scan }.to_not raise_error
expect(WPScan::DB::VulnApi.token).to eql 'token'
end
end
end
end
end
end
context 'when token in ENV' do
before do
ENV[described_class::ENV_KEY] = 'token-from-env'
expect(WPScan::DB::VulnApi)
.to receive(:status)
.and_return('success' => true, 'plan' => 'free', 'requests_remaining' => 'Unlimited')
end
it 'sets the token and does not raise an error' do
expect { controller.before_scan }.to_not raise_error
expect(WPScan::DB::VulnApi.token).to eql 'token-from-env'
end
end
end
end

View File

@@ -9,7 +9,7 @@ describe WPScan::Finders::DbExports::KnownLocations do
describe '#potential_urls' do
before do
expect(target).to receive(:sub_dir).at_least(1).and_return(false)
allow(target).to receive(:sub_dir).and_return(false)
end
it 'replace {domain_name} by its value' do
@@ -22,11 +22,45 @@ describe WPScan::Finders::DbExports::KnownLocations do
http://ex.lo/aa/backups/db_backup.sql
]
end
%w[dev poc www].each do |sub_domain|
context "when #{sub_domain} sub-domain" do
let(:url) { "https://#{sub_domain}.domain.tld" }
it 'replace {domain_name} by its correct value' do
expect(finder.potential_urls(opts).keys).to include "#{url}/domain.sql"
end
end
end
context 'when multi-level tlds' do
let(:url) { 'https://something.com.tr' }
it 'replace {domain_name} by its correct value' do
expect(finder.potential_urls(opts).keys).to include 'https://something.com.tr/something.sql'
end
end
context 'when multi-level tlds and sub-domain' do
let(:url) { 'https://dev.something.com.tr' }
it 'replace {domain_name} by its correct value' do
expect(finder.potential_urls(opts).keys).to include 'https://dev.something.com.tr/something.sql'
end
end
context 'when some weird stuff' do
let(:url) { 'https://098f6bcd4621d373cade4e832627b4f6.aa-bb-ccc-dd.domain-test.com' }
it 'replace {domain_name} by its correct value' do
expect(finder.potential_urls(opts).keys).to include "#{url}/domain-test.sql"
end
end
end
describe '#aggressive' do
before do
expect(target).to receive(:sub_dir).at_least(1).and_return(false)
allow(target).to receive(:sub_dir).and_return(false)
expect(target).to receive(:head_or_get_params).and_return(method: :head)
finder.potential_urls(opts).each_key do |url|

View File

@@ -6,8 +6,55 @@ describe WPScan::Finders::InterestingFindings::MuPlugins do
let(:url) { 'http://ex.lo/' }
let(:fixtures) { FINDERS_FIXTURES.join('interesting_findings', 'mu_plugins') }
before do
expect(target).to receive(:content_dir).at_least(1).and_return('wp-content')
end
describe '#passive' do
xit
before { stub_request(:get, url).to_return(body: body) }
context 'when no uris' do
let(:body) { '' }
its(:passive) { should be nil }
end
context 'when a large amount of unrelated uris' do
let(:body) do
Array.new(250) { |i| "<a href='#{url}#{i}.html'>Some Link</a><img src='#{url}img-#{i}.png'/>" }.join("\n")
end
it 'should not take a while to process the page' do
time_start = Time.now
result = finder.passive
time_end = Time.now
expect(result).to be nil
expect(time_end - time_start).to be < 1
end
end
context 'when uris' do
let(:body) { File.read(fixtures.join(fixture)) }
context 'when none matching' do
let(:fixture) { 'no_match.html' }
its(:passive) { should be nil }
end
context 'when matching via href' do
let(:fixture) { 'match_href.html' }
its(:passive) { should be_a WPScan::Model::MuPlugins }
end
context 'when matching from src' do
let(:fixture) { 'match_src.html' }
its(:passive) { should be_a WPScan::Model::MuPlugins }
end
end
end
describe '#aggressive' do

View File

@@ -0,0 +1,11 @@
# frozen_string_literal: true
describe WPScan::Finders::MainTheme::CssStyleIn404Page do
subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }
let(:url) { 'http://wp.lab/' }
let(:fixtures) { FINDERS_FIXTURES.join('main_theme', 'css_style_in_404_page') }
# This stuff is just a child class of CssStyleInHomepage (using the error_404_res rather than homepage_res)
# which already has a spec
end

View File

@@ -1,10 +1,10 @@
# frozen_string_literal: true
describe WPScan::Finders::MainTheme::CssStyle do
describe WPScan::Finders::MainTheme::CssStyleInHomepage do
subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }
let(:url) { 'http://wp.lab/' }
let(:fixtures) { FINDERS_FIXTURES.join('main_theme', 'css_style') }
let(:fixtures) { FINDERS_FIXTURES.join('main_theme', 'css_style_in_homepage') }
describe '#passive' do
after do
@@ -33,7 +33,7 @@ describe WPScan::Finders::MainTheme::CssStyle do
@expected = WPScan::Model::Theme.new(
'twentyfifteen',
target,
found_by: 'Css Style (Passive Detection)',
found_by: 'Css Style In Homepage (Passive Detection)',
confidence: 70,
style_url: 'http://wp.lab/wp-content/themes/twentyfifteen/style.css?ver=4.1.1'
)
@@ -47,7 +47,7 @@ describe WPScan::Finders::MainTheme::CssStyle do
@expected = WPScan::Model::Theme.new(
'custom',
target,
found_by: 'Css Style (Passive Detection)',
found_by: 'Css Style In Homepage (Passive Detection)',
confidence: 70,
style_url: 'http://wp.lab/wp-content/themes/custom/style.css'
)

View File

@@ -0,0 +1,11 @@
# frozen_string_literal: true
describe WPScan::Finders::MainTheme::UrlsIn404Page do
subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) }
let(:url) { 'http://wp.lab/' }
let(:fixtures) { FINDERS_FIXTURES.join('main_theme', 'urls_in_404_page') }
# This stuff is just a child class of URLsInHomepage (using the error_404_res rather than homepage_res)
# which already has a spec
end

View File

@@ -6,7 +6,8 @@ describe WPScan::Finders::MainTheme::UrlsInHomepage do
let(:url) { 'http://wp.lab/' }
let(:fixtures) { FINDERS_FIXTURES.join('main_theme', 'urls_in_homepage') }
it_behaves_like 'App::Finders::WpItems::URLsInHomepage' do
it_behaves_like 'App::Finders::WpItems::UrlsInPage' do
let(:page_url) { url }
let(:type) { 'themes' }
let(:uniq_links) { false }
let(:uniq_codes) { false }
@@ -18,6 +19,8 @@ describe WPScan::Finders::MainTheme::UrlsInHomepage do
before do
stub_request(:get, /.*.css/)
stub_request(:get, target.url).to_return(body: File.read(fixtures.join('found.html')))
allow(target).to receive(:content_dir).and_return('wp-content')
end
it 'returns the expected Themes' do

View File

@@ -7,32 +7,50 @@ describe WPScan::Finders::MainTheme::WooFrameworkMetaGenerator do
let(:fixtures) { FINDERS_FIXTURES.join('main_theme', 'woo_framework_meta_generator') }
describe '#passive' do
after do
stub_request(:get, url).to_return(body: File.read(fixtures.join(@file)))
expect(finder.passive).to eql @expected
before do
stub_request(:get, url).to_return(body: File.read(fixtures.join(homepage_fixture)))
stub_request(:get, ERROR_404_URL_PATTERN).to_return(body: File.read(fixtures.join(error_404_fixture)))
end
context 'when no Woo generator' do
let(:homepage_fixture) { 'no_woo_generator.html' }
let(:error_404_fixture) { 'no_woo_generator.html' }
it 'returns nil' do
@file = 'no_woo_generator.html'
@expected = nil
expect(finder.passive).to eql nil
end
end
context 'when Woo generator' do
before do
expect(target).to receive(:content_dir).at_least(1).and_return('wp-content')
allow(target).to receive(:content_dir).and_return('wp-content')
stub_request(:get, "#{url}wp-content/themes/Merchant/style.css")
end
it 'returns the expected theme' do
@file = 'woo_generator.html'
@expected = WPScan::Model::Theme.new(
'Merchant', target,
found_by: 'Woo Framework Meta Generator (Passive Detection)',
confidence: 80
)
context 'from the homepage' do
let(:homepage_fixture) { 'woo_generator.html' }
let(:error_404_fixture) { 'no_woo_generator.html' }
it 'returns the expected theme' do
expect(finder.passive).to eql WPScan::Model::Theme.new(
'Merchant', target,
found_by: 'Woo Framework Meta Generator (Passive Detection)',
confidence: 80
)
end
end
context 'from the 404 page' do
let(:homepage_fixture) { 'no_woo_generator.html' }
let(:error_404_fixture) { 'woo_generator.html' }
it 'returns the expected theme' do
expect(finder.passive).to eql WPScan::Model::Theme.new(
'Merchant', target,
found_by: 'Woo Framework Meta Generator (Passive Detection)',
confidence: 80
)
end
end
end
end

View File

@@ -8,7 +8,7 @@ describe WPScan::Finders::MainTheme::Base do
describe '#finders' do
it 'contains the expected finders' do
expect(main_theme.finders.map { |f| f.class.to_s.demodulize })
.to eq %w[CssStyle WooFrameworkMetaGenerator UrlsInHomepage]
.to eq %w[CssStyleInHomepage CssStyleIn404Page WooFrameworkMetaGenerator UrlsInHomepage UrlsIn404Page]
end
end
end

View File

@@ -0,0 +1,11 @@
# frozen_string_literal: true
describe WPScan::Finders::Plugins::UrlsIn404Page do
subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) }
let(:url) { 'https://wp.lab/' }
let(:fixtures) { FINDERS_FIXTURES.join('plugins', 'urls_in_404_page') }
# This stuff is just a child class of URLsInHomepage (using the error_404_res rather than homepage_res)
# which already has a spec
end

View File

@@ -3,14 +3,17 @@
describe WPScan::Finders::Plugins::UrlsInHomepage do
subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) }
let(:url) { 'http://wp.lab/' }
let(:url) { 'https://wp.lab/' }
let(:fixtures) { FINDERS_FIXTURES.join('plugins', 'urls_in_homepage') }
it_behaves_like 'App::Finders::WpItems::URLsInHomepage' do
before { target.scope << 'sub.lab' }
it_behaves_like 'App::Finders::WpItems::UrlsInPage' do
let(:page_url) { url }
let(:type) { 'plugins' }
let(:uniq_links) { true }
let(:uniq_codes) { true }
let(:expected_from_links) { (1..4).map { |i| "dl-#{i}" } }
let(:expected_from_links) { (1..5).map { |i| "dl-#{i}" } }
let(:expected_from_codes) { (1..6).map { |i| "dc-#{i}" } }
end

View File

@@ -8,7 +8,7 @@ describe WPScan::Finders::Plugins::Base do
describe '#finders' do
it 'contains the expected finders' do
expect(plugins.finders.map { |f| f.class.to_s.demodulize })
.to eq %w[UrlsInHomepage HeaderPattern Comment Xpath BodyPattern JavascriptVar KnownLocations]
.to eq %w[UrlsInHomepage UrlsIn404Page HeaderPattern Comment Xpath BodyPattern JavascriptVar KnownLocations]
end
end
end

View File

@@ -0,0 +1,11 @@
# frozen_string_literal: true
describe WPScan::Finders::Themes::UrlsIn404Page do
subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new(url) }
let(:url) { 'http://wp.lab/' }
let(:fixtures) { FINDERS_FIXTURES.join('themes', 'urls_in_404_page') }
# This stuff is just a child class of URLsInHomepage (using the error_404_res rather than homepage_res)
# which already has a spec
end

View File

@@ -6,7 +6,10 @@ describe WPScan::Finders::Themes::UrlsInHomepage do
let(:url) { 'http://wp.lab/' }
let(:fixtures) { FINDERS_FIXTURES.join('themes', 'urls_in_homepage') }
it_behaves_like 'App::Finders::WpItems::URLsInHomepage' do
# before { target.scope << 'sub.lab' }
it_behaves_like 'App::Finders::WpItems::UrlsInPage' do
let(:page_url) { url }
let(:type) { 'themes' }
let(:uniq_links) { true }
let(:uniq_codes) { true }

View File

@@ -8,7 +8,7 @@ describe WPScan::Finders::Themes::Base do
describe '#finders' do
it 'contains the expected finders' do
expect(themes.finders.map { |f| f.class.to_s.demodulize })
.to eq %w[UrlsInHomepage KnownLocations]
.to eq %w[UrlsInHomepage UrlsIn404Page KnownLocations]
end
end
end

View File

@@ -19,7 +19,7 @@ describe WPScan::Finders::Users::AuthorIdBruteForcing do
end
end
describe '#potential_username' do
describe '#username_from_response' do
[
'4.1.1', '4.1.1-permalink',
'3.0', '3.0-permalink',
@@ -32,6 +32,19 @@ describe WPScan::Finders::Users::AuthorIdBruteForcing do
expect(finder.username_from_response(res)).to eql 'admin'
end
end
context 'when a lot of unrelated links' do
it 'should not take a while to process the page' do
body = Array.new(300) { |i| "<a href='#{url}#{i}.html'>Some Link</a>" }.join("\n")
body << '<a href="https://wp.lab/author/test/">Link</a>'
time_start = Time.now
expect(finder.username_from_response(Typhoeus::Response.new(body: body))).to eql 'test'
time_end = Time.now
expect(time_end - time_start).to be < 1
end
end
end
describe '#display_name_from_body' do
@@ -50,7 +63,7 @@ describe WPScan::Finders::Users::AuthorIdBruteForcing do
end
context 'when no display_name' do
['4.1.1', '3.0', '2.9.2'].each do |file|
%w[4.9-span-tag 4.1.1 3.0 2.9.2].each do |file|
it "returns nil for #{file}-empty.html" do
body = File.read(fixtures.join("#{file}-empty.html"))

View File

@@ -16,12 +16,31 @@ describe WPScan::Finders::Users::AuthorPosts do
results = finder.potential_usernames(res)
expect(results).to eql([
['admin', 'Author Pattern', 100],
['admin display_name', 'Display Name', 30],
['editor', 'Author Pattern', 100],
['editor', 'Display Name', 30]
])
expect(results).to eql [
['admin', 'Author Pattern', 100],
['admin display_name', 'Display Name', 30],
['editor', 'Author Pattern', 100],
['editor', 'Display Name', 30]
]
end
context 'when a lot of unrelated uris' do
it 'should not take a while to process the page' do
body = Array.new(300) { |i| "<a href='#{url}#{i}.html'>Some Link</a>" }.join("\n")
body << "<a href='#{url}author/admin/'>Other Link</a>"
body << "<a href='#{url}?author=2'>user display name</a>"
time_start = Time.now
results = finder.potential_usernames(Typhoeus::Response.new(body: body))
time_end = Time.now
expect(results).to eql [
['admin', 'Author Pattern', 100],
['user display name', 'Display Name', 30]
]
expect(time_end - time_start).to be < 1
end
end
end
end

View File

@@ -19,15 +19,17 @@ describe WPScan::Finders::Users::OembedApi do
end
context 'when a JSON response' do
let(:body) { File.read(fixture) }
context 'when 404' do
let(:body) { File.read(fixtures.join('404.json')) }
let(:fixture) { fixtures.join('404.json') }
its(:aggressive) { should eql([]) }
end
context 'when 200' do
context 'when author_url present' do
let(:body) { File.read(fixtures.join('200_author_url.json')) }
let(:fixture) { fixtures.join('200_author_url.json') }
it 'returns the expected array of users' do
users = finder.aggressive
@@ -44,7 +46,7 @@ describe WPScan::Finders::Users::OembedApi do
end
context 'when author_url not present but author_name' do
let(:body) { File.read(fixtures.join('200_author_name.json')) }
let(:fixture) { fixtures.join('200_author_name.json') }
it 'returns the expected array of users' do
users = finder.aggressive
@@ -59,6 +61,12 @@ describe WPScan::Finders::Users::OembedApi do
expect(user.interesting_entries).to eql ['http://wp.lab/wp-json/oembed/1.0/embed?url=http://wp.lab/&format=json']
end
end
context 'when body is an array' do
let(:fixture) { fixtures.join('array.json') }
its(:aggressive) { should eql([]) }
end
end
end
end

View File

@@ -87,6 +87,8 @@ describe WPScan::Finders::Users::WpJsonApi do
describe '#api_url' do
let(:fixtures) { super().join('api_url') }
before { allow(target).to receive(:sub_dir).and_return(false) }
context 'when url in the homepage' do
{
in_scope: 'https://wp.lab/wp-json/wp/v2/users/',
@@ -100,7 +102,7 @@ describe WPScan::Finders::Users::WpJsonApi do
end
context 'when subdir' do
before { allow(target).to receive(:subdir).and_return('cms') }
before { allow(target).to receive(:sub_dir).and_return('cms') }
{
in_scope_subdir: 'https://wp.lab/cms/wp-json/wp/v2/users/',

View File

@@ -10,10 +10,9 @@ describe WPScan::Model::Theme do
before { expect(blog).to receive(:content_dir).at_least(1).and_return('wp-content') }
describe '#new' do
before do
stub_request(:get, /.*\.css\z/)
.to_return(body: File.read(fixtures.join('style.css')))
end
before { stub_request(:get, /.*\.css\z/).to_return(body: File.read(fixture)) }
let(:fixture) { fixtures.join('style.css') }
its(:url) { should eql 'http://wp.lab/wp-content/themes/spec/' }
its(:style_url) { should eql 'http://wp.lab/wp-content/themes/spec/style.css' }
@@ -34,6 +33,14 @@ describe WPScan::Model::Theme do
its(:style_url) { should eql opts[:style_url] }
end
context 'when some new lines are stripped' do
let(:fixture) { fixtures.join('stripped_new_lines.css') }
its(:style_name) { should eql 'Divi' }
its(:style_uri) { should eql 'http://www.elegantthemes.com/gallery/divi/' }
its(:license_uri) { should eql 'http://www.gnu.org/licenses/gpl-2.0.html' }
end
end
describe '#version' do

View File

@@ -46,7 +46,7 @@ describe WPScan::Model::WpItem do
end
it 'encodes the path' do
expect(wp_item.url('#t#')).to eql "#{item_url}%23t%23"
expect(wp_item.url('#t#')).to eql "#{item_url}#t%23"
expect(wp_item.url('t .txt')).to eql "#{item_url}t%20.txt"
end
end

View File

@@ -1,4 +1,4 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore
!.gitignore

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,94 @@
msgid ""
msgstr ""
"Project-Id-Version: Woo Pelecard v1.0.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-07-07 07:09+0200\n"
"PO-Revision-Date: 2014-07-07 07:09+0200\n"
"Last-Translator: Tzvi Rabinovitch <tzvi.ra@gmail.com>\n"
"Language-Team: \n"
"Language: he_IL\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Poedit 1.5.4\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;"
"_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2\n"
"X-Poedit-Basepath: .\n"
"X-Textdomain-Support: yes\n"
"X-Poedit-SearchPath-0: ..\n"
#: ../10bit-easycard-paybuttons-options.php:18
msgid "Settings saved."
msgstr "שמרתי את ההגדרות."
#: ../10bit-easycard-paybuttons-options.php:23
msgid "10Bit EasyCard PayButtons Settings"
msgstr "כפתורי תשלום איזיקארד"
#: ../10bit-easycard-paybuttons-options.php:37
msgid "Client ID"
msgstr "מזהה לקוח"
# @ TenBit_woo_pelecard
#: ../10bit-easycard-paybuttons-options.php:45
msgid "Password"
msgstr "סיסמה"
#: ../10bit-easycard-paybuttons-options.php:53
msgid "Maximum Payments"
msgstr "מספר תשלמים מקסימלי"
#: ../10bit-easycard-paybuttons-options.php:64
msgid "Save Changes"
msgstr "שמור שינויים"
#: ../10bit-easycard-paybuttons-options.php:70
msgid "Usage :"
msgstr "שימוש"
#: ../10bit-easycard-paybuttons-options.php:72
msgid "Add the folloing short code inside a post or a page :"
msgstr "הוסיפו את השורטקוד הבא לדף או לעמוד באתר"
#: ../10bit-easycard-paybuttons-options.php:76
msgid "value : The amount to pay"
msgstr "value : הסכום לתשלום"
#: ../10bit-easycard-paybuttons-options.php:78
msgid "item_name : the name of the sold item"
msgstr "item_name : שם המוצר למכירה"
#: ../10bit-easycard-paybuttons-options.php:80
msgid "button_class : CSS class for styling"
msgstr "button_class : קלאס CSS לעיצוב"
#: ../10bit-easycard-paybuttons-options.php:82
msgid "button_text : Text to show on the button"
msgstr "button_text : הטקסט שיופיע על הכפתור"
#: ../10bit-paybuttons-easycard.php:29
msgid "EasyCard Pay Buttons"
msgstr "כפתורי תשלום איזיקארד"
# @ TenBit_woo_pelecard
#~ msgid "License Key"
#~ msgstr "מפתח"
#~ msgid "Valid"
#~ msgstr "תקין"
#~ msgid "Invalid"
#~ msgstr "לא תקין"
#, fuzzy
#~ msgid "Leave blank for not sending a copy"
#~ msgstr "השאר ריק במידה ואינך מעוניים בהעתק"
#, fuzzy
#~ msgid "10Bit iCount Settings"
#~ msgstr "הגדרות icount"
#~ msgid "Easycard"
#~ msgstr "איזיקארד"

View File

@@ -0,0 +1,132 @@
msgid ""
msgstr ""
"Project-Id-Version: Woo Pelecard v1.0.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-07-09 01:31+0200\n"
"PO-Revision-Date: 2014-07-09 01:32+0200\n"
"Last-Translator: Tzvi Rabinovitch <tzvi.ra@gmail.com>\n"
"Language-Team: \n"
"Language: he_IL\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Poedit 1.5.4\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;"
"_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2\n"
"X-Poedit-Basepath: .\n"
"X-Textdomain-Support: yes\n"
"X-Poedit-SearchPath-0: ..\n"
# @ TenBit_woo_pelecard
#: ../10bit-paybuttons-pelecard.php:28
msgid "pelecard Pay Buttons"
msgstr "כפתורי תשלום פלאכארד"
#: ../10bit-pelecard-paybuttons-options.php:68
msgid "Settings saved."
msgstr "שמרתי את ההגדרות."
#: ../10bit-pelecard-paybuttons-options.php:73
msgid "10Bit pelecard PayButtons Settings"
msgstr "כפתורי תשלום פלאכארד"
# @ TenBit_woo_pelecard
#: ../10bit-pelecard-paybuttons-options.php:87
msgid "Terminal Number"
msgstr "מספר מסוף סליקה"
# @ TenBit_woo_pelecard
#: ../10bit-pelecard-paybuttons-options.php:95
msgid "Username"
msgstr "שם משתמש"
# @ TenBit_woo_pelecard
#: ../10bit-pelecard-paybuttons-options.php:103
msgid "Password"
msgstr "סיסמה"
#: ../10bit-pelecard-paybuttons-options.php:111
msgid "Maximum Payments"
msgstr "מספר תשלמים מקסימלי"
#: ../10bit-pelecard-paybuttons-options.php:119
msgid "Currency"
msgstr "מטבע"
#: ../10bit-pelecard-paybuttons-options.php:123
msgid "ILS"
msgstr "ש\"ח"
#: ../10bit-pelecard-paybuttons-options.php:124
msgid "USD"
msgstr "דולר"
#: ../10bit-pelecard-paybuttons-options.php:130
msgid "Success ( thank you ) page URL"
msgstr "כתובת הצלחה ( דף תודה )"
#: ../10bit-pelecard-paybuttons-options.php:138
msgid "Error page URL"
msgstr "כתובת כשלון"
#: ../10bit-pelecard-paybuttons-options.php:146
msgid "Path to custom logo"
msgstr "קישור ללוגו "
#: ../10bit-pelecard-paybuttons-options.php:154
msgid "Path to small custom logo"
msgstr "קישור ללוגו קטן "
#: ../10bit-pelecard-paybuttons-options.php:162
msgid "Hide PCI DSS logo"
msgstr "הסתר את הלוגו של PCI DSS"
#: ../10bit-pelecard-paybuttons-options.php:170
msgid "Hide Pelecard logo"
msgstr "הסתר את לוגו פלאכארד"
#: ../10bit-pelecard-paybuttons-options.php:178
msgid "Path To custom Style sheet(CSS)"
msgstr "כתובת כשלון"
#: ../10bit-pelecard-paybuttons-options.php:183
msgid "must be a secured URL ( HTTPS )"
msgstr "חייב להיות מכתובת מאובטחת (HTTPS )"
#: ../10bit-pelecard-paybuttons-options.php:189
msgid "Background color"
msgstr "צבע רקע"
#: ../10bit-pelecard-paybuttons-options.php:195
msgid "Use hexadecimal color without the #"
msgstr "ערך הקסדצימלי ללא #"
#: ../10bit-pelecard-paybuttons-options.php:217
msgid "Save Changes"
msgstr "שמור שינויים"
#: ../10bit-pelecard-paybuttons-options.php:223
msgid "Usage :"
msgstr "שימוש"
#: ../10bit-pelecard-paybuttons-options.php:225
msgid "Add the following short code inside a post or a page :"
msgstr "הוסיפו את השורטקוד הבא לדף או לעמוד באתר"
#: ../10bit-pelecard-paybuttons-options.php:229
msgid "value : The amount to pay"
msgstr "value : הסכום לתשלום"
#: ../10bit-pelecard-paybuttons-options.php:231
msgid "item_name : the name of the sold item"
msgstr "item_name : שם המוצר למכירה"
#: ../10bit-pelecard-paybuttons-options.php:233
msgid "button_class : CSS class for styling"
msgstr "button_class : קלאס CSS לעיצוב"
#: ../10bit-pelecard-paybuttons-options.php:235
msgid "button_text : Text to show on the button"
msgstr "button_text : הטקסט שיופיע על הכפתור"

View File

@@ -0,0 +1,24 @@
# Italian translation for ab-human-time
# Copyright (C) 2014 AB Human Time
# This file is distributed under the same license as the AB Human Time package.
msgid ""
msgstr ""
"Project-Id-Version: AB Human Time 0.1\n"
"POT-Creation-Date: 2014-02-26 20:13+0100\n"
"PO-Revision-Date: 2014-02-26 21:25+0100\n"
"Last-Translator: endrix.develop <endrix.develop@gmail.com>\n"
"Language-Team: <endrix.develop@gmail.com>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.6.4\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Language: it_IT\n"
#: ../ab-human-time.php:21
msgid "Published "
msgstr "Pubblicato "
#: ../ab-human-time.php:23
msgid " ago"
msgstr " fa"

View File

@@ -0,0 +1,49 @@
msgid ""
msgstr ""
"Project-Id-Version: xq-xe-xt-xy 1.0\n"
"POT-Creation-Date: 2018-07-11 09:44+0300\n"
"PO-Revision-Date: 2018-07-11 09:44+0300\n"
"Last-Translator: \n"
"Language-Team: Marko Maksym\n"
"Language: uk_UA\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.0.6\n"
"X-Poedit-Basepath: ../includes\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Poedit-KeywordsList: __;_e\n"
"X-Poedit-SearchPath-0: .\n"
#: admin/class-admin-main.php:66
msgid "Title of the page"
msgstr ""
#: admin/class-admin-main.php:66
msgid "Link Name"
msgstr ""
#: admin/class-admin-main.php:69
msgid "Submenu title"
msgstr ""
#: admin/class-admin-main.php:69
msgid "Submenu item"
msgstr ""
#: admin/templates/index.php:8
msgid "Settings Page"
msgstr ""
#: admin/templates/main_module_menu.php:10
msgid "Main page"
msgstr ""
#: admin/templates/main_module_menu.php:13 admin/templates/page1.php:8
msgid "Page 1"
msgstr ""
#: admin/templates/main_module_menu.php:16 admin/templates/page2.php:8
msgid "Page 2"
msgstr ""

View File

@@ -0,0 +1,112 @@
# Copyright (C) 2016 Kailey Lampert
# This file is distributed under the same license as the PACKAGE package.
# Kailey Lampert <trepmal@gmail.com>, 2016.
msgid ""
msgstr ""
"Project-Id-Version: 1.7\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-09-08 17:48-0700\n"
"PO-Revision-Date: 2016-09-08 17:48-0700\n"
"Last-Translator: Kailey Lampert <trepmal@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: active-plugins.php:62
msgid "Acitve Plugins is for multisite use only."
msgstr ""
#: active-plugins.php:72 active-plugins.php:83
msgid "Active Plugins Across Network"
msgstr ""
#: active-plugins.php:72
msgid "Active Plugins"
msgstr ""
#: active-plugins.php:86
#, php-format
msgid "<a href=\"%s\">Network-Activated Plugins</a>"
msgstr ""
#: active-plugins.php:87
#, php-format
msgid "<a href=\"%s\">MU Plugins</a>"
msgstr ""
#: active-plugins.php:90
#, php-format
msgid "List does not include: %s"
msgstr ""
#: active-plugins.php:146
msgid ""
"Totals <span class=\"description\">each active plugin and how many users</"
"span>"
msgstr ""
#: active-plugins.php:176 active-plugins.php:213
#, php-format
msgid "v%s"
msgstr ""
#: active-plugins.php:180 active-plugins.php:214
#, php-format
msgid "%1$s %2$s"
msgstr ""
#: active-plugins.php:182
#, php-format
msgid "%s (Uninstalled)"
msgstr ""
#: active-plugins.php:187
#, php-format
msgid " (tagged: %s)"
msgstr ""
#: active-plugins.php:197
msgid "Select all"
msgstr ""
#: active-plugins.php:198
msgid "Deselect all"
msgstr ""
#: active-plugins.php:199
msgid "Toggle"
msgstr ""
#: active-plugins.php:209
msgid "Plugins with zero (0) users:"
msgstr ""
#: active-plugins.php:217
msgid "none"
msgstr ""
#: active-plugins.php:224
msgid "Show sites with no active plugins"
msgstr ""
#: active-plugins.php:235
msgid "Edit"
msgstr ""
#: active-plugins.php:236
msgid "View"
msgstr ""
#: active-plugins.php:237
msgid "Dashboard"
msgstr ""
#: active-plugins.php:238
msgid "Plugins"
msgstr ""
#: active-plugins.php:249
msgid "(network-activated)"
msgstr ""

View File

@@ -0,0 +1,619 @@
# Copyright (C) 2019 RedNao
# This file is distributed under the same license as the Extra Product Options Builder for WooCommerce plugin.
msgid ""
msgstr ""
"Project-Id-Version: Extra Product Options Builder for WooCommerce 1.2.11\n"
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/woo-extra-products\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"POT-Creation-Date: 2019-11-02T18:08:21+00:00\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"X-Generator: WP-CLI 2.3.0\n"
"X-Domain: rednaowooextraproduct\n"
#. Plugin Name of the plugin
msgid "Extra Product Options Builder for WooCommerce"
msgstr ""
#. Plugin URI of the plugin
msgid "http://smartforms.rednao.com/getit"
msgstr ""
#. Description of the plugin
msgid "Additional product fields for woocommerce"
msgstr ""
#. Author of the plugin
msgid "RedNao"
msgstr ""
#. Author URI of the plugin
msgid "http://rednao.com"
msgstr ""
#: jstranslations/InternalShared.php:2
msgid "Jan"
msgstr ""
#: jstranslations/InternalShared.php:3
msgid "Feb"
msgstr ""
#: jstranslations/InternalShared.php:4
msgid "Mar"
msgstr ""
#: jstranslations/InternalShared.php:5
msgid "Apr"
msgstr ""
#: jstranslations/InternalShared.php:6
msgid "May"
msgstr ""
#: jstranslations/InternalShared.php:7
msgid "Jun"
msgstr ""
#: jstranslations/InternalShared.php:8
msgid "Jul"
msgstr ""
#: jstranslations/InternalShared.php:9
msgid "Aug"
msgstr ""
#: jstranslations/InternalShared.php:10
msgid "Sep"
msgstr ""
#: jstranslations/InternalShared.php:11
msgid "Oct"
msgstr ""
#: jstranslations/InternalShared.php:12
msgid "Nov"
msgstr ""
#: jstranslations/InternalShared.php:13
msgid "Dec"
msgstr ""
#: jstranslations/InternalShared.php:14
msgid "January"
msgstr ""
#: jstranslations/InternalShared.php:15
msgid "February"
msgstr ""
#: jstranslations/InternalShared.php:16
msgid "March"
msgstr ""
#: jstranslations/InternalShared.php:17
msgid "April"
msgstr ""
#: jstranslations/InternalShared.php:18
msgid "June"
msgstr ""
#: jstranslations/InternalShared.php:19
msgid "July"
msgstr ""
#: jstranslations/InternalShared.php:20
msgid "August"
msgstr ""
#: jstranslations/InternalShared.php:21
msgid "September"
msgstr ""
#: jstranslations/InternalShared.php:22
msgid "October"
msgstr ""
#: jstranslations/InternalShared.php:23
msgid "November"
msgstr ""
#: jstranslations/InternalShared.php:24
msgid "December"
msgstr ""
#: jstranslations/InternalShared.php:25
msgid "Su"
msgstr ""
#: jstranslations/InternalShared.php:26
msgid "Mo"
msgstr ""
#: jstranslations/InternalShared.php:27
msgid "Tu"
msgstr ""
#: jstranslations/InternalShared.php:28
msgid "We"
msgstr ""
#: jstranslations/InternalShared.php:29
msgid "Th"
msgstr ""
#: jstranslations/InternalShared.php:30
msgid "Fr"
msgstr ""
#: jstranslations/InternalShared.php:31
msgid "Sa"
msgstr ""
#: jstranslations/InternalShared.php:32
msgid "Sun"
msgstr ""
#: jstranslations/InternalShared.php:33
msgid "Mon"
msgstr ""
#: jstranslations/InternalShared.php:34
msgid "Tue"
msgstr ""
#: jstranslations/InternalShared.php:35
msgid "Wed"
msgstr ""
#: jstranslations/InternalShared.php:36
msgid "Thu"
msgstr ""
#: jstranslations/InternalShared.php:37
msgid "Fri"
msgstr ""
#: jstranslations/InternalShared.php:38
msgid "Sat"
msgstr ""
#: jstranslations/InternalShared.php:39
#: jstranslations/ProductFieldBuilder.php:97
msgid "Sunday"
msgstr ""
#: jstranslations/InternalShared.php:40
#: jstranslations/ProductFieldBuilder.php:98
msgid "Monday"
msgstr ""
#: jstranslations/InternalShared.php:41
#: jstranslations/ProductFieldBuilder.php:99
msgid "Tuesday"
msgstr ""
#: jstranslations/InternalShared.php:42
#: jstranslations/ProductFieldBuilder.php:100
msgid "Wednesday"
msgstr ""
#: jstranslations/InternalShared.php:43
#: jstranslations/ProductFieldBuilder.php:101
msgid "Thursday"
msgstr ""
#: jstranslations/InternalShared.php:44
#: jstranslations/ProductFieldBuilder.php:102
msgid "Friday"
msgstr ""
#: jstranslations/InternalShared.php:45
#: jstranslations/ProductFieldBuilder.php:103
msgid "Saturday"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:2
msgid "Please select a field"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:3
msgid "Cancel"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:4
msgid "Import"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:5
msgid "Export"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:6
#: ProductFieldBuilder.php:1
msgid "Label"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:7
msgid "Image URL"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:8
msgid "Price"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:9
msgid "Sale"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:10
msgid "Price Type"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:11
msgid "Fixed amount"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:12
msgid "% of original price"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:13
msgid "% of original price + options"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:14
msgid "Settings"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:15
msgid "Conditions"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:16
msgid "Enable Show/Hide Conditions"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:17
msgid "Show"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:18
msgid "Hide"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:19
msgid "this field if"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:20
msgid "Select a field"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:21
msgid "Fields"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:22
msgid "AND"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:23
msgid "or"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:24
msgid "Add new group"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:25
msgid "Select one"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:26
msgid "Equal to"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:27
msgid "Not Equal to"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:28
msgid "Is Empty"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:29
msgid "Is Not Empty"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:30
msgid "Contains"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:31
msgid "Not Contains"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:32
msgid "Default text"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:33
#: ProductFieldBuilder.php:1
msgid "Placeholder"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:34
#: ProductFieldBuilder.php:1
msgid "Required"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:35
#: ProductFieldBuilder.php:1
msgid "Show quantity selector"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:36
#: ProductFieldBuilder.php:1
msgid "Quantity Position"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:37
msgid "Left"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:38
msgid "Right"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:39
msgid "Top"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:40
msgid "Bottom"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:41
#: ProductFieldBuilder.php:1
msgid "Default value"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:42
#: ProductFieldBuilder.php:1
msgid "Quantity Label"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:43
#: ProductFieldBuilder.php:1
msgid "0 = No Maximum"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:44
#: ProductFieldBuilder.php:1
msgid "Maximum Value"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:45
#: ProductFieldBuilder.php:1
msgid "0 = No Minimum"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:46
#: ProductFieldBuilder.php:1
msgid "Minimum Value"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:47
msgid "Price type"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:48
msgid "None (don't use this field to calculate price)"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:49
msgid "Fixed Amount"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:50
#: ProductFieldBuilder.php:1
msgid "Quantity"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:51
msgid "Current value"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:52
msgid "Percent of the original price"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:53
msgid "Percent of the original price + options"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:54
msgid "Price per word"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:55
msgid "Price per char"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:56
msgid "Sale Price (Empty = No Sale)"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:57
msgid "Percentage"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:58
msgid "Sale Percentage"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:59
msgid "Free chars"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:60
msgid "Ignore Spaces"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:61
msgid "Free words"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:62
#: ProductFieldBuilder.php:1
msgid "Hide price"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:63
#: ProductFieldBuilder.php:1
msgid "General"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:64
#: ProductFieldBuilder.php:1
msgid "Pricing"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:65
msgid "Text"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:66
#: ProductFieldBuilder.php:1
msgid "Options"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:67
msgid "Phone: (999)99-999-999"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:68
msgid "Credit Card: 9999 9999 9999 9999"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:69
msgid "Custom"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:70
msgid "9=Numbers, a=letters, *=Numbers or letters"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:71
msgid "Custom Mask"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:72
msgid "Mask Char"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:73
msgid "Image Width"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:74
msgid "Image Height"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:75
msgid "Allow Multiple"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:76
msgid "Horizontal"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:77
msgid "Vertical"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:78
#: ProductFieldBuilder.php:1
msgid "Date Format"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:79
msgid "Price Per Day"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:80
msgid "Label (Start Date)"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:81
msgid "Placeholder (Start Date)"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:82
msgid "Default Date (Start Date)"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:83
msgid "This property support two type of fields"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:84
msgid "A number, representing the number of dates from now e.g. 0 for today 1 for tomorrow"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:85
msgid "2 for the day after tomorrow and so on. It supports negative numbers as well"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:86
msgid "An specific date in the format of YYYY/MM/DD e.g. 2000/02/01 for February first of 2000"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:87
msgid "Start Date"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:88
msgid "Label (End Date)"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:89
msgid "End Date"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:90
msgid "Title"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:91
msgid "Style"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:92
msgid "Dashed"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:93
msgid "Solid"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:94
msgid "Color"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:95
msgid "Default Date"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:96
msgid "Week Start On"
msgstr ""
#: jstranslations/ProductFieldBuilder.php:104
msgid "Default Color"
msgstr ""

View File

@@ -0,0 +1,428 @@
# Copyright (C) 2012
# This file is distributed under the same license as the package.
msgid ""
msgstr ""
"Project-Id-Version: Advanced Category Column\n"
"Report-Msgid-Bugs-To: http://wordpress.org/tag/advanced-category-column\n"
"POT-Creation-Date: 2016-02-17 11:35+0200\n"
"PO-Revision-Date: 2016-02-17 11:36+0200\n"
"Last-Translator: Stefan Crämer <translate@atelier-fuenf.de>\n"
"Language-Team: Waldemar Stoffel <stoffel@atelier-fuenf.de>\n"
"Language: es_ES\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Generator: Poedit 1.8.1\n"
"X-Poedit-Basepath: ..\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;"
"esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;_n_noop:1,2;"
"_nx_noop:3c,1,2;__ngettext_noop:1,2\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Poedit-SearchPath-0: .\n"
#: advanced-cc.php:112
msgid "FAQ"
msgstr "FAQ"
#: advanced-cc.php:113
msgid "Donate"
msgstr "Donar"
#: advanced-cc.php:123 class-lib/A5_OptionPageClass.php:31
#: class-lib/ACC_AdminClass.php:35
msgid "Settings"
msgstr "Ajustes"
#: class-lib/A5_ImageClass.php:48
msgid "Permalink to"
msgstr "enlace permanente a"
#: class-lib/A5_OptionPageClass.php:145
msgid "Click to toggle"
msgstr ""
#: class-lib/A5_OptionPageClass.php:382
msgid "Not set"
msgstr ""
#: class-lib/A5_WidgetClass.php:37
msgid "Homepage"
msgstr "Página de Inicio"
#: class-lib/A5_WidgetClass.php:38
msgid "Frontpage (e.g. a static page as homepage)"
msgstr ""
"Página Inicial (por ejemplo, una página estática como página de inicio)"
#: class-lib/A5_WidgetClass.php:39
msgid "&#34;Page&#34; pages"
msgstr "&#34;Pagína&#34; páginas"
#: class-lib/A5_WidgetClass.php:40
msgid "Category pages"
msgstr "Categoría de páginas"
#: class-lib/A5_WidgetClass.php:41
msgid "Single post pages"
msgstr "Páginas de post simples"
#: class-lib/A5_WidgetClass.php:42
msgid "Archive pages"
msgstr "Páginas de Archivo"
#: class-lib/A5_WidgetClass.php:43
#, fuzzy
msgid "Post type archives"
msgstr "Páginas de post simples"
#: class-lib/A5_WidgetClass.php:44
msgid "Tag pages"
msgstr "Páginas de Etiquetas"
#: class-lib/A5_WidgetClass.php:45
msgid "Attachments"
msgstr "Adjuntos"
#: class-lib/A5_WidgetClass.php:46
msgid "Custom Taxonomy pages (only available, if having a plugin)"
msgstr ""
"Páginas de Taxonomía Personalizada (sólo está disponible si tiene un plugin)"
#: class-lib/A5_WidgetClass.php:47
msgid "Author pages"
msgstr "Páginas del autor"
#: class-lib/A5_WidgetClass.php:48
msgid "Search Results"
msgstr "Buscar Resultados"
#: class-lib/A5_WidgetClass.php:49
msgid "&#34;Not Found&#34;"
msgstr "&#34;No Encontrado&#34;"
#: class-lib/A5_WidgetClass.php:52
#, fuzzy
msgid "Login Page (only available, if having a plugin)"
msgstr ""
"Páginas de Taxonomía Personalizada (sólo está disponible si tiene un plugin)"
#: class-lib/A5_WidgetClass.php:54
msgid "Check all"
msgstr "Seleccionar todo"
#: class-lib/A5_WidgetClass.php:56
msgid ""
"Check, where you want to show the widget. By default, it is showing on the "
"homepage and the category pages:"
msgstr ""
"Seleccione, dónde desea mostrar el widget. Por defecto, se muestra en la "
"página principal y en las páginas de la categoría:"
#: class-lib/A5_WidgetClass.php:92
msgid "Under image"
msgstr ""
#: class-lib/A5_WidgetClass.php:92
msgid "Left of image"
msgstr ""
#: class-lib/A5_WidgetClass.php:92
msgid "Right of image"
msgstr ""
#: class-lib/A5_WidgetClass.php:92
msgid "Don&#39;t show excerpt"
msgstr ""
#: class-lib/A5_WidgetClass.php:94
msgid ""
"Choose, whether or not to display the excerpt and whether it comes under the "
"thumbnail or next to it."
msgstr ""
#: class-lib/A5_WidgetClass.php:104
msgid "Weight of the Post Title:"
msgstr "Peso del título del Post:"
#: class-lib/A5_WidgetClass.php:108
msgid "Left"
msgstr ""
#: class-lib/A5_WidgetClass.php:108
msgid "Right"
msgstr ""
#: class-lib/A5_WidgetClass.php:108
msgid "Center"
msgstr ""
#: class-lib/A5_WidgetClass.php:108
msgid "Justify"
msgstr ""
#: class-lib/A5_WidgetClass.php:110
msgid "How do you want to align the Post Title?"
msgstr ""
#: class-lib/A5_WidgetClass.php:121
msgid ""
"Check to have an additional &#39;read more&#39; link at the end of the "
"excerpt."
msgstr ""
#: class-lib/A5_WidgetClass.php:122
#, php-format
msgid ""
"Write here some text for the &#39;read more&#39; link. By default, it is %s:"
msgstr ""
#: class-lib/A5_WidgetClass.php:123
msgid ""
"If you want to style the &#39;read more&#39; link, you can enter a class "
"here."
msgstr ""
#: class-lib/ACC_AdminClass.php:63
msgid ""
"http://wasistlos.waldemarstoffel.com/plugins-fur-wordpress/advanced-category-"
"column-plugin"
msgstr ""
"http://wasistlos.waldemarstoffel.com/plugins-fur-wordpress/advanced-category-"
"column-plugin"
#: class-lib/ACC_AdminClass.php:63
msgid "Plugin Support"
msgstr ""
#: class-lib/ACC_AdminClass.php:65
msgid ""
"Style the links of the widget. If you leave this empty, your theme will "
"style the hyperlinks."
msgstr ""
"El estilo de los enlaces del widget. Si deja el campo vacío, el tema será el "
"mismo estilo de los hipervínculos."
#: class-lib/ACC_AdminClass.php:67
msgid "Just input something like,"
msgstr "Sólo algo de entrada como,"
#: class-lib/ACC_AdminClass.php:71
msgid "to get fat, blue, underlined links."
msgstr "Los enlaces serán, azul subrayado."
#: class-lib/ACC_AdminClass.php:73
msgid ""
"You most probably have to use &#34;!important&#34; at the end of each line, "
"to make it work."
msgstr ""
"Lo más probable es usar &#34;!important&#34; al final de cada línea, para "
"hacer que funcione."
#: class-lib/ACC_AdminClass.php:86
msgid "Debug Info"
msgstr ""
#: class-lib/ACC_AdminClass.php:105
msgid "Styling of the links"
msgstr "Estilo de los enlaces"
#: class-lib/ACC_AdminClass.php:107
msgid "Link style:"
msgstr "Estílo enlace:"
#: class-lib/ACC_AdminClass.php:109
msgid "Hover style:"
msgstr "Estilo hover:"
#: class-lib/ACC_AdminClass.php:111
msgid "Widget container:"
msgstr ""
#: class-lib/ACC_AdminClass.php:111
msgid ""
"You can enter your own style for the widgets here. This will overwrite the "
"styles of your theme."
msgstr ""
#: class-lib/ACC_AdminClass.php:111
msgid ""
"If you leave this empty, you can still style every instance of the widget "
"individually."
msgstr ""
#: class-lib/ACC_AdminClass.php:113
#, fuzzy
msgid "Compress Style Sheet:"
msgstr "Estílo enlace:"
#: class-lib/ACC_AdminClass.php:113
msgid "Click here to compress the style sheet."
msgstr ""
#: class-lib/ACC_AdminClass.php:115
msgid "Debug:"
msgstr ""
#: class-lib/ACC_AdminClass.php:115
msgid ""
"If you can&#39;t reach the dynamical style sheet, you&#39;ll have to display "
"the styles inline. By clicking here you can do so."
msgstr ""
#: class-lib/ACC_AdminClass.php:119
msgid "entries"
msgstr ""
#: class-lib/ACC_AdminClass.php:119
msgid "entry"
msgstr ""
#: class-lib/ACC_AdminClass.php:121
#, php-format
msgid "Empty cache (%d %s):"
msgstr ""
#: class-lib/ACC_AdminClass.php:121
msgid "You can empty the plugin&#39;s cache here, if necessary."
msgstr ""
#: class-lib/ACC_AdminClass.php:129
msgid "Just put some css code here."
msgstr "Sólo hay que poner algo de código CSS aquí."
#: class-lib/ACC_AdminClass.php:189
msgid "Cache emptied."
msgstr ""
#: class-lib/ACC_WidgetClass.php:18
msgid ""
"Configure the output and looks of the widget. Then display thumbnails and "
"excerpts of posts in your sidebars and define, on what kind of pages they "
"will show."
msgstr ""
"Configure la salida y la apariencia del widget. Entonces se mostrarán las "
"miniaturas y extractos de los mensajes en las barras laterales y se definirá "
"en qué tipo de páginas se mostrarán."
#: class-lib/ACC_WidgetClass.php:108
msgid "Title:"
msgstr "Título:"
#: class-lib/ACC_WidgetClass.php:109
#, php-format
msgid ""
"To exclude certain categories or to show just a special category, simply "
"write their ID&#39;s separated by comma (e.g. %s-5, 2, 4%s will show "
"categories 2 and 4 and will exclude category 5):"
msgstr ""
"Para excluir ciertas categorías o para mostrar sólo una categoría especial, "
"basta con escribir su ID separado por coma (por ejemplo,%s-5, 2, 4%s "
"mostrará las categorías 2 y 4, y se excluye la categoría 5):"
#: class-lib/ACC_WidgetClass.php:110
msgid "Check to show the categories in which the post is filed."
msgstr "Seleccione para mostrar las categorías en que se presenta el mensaje."
#: class-lib/ACC_WidgetClass.php:111
msgid ""
"Give some text that you want in front of the post&#39;s categtories (i.e "
"&#39;filed under&#39;:"
msgstr ""
"De algún texto que usted quiere al frente de la categoría de mensajes (ej. "
"&#39;llenado debajo&#39;:"
#: class-lib/ACC_WidgetClass.php:112
msgid "How many posts will be displayed in the sidebar:"
msgstr "Cuántos post se mostrarán en la barra lateral:"
#: class-lib/ACC_WidgetClass.php:113
msgid "Offset (how many posts are spared out in the beginning):"
msgstr "Offset (cuántos post están a salvo en el inicio):"
#: class-lib/ACC_WidgetClass.php:114
msgid "Check to have the offset only on your homepage."
msgstr ""
"Verificación para que el desplazamiento sólo sea en la página principal."
#: class-lib/ACC_WidgetClass.php:115
msgid "Width of the thumbnail (in px):"
msgstr "Ancho de las miniaturas (en px)"
#: class-lib/ACC_WidgetClass.php:116
#, php-format
msgid ""
"If wanting a border around the image, write the style here. %s would make it "
"a black border, 1px wide."
msgstr ""
#: class-lib/ACC_WidgetClass.php:118
msgid "In case there is no excerpt defined, how many sentences are displayed:"
msgstr ""
"En caso de que no haya extracto definido, como cuantas frases se muestran:"
#: class-lib/ACC_WidgetClass.php:119
msgid "Check to display words instead of sentences."
msgstr "Seleccione para mostrar palabras en lugar de oraciones."
#: class-lib/ACC_WidgetClass.php:120
msgid "Check to have each sentense in a new line."
msgstr "Seleccione para tener cada sentencia en una línea nueva."
#: class-lib/ACC_WidgetClass.php:122
msgid ""
"Check to return the excerpt unfiltered (might avoid interferences with other "
"plugins)."
msgstr ""
"Seleccione para retornar el extracto sin filtrar (puede evitar "
"interferencias con otros plugins)."
#: class-lib/ACC_WidgetClass.php:123
msgid ""
"If you want a line between the posts, this is the height in px (if not "
"wanting a line, leave emtpy):"
msgstr ""
"Si usted quiere una línea entre los posts, esta es la altura en píxeles (si "
"no quisiera una línea, deje en blanco)"
#: class-lib/ACC_WidgetClass.php:124
msgid "The color of the line (e.g. #cccccc):"
msgstr "El color de la línea (e.g. #cccccc):"
#: class-lib/ACC_WidgetClass.php:126
#, fuzzy, php-format
msgid ""
"Here you can finally style the widget. Simply type something like%sto get "
"just a gray outline and a padding of 10 px. If you leave that section empty, "
"your theme will style the widget."
msgstr ""
"Aquí usted puede finalmente ver el estilo del widget. Simplemente escriba "
"algo como%1$s%2$sborder-left: 1px dashed;%2$sborder-color: #000000;%3$s"
"%2$spara obtener una línea de puntos negro de la izquierda. Si deja la "
"sección vacía, su tema le dará estilo al widget."
#~ msgid ""
#~ "The Advanced Category Column does, what the Category Column Plugin does; "
#~ "it creates a widget, which you can drag to your sidebar and it will show "
#~ "excerpts of the posts of other categories than showed in the center-"
#~ "column. It just has more options than the the Category Column Plugin. It "
#~ "is tested with WP up to version 3.5 and it might work with versions down "
#~ "to 2.9, but will never be explicitly supported for those. The 'Advanced' "
#~ "means, that you have a couple of more options than in the 'Category "
#~ "Column Plugin'."
#~ msgstr ""
#~ "La Columna Categoría Avanzada hace, lo que hace el Plugin de Columna de "
#~ "Categoría, se crea un widget, que se puede arrastrar a la barra lateral y "
#~ "se mostrarán extractos de los mensajes de otras categorías que se "
#~ "mostraron en la columna del centro. Simplemente tiene más opciones que el "
#~ "Plugin de Columna de Categoría. Se probó con WP hasta la versión 3.5 y "
#~ "que podría funcionar con las versiones hasta la 2.9, pero nunca se probó "
#~ "explícitamente en aquellos. Los menús 'Avanzados' significan, que tiene "
#~ "un par de opciones más que el 'Plugin de Columna de Categoría'."
#~ msgid "Waldemar Stoffel"
#~ msgstr "Waldemar Stoffel"
#~ msgid "http://www.waldemarstoffel.com"
#~ msgstr "http://www.waldemarstoffel.com"

View File

@@ -0,0 +1,410 @@
msgid ""
msgstr ""
"Project-Id-Version: WooCommerce Alkubot v1.0.0\n"
"POT-Creation-Date: 2019-08-11 13:37+0300\n"
"PO-Revision-Date: 2019-10-22 09:43+0300\n"
"Language-Team: Alkubot\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.0.6\n"
"X-Poedit-Basepath: .\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Last-Translator: \n"
"Language: en_US\n"
"X-Poedit-SearchPath-0: .\n"
# Admin - layouts/menu
msgid "Terméklista"
msgstr "Product list"
msgid "Beállítások"
msgstr "Settings"
msgid "Felíratkozók"
msgstr "Subscribers"
msgid "Statisztika"
msgstr "Statistics"
msgid "Visszajelzés"
msgstr "Feedback"
msgid "Alkubot varázsló"
msgstr "Alkubot wizard"
msgid "Alkubot telepítése"
msgstr "Install Alkubot"
# Admin - product
msgid "Újragenerálás"
msgstr "Rework"
msgid "Product subtitle"
msgstr "Here you can find the product list that can be modified or you can even generate a new one."
msgid "Összes termék"
msgstr "Every product"
msgid "Termék kategóriánként"
msgstr "Categories"
msgid "Bizonyos termékeknél"
msgstr "Products"
# Admin - product/popups
msgid "Reinstall text"
msgstr "Are you sure you want to rework the settings of Alkubot? Doing so will reset your current settings!"
msgid "Switch discount type text"
msgstr "Are you sure you want to change the settings for the selected type? The modifications will be activated right away."
msgid "Mégse"
msgstr "Cancel"
# Admin - product/all.content
msgid "Product all subtitle"
msgstr "Please set the maximum percentage of discount that Alkubot can give to a visitor!"
msgid "vagyis az Alkubot"
msgstr "that is, Alkubot wont give more than"
msgid "kedvezménynél többet nem ad egy látogatónak"
msgstr "discount to a visitor"
msgid "Alkudozok gomb megjelenitése a termék oldalon"
msgstr "Show “Get a Deal” button on the product page"
msgid "Hint text: all product"
msgstr "The visitor can instantly start negotiating for a deal by pushing the \"Get a Deal\" button. This way, he doesn't have to wait for the timed Alkubot chat window to pop-up."
msgid "Engedélyezve"
msgstr "Enabled"
msgid "Kikapcsolva"
msgstr "Disabled"
# Admin - product/category.content
msgid "Összes"
msgstr "All"
msgid "Alkudozom gomb megjelenése:"
msgstr "“Get a Deal” button"
msgid "Be"
msgstr "On"
msgid "Ki"
msgstr "Off"
# Admin - product/categories
msgid "No category found"
msgstr "No category found!"
# Admin - product/product.content
msgid "Termékek rejtése"
msgstr "Hide products"
msgid "Termékek megjelenítése"
msgstr "Show products"
# Admin - product/products
msgid "No product found"
msgstr "No product found!"
# Admin - product/search
msgid "Search placeholder"
msgstr "Search for a product"
# Admin - settings
msgid "Alkubot időzítése"
msgstr "Alkubot timing"
msgid "Itt beállíthatod, hogy a bot, miként reagáljon, bizonyos interakciókra."
msgstr "Here you can set how Alkubot should react to certain actions"
msgid "Oldal elhagyásakor"
msgstr "While leaving the product page"
msgid "Bizonyos oldalon töltött idő után"
msgstr "After a certain time that the visitor spends on the product page"
msgid "Kérjük adja meg hány mp után aktiválódjon"
msgstr "The time after Alkubot shows up"
msgid "mp"
msgstr "sec"
msgid "Oldal görgetésekor"
msgstr "While scrolling the product page"
msgid "Email beállítások"
msgstr "Email settings"
msgid "Sikeres alku után email cím elkérése"
msgstr "Should Alkubot ask for an email after an accepted deal?"
msgid "Bot aktiválása"
msgstr "Activate Alkubot"
msgid "Modosít"
msgstr "Modify"
msgid "Settings popup title"
msgstr "Saved!"
msgid "Settings popup text"
msgstr "Your settings have been successfully modified!"
msgid "Hint text: settings leave"
msgstr "Alkubot pops up when the visitor tries to leave the page."
msgid "Hint text: settings time"
msgstr "Alkubot pops up after a certain number of seconds."
msgid "Hint text: settings scroll"
msgstr "Alkubot pops up when the visitors scroll until 3/4 of the site."
msgid "Hint text: settings email"
msgstr "After an accepted deal, the visitor has to give his email address in order to get his discount."
# Admin - settings/chat.position
msgid "Hol helyezkedjen el?"
msgstr "Where should Alkubot show up on your site?"
msgid "Bal oldalt"
msgstr "Left side"
msgid "Középen"
msgstr "Middle"
msgid "Jobb oldalt"
msgstr "Right side"
# Admin - statistics
msgid "Legenerált kuponkodok"
msgstr "Coupons generated"
msgid "Mutass mindent"
msgstr "Show all"
# Admin - statistics/infobox
msgid "db"
msgstr "pc"
msgid "Ft"
msgstr "HUF "
msgid "Sikeres alku száma"
msgstr "Successful <br> Deals"
msgid "Megadott email cimek száma"
msgstr "Emails <br> Collected"
msgid "Eddigi bevétel"
msgstr "Proceeds <br> so far"
# Admin - statistics/coupons
msgid "Dátum"
msgstr "Date"
msgid "Kupon"
msgstr "Coupon"
msgid "Felhasználó"
msgstr "User"
msgid "Felhasználták már?"
msgstr "Used up?"
msgid "Igen"
msgstr "Yes"
msgid "Nem"
msgstr "No"
msgid "Részletek"
msgstr "Details"
msgid "Még nincs legenerált kupon!"
msgstr "No generated voucher yet!"
# Admin - statistics/details
msgid "kupon részletei"
msgstr "coupon details"
msgid "Vissza a statisztikákhoz"
msgstr "Back to statistics"
msgid "Termék neve"
msgstr "Product name"
msgid "Kupon generálásának időpontja"
msgstr "Coupon generation date"
msgid "Felhasználva"
msgstr "Used"
msgid "még nincs"
msgstr "not yet"
msgid "Termékre beállitott maximális kedvezmény"
msgstr "Maximum discount set for the product"
msgid "Kialkudott kedvezmény"
msgstr "Negotiated discount"
msgid "vendég"
msgstr "guest"
# Admin - subscribers
msgid "Összesen"
msgstr "Total"
msgid "Email cimek exportálása"
msgstr "Exports Emails"
msgid "Törlés"
msgstr "Delete"
msgid "Még nincs egy feliratkozó sem!"
msgstr "No subscriber yet!"
msgid "Delete subscriber popup title"
msgstr "Delete subscriber"
msgid "Delete subscriber popup text"
msgstr "Are you sure you want to delete this email address?"
msgid "Igen törlöm"
msgstr "Yes, I am sure!"
# Admin - feedback
msgid "Név"
msgstr "Name"
msgid "Email"
msgstr "Email"
msgid "Visszajelzés tipusa"
msgstr "Feedback type"
msgid "Válassz a listából"
msgstr "Pick one"
msgid "Értékelés"
msgstr "Rate us"
msgid "Üzenet"
msgstr "Message"
msgid "Küldés"
msgstr "Send"
msgid "Required text"
msgstr "Please fill out this field."
msgid "Feedback popup title"
msgstr "Thank you for your feedback!"
msgid "Feedback popup text"
msgstr "Your opinion is important to us. We aim to reply to your feedback as soon as possible."
msgid "Close window"
msgstr "Close window"
msgid "Hibajelentés"
msgstr "Bug report"
msgid "Észrevétel"
msgstr "Feedback"
msgid "Not valid email text"
msgstr "Please enter a valid email address"
msgid "kötelező"
msgstr "required"
msgid "Feedback subtitle"
msgstr "Just fill out the below form in case you have feedback or need help regarding Alkubot"
# Admin - wizard
msgid "Varázsló"
msgstr "Setup Wizard"
msgid "Wizard subtitle"
msgstr "By answering a few simple questions you can setup Alkubot within minutes."
# Admin - wizard/lastStepComment
msgid "Wizard last step comment text"
msgstr "You can fine-tune Alkubot under Settings after finishing this setup wizard."
# Admin - wizard/step1
msgid "Kérlek válaszd ki, milyen szinten akarod beállitani a botot"
msgstr "Please choose the level which you want to use Alkubot for."
msgid "Tovább"
msgstr "Next"
# Admin - wizard/step2.all
msgid "Vissza"
msgstr "Back"
# Admin - wizard/step2.categories
msgid "Kérlek add meg, mely kategoriákra legyen engedélyezve az alkubot."
msgstr "Please pick the categories that Alkubot should be applied to!"
# Admin - wizard/step3.categories
msgid "Wizard categories step 3 subtitle"
msgstr "Here you can set the maximum percentage of discount that Alkubot can give to a visitor for each category."
msgid "Nem választottál ki egy kategoriát sem."
msgstr "No category have been chosen."
# Admin - wizard/step3.products
msgid "Wizard products step 3 subtitle"
msgstr "Here you can set the maximum percentage of discount that Alkubot can give to a visitor for each product."
msgid "Nem választottál ki terméket."
msgstr "No product have been chosen."
# Admin - wizard/steps.header
msgid "Step"
msgstr "Step"
# Frontend
msgid "Elfogadom"
msgstr "Accept"
msgid "Elutasítom"
msgstr "Decline"
msgid "Normál ár"
msgstr "Normal price"
msgid "Írd ide az üzeneted"
msgstr "Write your message here"
msgid "Alkudozok"
msgstr "Bargain"
msgid "Gratulálunk!"
msgstr "Congratulations!"
msgid "Sikeres alkut kötöttél"
msgstr "You made a deal"
msgid "Az Alkubot lezárta a chatet"
msgstr "Chat was closed by Alkubot"
msgid "Powered by url"
msgstr "https://www.alkubot.com?utm_medium=referal&utm_source=bot&utm_campaign=powered+by"
msgid "Sokkalod az arat?"
msgstr "Too pricey?"
msgid "Alkudozzunk rola"
msgstr "Let's make a deal!"
msgid "Alku inditasa most"
msgstr "Negotiate the price"

View File

@@ -0,0 +1,53 @@
# Copyright (C) 2013 Allow Javascript in Text Widgets
# This file is distributed under the same license as the Allow Javascript in Text Widgets package.
msgid ""
msgstr ""
"Project-Id-Version: Allow Javascript in Text Widgets 0.3\n"
"Report-Msgid-Bugs-To: http://wordpress.org/tag/allow-javascript-in-text-"
"widgets\n"
"POT-Creation-Date: 2013-12-17 09:48:40+00:00\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"PO-Revision-Date: 2013-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
#: allow-javascript-in-text-widgets.php:20
msgid "Arbitrary text or HTML"
msgstr ""
#: allow-javascript-in-text-widgets.php:22
msgid "Text"
msgstr ""
#: allow-javascript-in-text-widgets.php:49
msgid "Title:"
msgstr ""
#: allow-javascript-in-text-widgets.php:54
msgid "Automatically add paragraphs"
msgstr ""
#. Plugin Name of the plugin/theme
msgid "Allow Javascript in Text Widgets"
msgstr ""
#. Plugin URI of the plugin/theme
msgid "http://philipjohn.co.uk/#pj-better-multisite-text-widget"
msgstr ""
#. Description of the plugin/theme
msgid ""
"Replaces the default text widget with one that allows Javascript so you can "
"do basic things like add Google Ads to your sidebar without using other "
"plugins."
msgstr ""
#. Author of the plugin/theme
msgid "Philip John"
msgstr ""
#. Author URI of the plugin/theme
msgid "http://philipjohn.co.uk"
msgstr ""

Some files were not shown because too many files have changed in this diff Show More